Re: The dmesg files requested

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 10 Dec 2010, Sarah Sharp wrote:

> On Fri, Dec 10, 2010 at 02:50:14PM -0500, Alan Stern wrote:
> > Okay, very good.  This shows exactly what the "Safely remove drive"  
> > button does:
> > 
> > 	The drive is unmounted;
> > 
> > 	A "spin-down" command is sent (obviously it doesn't do anything
> > 	for a flash drive);
> > 
> > 	A SYNCHRONIZE CACHE comand is sent, perhaps as part of the
> > 	unmount procedure;
> > 
> > 	The USB port is suspended and then immediately resumed (no 
> > 	idea why);
> > 
> > 	The device is set to config 0, i.e., unconfigured;
> 
> usb_set_configuration() resumes the device.  So if the device had
> autosuspend enabled, and the filesystem was unmounted, the USB storage
> driver would suspend it, and then usb_set_configuration() would resume
> it.

_If_ the device was enabled for autosuspend.  By default USB drives
aren't, but maybe Maddog's environment does enable it.

> > 	The USB port is suspended again (no idea why);
> 
> In usb_set_configuration(), when it's called with configuration = -1,
> configuration gets set to 0, and cp remains NULL after the first if
> statement.
> 
> Later, usb_set_configuration() calls into the xHCI to remove all the
> endpoints (except control ep 0) by calling usb_hcd_alloc_bandwidth(dev,
> NULL, NULL, NULL).  It sends the control message to set config 0, and
> then there's this interesting bit of code:
> 
>         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
>                               USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
>                               NULL, 0, USB_CTRL_SET_TIMEOUT);
>         if (ret < 0) {
>                 /* All the old state is gone, so what else can we do?
>                  * The device is probably useless now anyway.
>                  */
>                 cp = NULL;
>         }
> 
>         dev->actconfig = cp;
>         if (!cp) {
>                 usb_set_device_state(dev, USB_STATE_ADDRESS);
>                 usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
>                 mutex_unlock(hcd->bandwidth_mutex);
>                 usb_autosuspend_device(dev);
>                 goto free_interfaces;
>         }
> 
> Since cp was never set in this function, the second if statement always
> runs if the function was called with configuration = -1.  It sort of
> looks like the second if statement was supposed to only run if the
> control message failed, but it does seem to have the effect of skipping
> the new interface installation and returning 0, so I guess it's
> intentional?

You've got it wrong.  The _first_ "if" statement runs if the control
message fails, and the second runs if the device got unconfigured (cp
== NULL means there is no new configuration).  Yes, it is all
intentional.

> In any case, that second call to usb_autosuspend_device() is where the
> second suspend came from.
> 
> If this code is intentional (and not a bug) I think I should move the
> call to usb_hcd_alloc_bandwidth() in the second if statement into the
> first if statement.  That way the xHCI driver doesn't get called twice
> to remove bandwidth for all the endpoints.

Actually, it looks like the usb_hcd_alloc_bandwidth() in the second 
"if" statement is completely redundant.  It should simply be removed.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux