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