Linux USB
 help / color / mirror / Atom feed
From: Stanislaw Gruszka <stf_xl@wp.pl>
To: Mauricio Faria de Oliveira <mfo@igalia.com>
Cc: Matthieu CASTET <castet.matthieu@free.fr>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Andrew Morton <akpm@osdl.org>,
	kernel-dev@igalia.com, linux-usb@vger.kernel.org,
	linux-kernel@vger.kernel.org, Greg Kroah-Hartman <gregkh@suse.de>,
	Andrey Tsygunka <aitsygunka@yandex.ru>,
	syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com,
	syzbot+306212936b13e520679d@syzkaller.appspotmail.com,
	syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com
Subject: Re: [PATCH v3] usb: atm: ueagle-atm: wait for pre-firmware load in .disconnect()
Date: Wed, 27 May 2026 09:33:53 +0200	[thread overview]
Message-ID: <20260527073353.GA47101@wp.pl> (raw)
In-Reply-To: <20260526-ueagle-atm_req-fw-sync-v3-1-93c01961daaf@igalia.com>

On Tue, May 26, 2026 at 02:09:44PM -0300, Mauricio Faria de Oliveira wrote:
> ueagle-atm uses the asynchronous request_firmware_nowait() in .probe(),
> but does not wait for its completion, not even in .disconnect(); so, if the
> device is unplugged meanwhile, its teardown runs concurrently with that.
> 
> Even though this inconsistency is worth addressing on its own, it has also
> triggered several bug reports in syzbot over the years (some auto-closed)
> where the firmware sysfs fallback mechanism (CONFIG_FW_LOADER_USER_HELPER)
> creates a firmware subdirectory in the device directory during its removal,
> which might hit unexpected conditions in kernfs, apparently, depending at
> which point the add and remove operations raced. (See links.)
> 
> The pattern is:
> 
> usb ?-?: Direct firmware load for ueagle-atm/eagle?.fw failed with error -2
> usb ?-?: Falling back to sysfs fallback for: ueagle-atm/eagle?.fw
> <ERROR>
> Call trace:
>  ...
>  kernfs_create_dir_ns
>  sysfs_create_dir_ns
>  create_dir
>  kobject_add_internal
>  kobject_add_varg
>  kobject_add
>  class_dir_create_and_add
>  get_device_parent
>  device_add
>  fw_load_sysfs_fallback
>  fw_load_from_user_helper
>  firmware_fallback_sysfs
>  _request_firmware
>  request_firmware_work_func
>  ...
> 
> (Some variations are observed, after fw_load_sysfs_fallback(), e.g., [1].)
> 
> While the kernfs side is being looked at, the ueagle-atm side can be fixed
> by waiting for the pre-firmware load in the .disconnect() handler.
> 
> This change has a similar approach to previous work by Andrey Tsygunka [2]
> (wait_for_completion() in .disconnect()), but it is relatively different in
> design/implementation; using the Originally-by tag for credit assignment.
> 
> This has been tested with:
> - synthetic reproducer to check the error path;
> - USB gadget (virtual device) to check the firmware upload path;
> - QEMU device emulator to check the device ID re-enumeration path;
> (The latter two were written by Claude; no other code/text in this commit.)
> 
> Links (year first reported):
>  2025 https://syzbot.org/bug?extid=ce1e5a1b4e086b43e56d
>  2025 https://syzbot.org/bug?extid=9af8471255ac36e34fd4
>  2024 https://syzbot.org/bug?extid=306212936b13e520679d
>  2023 https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
>  2022 https://syzbot.org/bug?extid=782984d6f1701b526edb
>  2021 https://syzbot.org/bug?id=f3f221579f4ef7e9691281f3c6f56c05f83e8490
>  2021 https://syzbot.org/bug?id=84d86f0d71394829df6fc53daf6642c045983881
>  2021 https://syzbot.org/bug?id=3302dc1c0e2b9c94f2e8edb404eabc9267bc6f90
> 
> [1] https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
> [2] https://lore.kernel.org/lkml/20250410093146.3776801-2-aitsygunka@yandex.ru/
> 
> Reported-by: syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com
> Closes: https://syzbot.org/bug?extid=ce1e5a1b4e086b43e56d
> Reported-by: syzbot+306212936b13e520679d@syzkaller.appspotmail.com
> Closes: https://syzbot.org/bug?extid=306212936b13e520679d
> Reported-by: syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=457452d30bcdda75ead2
> Originally-by: Andrey Tsygunka <aitsygunka@yandex.ru>
> Fixes: b72458a80c75 ("[PATCH] USB: Eagle and ADI 930 usb adsl modem driver")
> Assisted-by: Claude:claude-opus-4.7 # usb gadget & qemu device for testing
> Signed-off-by: Mauricio Faria de Oliveira <mfo@igalia.com>
Acked-by: Stanislaw Gruszka <stf_xl@wp.pl>

> ---
> Testing:
> =======
> 
> Tested with virtual devices and synthetic reproducer (hardware unavailable).
> 
> With two ueagle-atm patches currently in:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
>   usb-testing branch
> 
> With:
> 
>   # echo 1 >/sys/module/printk/parameters/ignore_loglevel
>   # echo 2 >/sys/module/ueagle_atm/parameters/debug
>   # echo 'file drivers/usb/atm/ueagle-atm.c +p' >/sys/kernel/debug/dynamic_debug/control
>   # echo 'file drivers/base/firmware_loader/* +p' >/sys/kernel/debug/dynamic_debug/control
> 
> Section 'Error path' shows an actual case of waiting for a few seconds in .disconnect().
> Other sections show non-waiting cases where firmware upload is successful (more likely).
> 
> Firmware upload path:
> --------------------
> 
> This has been tested with a USB gadget (virtual device) written by Claude [1].
> It ACKs pre-firmware upload commands, so the driver considers that successful:
> 
>   [  204.237892] usb 3-1: [ueagle-atm] firmware uploaded
>   
> Log (blocks separated for clarity):
> 
>   # insmod ueagle_gadget.ko
>   ...
>   [  203.414370] [ueagle-gadget] registered (VID=0x1039 PID=0x2101)
>   [  203.624444] usb 3-1: new full-speed USB device number 3 using dummy_hcd
>   ...
>   [  203.760088] usb 3-1: [ueagle-atm dbg] uea_probe: ADSL device found with vid (0X1039) pid (0X2101) Rev (0X2581): Eagle I
>   
>   [  204.004847] usb 3-1: [ueagle-atm] pre-firmware device, uploading firmware
>   [  204.004922] usb 3-1: [ueagle-atm] loading firmware ueagle-atm/eagleI.fw
>   [  204.009581] firmware_class: __allocate_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=00000000067944c4
>   [  204.009692] usb 3-1: loading /lib/firmware/updates/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [  204.009763] usb 3-1: loading /lib/firmware/updates/ueagle-atm/eagleI.fw failed for no such file or directory.
>   [  204.009822] usb 3-1: loading /lib/firmware/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [  204.034914] usb 3-1: Loading firmware from /lib/firmware/ueagle-atm/eagleI.fw
>   [  204.034933] usb 3-1: direct-loading ueagle-atm/eagleI.fw
>   [  204.034965] firmware_class: fw_set_page_data: fw-ueagle-atm/eagleI.fw fw_priv=00000000067944c4 data=000000007f403c77 size=10981
>   
>   [  204.035204] usb 3-1: Loaded FW: ueagle-atm/eagleI.fw, sha256: 8c5047be3b02ed4a8b98c22ed03c010afae1782f6056d8bf2f32bbdde834a74a
>   [  204.044467] ueagle_gadget gadget.0: [ueagle-gadget] LOAD_INTERNAL addr=0x7f92 (F8051_USBCS reset), len=1
>   [  204.237855] ueagle_gadget gadget.0: [ueagle-gadget] LOAD_INTERNAL addr=0x7f92 (F8051_USBCS reset), len=1
>   [  204.237892] usb 3-1: [ueagle-atm] firmware uploaded
>   [  204.237898] firmware_class: __free_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=00000000067944c4 data=000000007f403c77 size=10981
>   
>   # rmmod ueagle_gadget
>   
>   [  395.760610] ueagle_gadget gadget.0: [ueagle-gadget] disconnected
>   [  395.762723] ueagle_gadget gadget.0: [ueagle-gadget] unbound
>   [  395.763033] [ueagle-gadget] unregistered
>   [  395.767035] usb 3-1: USB disconnect, device number 3
>   [  395.767456] usb 3-1: [ueagle-atm dbg] uea_disconnect: pre-firmware device, waiting firmware upload
>   [  395.767466] usb 3-1: [ueagle-atm dbg] uea_disconnect: pre-firmware device, finished waiting
>   [  395.780360] firmware_class: fw_name_devm_release: fw_name-ueagle-atm/eagleI.fw devm-00000000905aab2b released
> 
> Device re-enumeration path:
> ---------------------------
> 
> This has been tested with a QEMU device emulator written by Claude [2].
> It ACKs pre-firmware upload commands, so the driver considers that successful,
> then re-enumerates the USB device to the post-firmware device ID.
> 
>   [   53.018638] usb 1-1: new high-speed USB device number 2 using xhci_hcd
>   ...
>   [   53.161065] usb 1-1: [ueagle-atm dbg] uea_probe: ADSL device found with vid (0X1039) pid (0X2101) Rev (0X0): Eagle I
>   [   53.279989] usb 1-1: reset high-speed USB device number 2 using xhci_hcd
>   
>   [   53.408011] usb 1-1: [ueagle-atm] pre-firmware device, uploading firmware
>   [   53.408070] usb 1-1: [ueagle-atm] loading firmware ueagle-atm/eagleI.fw
>   [   53.412221] firmware_class: __allocate_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=00000000573d611f
>   [   53.446730] usb 1-1: loading /lib/firmware/updates/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   53.446806] usb 1-1: loading /lib/firmware/updates/ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   53.446890] usb 1-1: loading /lib/firmware/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   53.469798] usb 1-1: Loading firmware from /lib/firmware/ueagle-atm/eagleI.fw
>   [   53.469811] usb 1-1: direct-loading ueagle-atm/eagleI.fw
>   [   53.469843] firmware_class: fw_set_page_data: fw-ueagle-atm/eagleI.fw fw_priv=00000000573d611f data=00000000c9c958dc size=10981
>   
>   [   53.470082] usb 1-1: Loaded FW: ueagle-atm/eagleI.fw, sha256: 8c5047be3b02ed4a8b98c22ed03c010afae1782f6056d8bf2f32bbdde834a74a
>   [   53.599908] usb 1-1: [ueagle-atm] firmware uploaded
>   [   53.599926] firmware_class: __free_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=00000000573d611f data=00000000c9c958dc size=10981
>   
>   [   53.600247] usb 1-1: USB disconnect, device number 2
>   [   53.613568] usb 1-1: [ueagle-atm dbg] uea_disconnect: pre-firmware device, waiting firmware upload
>   [   53.613594] usb 1-1: [ueagle-atm dbg] uea_disconnect: pre-firmware device, finished waiting
>   [   53.629523] firmware_class: fw_name_devm_release: fw_name-ueagle-atm/eagleI.fw devm-00000000682651e8 released
>   
>   [   53.873101] usb 1-1: new high-speed USB device number 3 using xhci_hcd
>   ...
>   [   54.011640] usb 1-1: New USB device found, idVendor=1039, idProduct=2100, bcdDevice=20.0b
>   ...
>   [   54.026724] usb 1-1: [ueagle-atm dbg] uea_probe: ADSL device found with vid (0X1039) pid (0X2100) Rev (0X200B): Eagle I
>   [   54.154845] usb 1-1: reset high-speed USB device number 3 using xhci_hcd
>   ...
> 
> Error path:
> ----------
> 
> This has been tested with a synthetic reproducer [3]:
> 
>   # mv /lib/firmware/ueagle-atm/eagleI.fw \
>        /lib/firmware/ueagle-atm/eagleI.fw.NOT-FOUND
>   
>   # cat ueagle-atm.syzlang
>   syz_usb_connect(0x3, 0x2d, &(0x7f00000002c0)=ANY=[@ANYBLOB="12011003faff82083910012181250102030109021b00028c4400600904"], &(0x7f0000000240)={0x0, 0x0, 0x0, 0x0})
>   
>   # ./syz-execprog -procs=1 -enable='' ueagle-atm.syzlang
> 
> Modified: 
> 
>   [   53.437324] usb 3-1: new high-speed USB device number 2 using dummy_hcd
>   ...
>   [   53.578680] usb 3-1: New USB device found, idVendor=1039, idProduct=2101, bcdDevice=25.81
>   ...
>   [   53.790811] usb 3-1: [ueagle-atm dbg] uea_probe: ADSL device found with vid (0X1039) pid (0X2101) Rev (0X2581): Eagle I
>   
>   [   54.534023] usb 3-1: [ueagle-atm] pre-firmware device, uploading firmware
>   [   54.534060] usb 3-1: [ueagle-atm] loading firmware ueagle-atm/eagleI.fw
>   [   54.544413] firmware_class: __allocate_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=0000000011cebda9
>   [   54.549369] usb 3-1: loading /lib/firmware/updates/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   54.549447] usb 3-1: loading /lib/firmware/updates/ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   54.549535] usb 3-1: loading /lib/firmware/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   54.549607] usb 3-1: loading /lib/firmware/ueagle-atm/eagleI.fw failed for no such file or directory.
>   
>   [   54.549618] usb 3-1: Direct firmware load for ueagle-atm/eagleI.fw failed with error -2
>   [   54.549627] usb 3-1: Falling back to sysfs fallback for: ueagle-atm/eagleI.fw
>   
>   [   54.549800] test kernfs_activate(): sleep 3s
>   [   54.617101] usb 3-1: USB disconnect, device number 2
>   [   54.623904] usb 3-1: [ueagle-atm dbg] uea_disconnect: pre-firmware device, waiting firmware upload
>   
>   [   57.589519] test kernfs_activate(): slept 3s
>   [   57.589708] firmware ueagle-atm!eagleI.fw: firmware: requesting ueagle-atm/eagleI.fw
>   [   57.615334] test __kernfs_remove(): done
>   [   57.615375] firmware_class: __free_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=0000000011cebda9 data=0000000000000000 size=0
>   [   57.615398] usb 3-1: [UEAGLE-ATM] firmware is not available
>   [   57.615425] usb 3-1: [ueagle-atm dbg] uea_disconnect: pre-firmware device, finished waiting
> 
> Original:
> 
>   [   45.622349] usb 3-1: new high-speed USB device number 2 using dummy_hcd
>   ...
>   [   45.998868] usb 3-1: New USB device found, idVendor=1039, idProduct=2101, bcdDevice=25.81
>   ...
>   [   46.325820] usb 3-1: [ueagle-atm dbg] uea_probe: ADSL device found with vid (0X1039) pid (0X2101) Rev (0X2581): Eagle I
>   
>   [   47.141820] usb 3-1: [ueagle-atm] pre-firmware device, uploading firmware
>   [   47.141866] usb 3-1: [ueagle-atm] loading firmware ueagle-atm/eagleI.fw
>   [   47.191338] firmware_class: __allocate_fw_priv: fw-ueagle-atm/eagleI.fw fw_priv=00000000ad970730
>   [   47.251273] usb 3-1: loading /lib/firmware/updates/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   47.251314] usb 3-1: loading /lib/firmware/updates/ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   47.315769] usb 3-1: loading /lib/firmware/.../ueagle-atm/eagleI.fw failed for no such file or directory.
>   [   47.315813] usb 3-1: loading /lib/firmware/ueagle-atm/eagleI.fw failed for no such file or directory.
>   
>   [   47.315819] usb 3-1: Direct firmware load for ueagle-atm/eagleI.fw failed with error -2
>   [   47.315823] usb 3-1: Falling back to sysfs fallback for: ueagle-atm/eagleI.fw
>   
>   [   47.315871] test kernfs_activate(): sleep 3s
>   [   47.379964] usb 3-1: USB disconnect, device number 2
>   [   47.381235] test __kernfs_remove(): done
>   [   50.363795] test kernfs_activate(): slept 3s
>   [   50.363809] ==================================================================
>   [   50.363814] BUG: KASAN: slab-use-after-free in kernfs_root+0x68/0x80
>   [   50.363834] Read of size 8 at addr ffff88800c015ee0 by task kworker/1:1/48
>   [   50.363843]
>   [   50.363851] CPU: 1 UID: 0 PID: 48 Comm: kworker/1:1 Not tainted ... #105 PREEMPT_{RT,(lazy)}
>   [   50.363865] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
>   [   50.363872] Workqueue: events request_firmware_work_func
>   [   50.363890] Call Trace:
>   [   50.363895]  <TASK>
>   [   50.363901]  dump_stack_lvl+0x64/0x80
>   [   50.364100]  print_report+0xce/0x620
>   [   50.364123]  kasan_report+0xce/0x100
>   [   50.364142]  kernfs_root+0x68/0x80
>   [   50.364151]  kernfs_next_descendant_post+0x1b/0x270
>   [   50.364162]  kernfs_activate+0x79/0x110
>   [   50.364172]  kernfs_add_one+0x267/0x3d0
>   [   50.364182]  kernfs_create_dir_ns+0xcc/0x140
>   [   50.364193]  sysfs_create_dir_ns+0x130/0x280
>   [   50.364241]  kobject_add_internal+0x21b/0x9c0
>   [   50.364252]  kobject_add+0x13a/0x200
>   [   50.364291]  device_add+0x21e/0x1540
>   [   50.364322]  firmware_fallback_sysfs+0x232/0x980
>   [   50.364334]  _request_firmware+0xa53/0x1100
>   [   50.364390]  request_firmware_work_func+0xeb/0x360
>   [   50.364413]  process_one_work+0x610/0x1150
>   [   50.364445]  worker_thread+0x50d/0xd60
>   [   50.364477]  kthread+0x318/0x400
>   [   50.364496]  ret_from_fork+0x447/0x6a0
>   [   50.364560]  ret_from_fork_asm+0x1a/0x30
>   [   50.364573]  </TASK>
>   [   50.364576]
>   [   50.364578] Allocated by task 48:
>   [   50.364583]  kasan_save_stack+0x33/0x60
>   [   50.364593]  kasan_save_track+0x14/0x30
>   [   50.364601]  __kasan_slab_alloc+0x6e/0x70
>   [   50.364609]  kmem_cache_alloc_noprof+0x1a5/0x4d0
>   [   50.364620]  __kernfs_new_node+0xce/0x950
>   [   50.364628]  kernfs_new_node+0xeb/0x170
>   [   50.364636]  kernfs_create_dir_ns+0x2b/0x140
>   [   50.364644]  sysfs_create_dir_ns+0x130/0x280
>   [   50.364651]  kobject_add_internal+0x21b/0x9c0
>   [   50.364660]  kobject_add+0x13a/0x200
>   [   50.364668]  device_add+0x21e/0x1540
>   [   50.364675]  firmware_fallback_sysfs+0x232/0x980
>   [   50.364683]  _request_firmware+0xa53/0x1100
>   [   50.364692]  request_firmware_work_func+0xeb/0x360
>   [   50.364700]  process_one_work+0x610/0x1150
>   [   50.364709]  worker_thread+0x50d/0xd60
>   [   50.364718]  kthread+0x318/0x400
>   [   50.364726]  ret_from_fork+0x447/0x6a0
>   [   50.364733]  ret_from_fork_asm+0x1a/0x30
>   [   50.364741]
>   [   50.364743] Freed by task 29:
>   [   50.364747]  kasan_save_stack+0x33/0x60
>   [   50.364754]  kasan_save_track+0x14/0x30
>   [   50.364762]  kasan_save_free_info+0x3b/0x60
>   [   50.364768]  __kasan_slab_free+0x43/0x70
>   [   50.364776]  kmem_cache_free+0xc3/0x510
>   [   50.364782]  rcu_core+0x5d1/0x1a50
>   [   50.364791]  rcu_cpu_kthread+0x148/0x6f0
>   [   50.364799]  smpboot_thread_fn+0x347/0x8e0
>   [   50.364809]  kthread+0x318/0x400
>   [   50.364816]  ret_from_fork+0x447/0x6a0
>   [   50.364823]  ret_from_fork_asm+0x1a/0x30
>   [   50.364831]
>   [   50.364833] Last potentially related work creation:
>   [   50.364836]  kasan_save_stack+0x33/0x60
>   [   50.364843]  kasan_record_aux_stack+0x8c/0xa0
>   [   50.364849]  __call_rcu_common.constprop.0+0x76/0xa20
>   [   50.364858]  kernfs_put.part.0+0x1aa/0x540
>   [   50.364866]  __kernfs_remove.part.0+0x3f2/0x820
>   [   50.364874]  kernfs_remove+0x9e/0xd0
>   [   50.364882]  __kobject_del+0xc3/0x340
>   [   50.364890]  kobject_del+0x35/0x50
>   [   50.364898]  device_del+0x5ef/0x960
>   [   50.364904]  usb_disconnect+0x504/0x970
>   [   50.364914]  hub_event+0x2898/0x4670
>   [   50.364922]  process_one_work+0x610/0x1150
>   [   50.364931]  worker_thread+0x50d/0xd60
>   [   50.364940]  kthread+0x318/0x400
>   [   50.364948]  ret_from_fork+0x447/0x6a0
>   [   50.364954]  ret_from_fork_asm+0x1a/0x30
>   [   50.364962]
>   [   50.364964] The buggy address belongs to the object at ffff88800c015ed8
>   [   50.364964]  which belongs to the cache kernfs_node_cache of size 136
>   [   50.364971] The buggy address is located 8 bytes inside of
>   [   50.364971]  freed 136-byte region [ffff88800c015ed8, ffff88800c015f60)
>   [   50.364979]
>   [   50.364982] The buggy address belongs to the physical page:
>   [   50.364986] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xc015
>   [   50.364994] flags: 0x100000000000000(node=0|zone=1)
>   [   50.365003] page_type: f5(slab)
>   [   50.365013] raw: 0100000000000000 ffff888006ead640 dead000000000122 0000000000000000
>   [   50.365021] raw: 0000000000000000 0000000000140014 00000000f5000000 0000000000000000
>   [   50.365025] page dumped because: kasan: bad access detected
>   [   50.365029]
>   [   50.365030] Memory state around the buggy address:
>   [   50.365034]  ffff88800c015d80: fb fb fb fb fb fb fb fb fb fb fc fc fc fc fc fc
>   [   50.365040]  ffff88800c015e00: fc fc fa fb fb fb fb fb fb fb fb fb fb fb fb fb
>   [   50.365045] >ffff88800c015e80: fb fb fb fc fc fc fc fc fc fc fc fa fb fb fb fb
>   [   50.365049]                                                        ^
>   [   50.365054]  ffff88800c015f00: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
>   [   50.365059]  ffff88800c015f80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>   [   50.365062] ==================================================================
>   [   50.537450] Disabling lock debugging due to kernel taint
> 
> References:
> 
> [1] https://gist.github.com/mfoliveira/c6b77fbae3d8083be6944477aedbc5d2
> [2] https://gist.github.com/mfoliveira/c33f6bb523a6bd518cc321f27e509d44
> [3] https://gist.github.com/mfoliveira/cd1d78561e2db80dd87103e835e3ebec
> ---
> Changes in v3:
> - Fix error path in .probe(): use kfree() instead of complete(),
>   as .disconnect() is not called if .probe() fails.
>   (Thanks: Stanislaw Gruszka <stf_xl@wp.pl>).
> - Link to v2: https://lore.kernel.org/r/20260522-ueagle-atm_req-fw-sync-v2-1-eee7f6b823a7@igalia.com
> 
> Changes in v2:
> - Changed approach from sync request_firmware() in .probe() 
>   to wait for request_firmware_async() in .disconnect().
> - Referenced previous work by Andrey Tsygunka <aitsygunka@yandex.ru>
> - Link to v1: https://lore.kernel.org/r/20260515-ueagle-atm_req-fw-sync-v1-1-406ca3939e2a@igalia.com
> ---
>  drivers/usb/atm/ueagle-atm.c | 36 +++++++++++++++++++++++++++++++-----
>  1 file changed, 31 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
> index ed2611aacb252fce829b4a33589c47912aadbe67..1e12fc19f8726d052b4571a1e11f3b009d251c22 100644
> --- a/drivers/usb/atm/ueagle-atm.c
> +++ b/drivers/usb/atm/ueagle-atm.c
> @@ -594,7 +594,9 @@ static int uea_send_modem_cmd(struct usb_device *usb,
>  static void uea_upload_pre_firmware(const struct firmware *fw_entry,
>  								void *context)
>  {
> -	struct usb_device *usb = context;
> +	struct usb_interface *intf = context;
> +	struct usb_device *usb = interface_to_usbdev(intf);
> +	struct completion *fw_done = usb_get_intfdata(intf);
>  	const u8 *pfw;
>  	u8 value;
>  	u32 crc = 0;
> @@ -663,15 +665,17 @@ static void uea_upload_pre_firmware(const struct firmware *fw_entry,
>  	uea_err(usb, "firmware is corrupted\n");
>  err:
>  	release_firmware(fw_entry);
> +	complete(fw_done);
>  }
>  
>  /*
>   * uea_load_firmware - Load usb firmware for pre-firmware devices.
>   */
> -static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
> +static int uea_load_firmware(struct usb_interface *intf, unsigned int ver)
>  {
>  	int ret;
>  	char *fw_name = EAGLE_FIRMWARE;
> +	struct usb_device *usb = interface_to_usbdev(intf);
>  
>  	uea_info(usb, "pre-firmware device, uploading firmware\n");
>  
> @@ -694,7 +698,7 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
>  	}
>  
>  	ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
> -					GFP_KERNEL, usb,
> +					GFP_KERNEL, intf,
>  					uea_upload_pre_firmware);
>  	if (ret)
>  		uea_err(usb, "firmware %s is not available\n", fw_name);
> @@ -2557,8 +2561,23 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
>  
>  	usb_reset_device(usb);
>  
> -	if (UEA_IS_PREFIRM(id))
> -		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
> +	if (UEA_IS_PREFIRM(id)) {
> +		struct completion *fw_done;
> +
> +		/* Wait for the firmware load to be done, in .disconnect() */
> +		fw_done = kzalloc_obj(*fw_done);
> +		if (!fw_done)
> +			return -ENOMEM;
> +
> +		init_completion(fw_done);
> +		usb_set_intfdata(intf, fw_done);
> +
> +		ret = uea_load_firmware(intf, UEA_CHIP_VERSION(id));
> +		if (ret)
> +			kfree(fw_done);
> +
> +		return ret;
> +	}
>  
>  	ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
>  	if (ret == 0) {
> @@ -2588,6 +2607,13 @@ static void uea_disconnect(struct usb_interface *intf)
>  		usbatm_usb_disconnect(intf);
>  		mutex_unlock(&uea_mutex);
>  		uea_info(usb, "ADSL device removed\n");
> +	} else if (usb->config->desc.bNumInterfaces == 1) {
> +		struct completion *fw_done = usb_get_intfdata(intf);
> +
> +		uea_dbg(usb, "pre-firmware device, waiting firmware upload\n");
> +		wait_for_completion(fw_done);
> +		uea_dbg(usb, "pre-firmware device, finished waiting\n");
> +		kfree(fw_done);
>  	}
>  }
>  
> 
> ---
> base-commit: 22d91cef94b5b86cff0d68ebfce7741740672704
> change-id: 20260515-ueagle-atm_req-fw-sync-204761fa0809
> 
> Best regards,
> -- 
> Mauricio Faria de Oliveira <mfo@igalia.com>
> 

      reply	other threads:[~2026-05-27  7:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-26 17:09 [PATCH v3] usb: atm: ueagle-atm: wait for pre-firmware load in .disconnect() Mauricio Faria de Oliveira
2026-05-27  7:33 ` Stanislaw Gruszka [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260527073353.GA47101@wp.pl \
    --to=stf_xl@wp.pl \
    --cc=aitsygunka@yandex.ru \
    --cc=akpm@osdl.org \
    --cc=castet.matthieu@free.fr \
    --cc=gregkh@linuxfoundation.org \
    --cc=gregkh@suse.de \
    --cc=kernel-dev@igalia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mfo@igalia.com \
    --cc=syzbot+306212936b13e520679d@syzkaller.appspotmail.com \
    --cc=syzbot+457452d30bcdda75ead2@syzkaller.appspotmail.com \
    --cc=syzbot+ce1e5a1b4e086b43e56d@syzkaller.appspotmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox