Re: Unlinking URBs before suspending USB

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

 



On Thu, 18 Feb 2010, FEI YANG wrote:

> I have seen a discussion about unlinking URBs before suspending the
> bus posted at
>         http://marc.info/?l=linux-usb&m=126296327514946&w=2
> I think I have a few more questions about this and would like to seek
> for your opinion.
> 
> 1. Is it really necessary to unlink pending URBs in driver's suspend
> method? My observation is that once usb_autopm_put_interface is
> called, the pending URB will eventually be cleaned up in function
> usb_hcd_flush_endpoint.
>         usb_autopm_put_interface -> usb_autopm_do_interface ->
> usb_suspend_both ->usb_hcd_flush_endpoint

That's true, and unlinking URBs in the suspend method isn't really
necessary.  It is a good idea, however, because it means that the URBs
will be cancelled at a time when the driver knows it is safe to do so.  
It also means that the driver won't see any URBs completing after the 
suspend method has returned.

> 2. When the host decides to suspend the bus, in case there is a
> pending IN URB, the driver doesn't really know if the IN URB is in the
> middle of DATA transfer stage or the peripheral is NAK'ing the IN
> token, the SUSPEND can potentially interrupt an ongoing transfer.

This can't happen.  The host won't suspend the bus unless the drivers
for all the devices on the bus have already been suspended, which means 
all the endpoint queues have been flushed and there are no pending 
URBs.

But let's suppose for the moment that it can happen.

> According to the EHCI spec, the hardware guarantees the current
> transaction (512 bytes packet for high speed)

For high-speed BULK.  Other types of transfer have different maxpacket 
sizes.

>  to be finished before
> the SUSPEND taking effect, this would result in an interrupted
> transfer with the first half being an integer multiple of 512 bytes
> and the second half being finished only after bus RESUME. I have
> implement some code in my driver to put these two part together to
> recover the interrupted transfer. However, if I do usb_kill_urb in the
> suspend method of the driver, sometimes the URB would be given back
> with actual_length equals to a number that is not integer multiple of
> 512 (such as 33 or 66), this broke the mechanism I implemented to
> re-assemble the interrupted transfer.

That should not happen, unless the transfer was a short packet.

> I don't know if that
> actual_length is really the bytes received (it doesn't look like there
> is expected data in the buffer) and how should I handle this kind of
> returning URB. Do you know how such a urb->actual_length could happen?
> Is it an artifact of usb_kill_urb?

No.  If the packets aren't short then actual_length should always be a
multiple of the maxpacket value.  If it isn't then something is wrong
somewhere.  This holds even if usb_kill_urb() or usb_unlink_urb() is 
called.

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