> On Saturday 04 December 2004 11:51 am, Alan Stern wrote:
> > In fact, I suggested skipping the class-specific reset entirely and
> > proceeding directly to the port reset, because that's what Windows does.
That worked for me, as in the attached patch. It turned
out that the class-specific reset was succeeding (because
the "port reset only if class-specific failed" logic
never did a port reset!), but was effectively a NOP
(because nothing seemed to happen). So this wasn't a
case of drive firmware (Maxtor) not responding any more...
I did notice two odd things with this patch though:
- It deadlocked if I tried the "lock_for_reset" stuff,
so I commented that out.
- Multiple resets were needed; see the log below.
The third reset happened about 35 seconds after
the sequence started, and until that happened it
seemed like absolutely nothing happened.
I think it might be a good idea to try out a cleaned-up
version of this patch more widely.
- Dave
--- 1.105/drivers/usb/storage/transport.c 2004-11-22 15:12:24 -08:00
+++ edited/drivers/usb/storage/transport.c 2004-12-07 09:50:54 -08:00
@@ -1124,11 +1131,28 @@
clear_bit(US_FLIDX_ABORTING, &us->flags);
scsi_unlock(us->host);
+ /* The class reset won't generally solve the problem, maybe
+ * because Windows won't use it. So try a hard reset first,
+ * if it's safe; likely that'll work well.
+ */
+ if (us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
+// lock_device_for_reset() seems to deadlock things...
+// result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
+// if (result == 0) {
+ result = usb_reset_device(us->pusb_dev);
+ dev_warn(&us->pusb_intf->dev, "usb reset --> %d\n",
+ result);
+// usb_unlock_device(us->pusb_dev);
+// }
+ } else
+ result = -EINVAL;
+
/* A 20-second timeout may seem rather long, but a LaCie
* StudioDrive USB2 device takes 16+ seconds to get going
* following a powerup or USB attach event.
*/
- result = usb_stor_control_msg(us, us->send_ctrl_pipe,
+ if (result < 0)
+ result = usb_stor_control_msg(us, us->send_ctrl_pipe,
request, requesttype, value, index, data, size,
20*HZ);
if (result < 0) {
--- 1.95/drivers/usb/storage/usb.c 2004-11-14 16:41:08 -08:00
+++ edited/drivers/usb/storage/usb.c 2004-12-07 08:07:51 -08:00
@@ -993,6 +998,11 @@
result = get_pipes(us);
if (result)
goto BadDevice;
+
+ dev_info(&intf->dev, "%s over %s\n",
+ us->protocol_name,
+ us->transport_name);
+
/* Acquire all the other resources and add the host */
result = usb_stor_acquire_resources(us);
After about 1/2 hour continuous usb-storage I/O, the
first error caused a reset.
The "reset/N" means the Nth transport reset in that routine.
38:45 ehci_hcd 0000:00:08.3: devpath 6 ep2out 3strikes
38:45 usb_stor_invoke_transport reset/1
38:45 usb_stor_Bulk_reset reset
38:45 ehci_hcd 0000:00:08.3: GetStatus port 6 status 001803 POWER sig=j CSC
CONNECT
38:45 hub 1-0:1.0: port 6 not enabled, trying reset again...
38:46 ehci_hcd 0000:00:08.3: port 6 high speed
38:46 ehci_hcd 0000:00:08.3: GetStatus port 6 status 001005 POWER sig=se0 PE
CONNECT
38:46 usb 1-6: reset high speed USB device using ehci_hcd and address 2
38:46 ehci_hcd 0000:00:08.3: port 6 high speed
38:46 ehci_hcd 0000:00:08.3: GetStatus port 6 status 001005 POWER sig=se0 PE
CONNECT
38:46 usb-storage 1-6:1.0: usb reset --> 0
Long delay here ...
39:22 usb_stor_invoke_transport reset/3
39:22 usb_stor_Bulk_reset reset
39:22 ehci_hcd 0000:00:08.3: port 6 high speed
39:22 ehci_hcd 0000:00:08.3: GetStatus port 6 status 001005 POWER sig=se0 PE
CONNECT
39:22 usb 1-6: reset high speed USB device using ehci_hcd and address 2
39:22 ehci_hcd 0000:00:08.3: port 6 high speed
39:22 ehci_hcd 0000:00:08.3: GetStatus port 6 status 001005 POWER sig=se0 PE
CONNECT
39:24 usb-storage 1-6:1.0: usb reset --> 0
Then it went back and finished.