Re: The dmesg files requested

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

 



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.

> 	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?

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.

Sarah Sharp
--
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