Re: [PATCH v2] usb: uas: wait for pending commands before unbinding
From: Oliver Neukum
Date: Mon Oct 26 2026 - 09:07:44 EST
Hi,
On 23.10.26 03:39, Jiayi Li wrote:
USB core normally disables interface endpoints before calling
uas_disconnect(). This cancels pending URBs while the device may still
be processing the associated commands. Some storage bridges then stop
responding after a driver rebind and need a disconnect and reconnect
to recover.
I am afraid there are some issues left. Let me address them inline
to the code.
+static void uas_pre_disconnect(struct usb_interface *intf)
+{
+ struct Scsi_Host *shost = usb_get_intfdata(intf);
+ struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
+ unsigned long start_time;
+
+ start_time = jiffies;
+ for (;;) {
+ if (READ_ONCE(devinfo->udev->state) == USB_STATE_NOTATTACHED)
+ return;
+
+ flush_work(&devinfo->work);
This raises two questions:
1. If an error happens while disconnect is running, why do we want to schedule
work?
2. Why only this and not also scan_work?
+ if (!usb_wait_anchor_empty_timeout(&devinfo->sense_urbs, 5000))
+ break;
Some commands run longer
+ if (!usb_wait_anchor_empty_timeout(&devinfo->data_urbs, 500))
+ break;
+
+ if (time_after(jiffies, start_time + 5 * HZ))
+ break;
+ if (uas_cmnd_list_empty(devinfo))
+ return;
+
+ msleep(20);
+ }
+
+ shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__);
+}
+
static void uas_disconnect(struct usb_interface *intf)
{
struct Scsi_Host *shost = usb_get_intfdata(intf);
struct uas_dev_info *devinfo = (struct uas_dev_info *)shost->hostdata;
unsigned long flags;
+ spin_lock_irqsave(&shost->host_lock, flags);
+ scsi_block_requests(shost);
+ spin_unlock_irqrestore(&shost->host_lock, flags);
+
+ uas_pre_disconnect(intf);
+
spin_lock_irqsave(&devinfo->lock, flags);
devinfo->resetting = 1;
spin_unlock_irqrestore(&devinfo->lock, flags);
Is the resetting flag even needed anymore?
If it is needed, why set it so late?
Regards
Oliver