On Wed, 10 Apr 2013, victor yeo wrote:
> I use kernel 3.4.4, the code in handle_stat1_irqs() is as below. There
> is no reset or disconnect member function in "struct
> usb_gadget_driver" in kernel 3.4.4.
>
> if (stat & (1 << SUSPEND_REQUEST_INTERRUPT)) {
> if (dev->driver->suspend)
> dev->driver->suspend (&dev->gadget);
> if (!enable_suspend)
> stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT);
> } else {
> if (dev->driver->resume)
> dev->driver->resume (&dev->gadget);
> /* at high speed, note erratum 0133 */
> }
Okay. I have a hard enough time remembering how the kernel works now;
I can't afford to remember how it worked five releases ago. :-)
In the 3.4 kernel, when either a reset or a disconnect occurs, the UDC
driver should call the gadget driver's ->disconnect handler.
> >> Another usbmon trace showing 3 SCSI_READ_10 command.
> >
> >This trace shows that the READ(10) commands worked correctly. Good.
> >But it also shows that the gadget did not respond correctly to the 0xA1
> >command near the end. The UDC was supposed to set the Halt feature
> >for the bulk-in endpoint and send a STALL packet, but it didn't.
>
> In gadget driver, when do_scsi_command() receives an unknown command,
> the return value is -EINVAL.
No, the return value is 0. Read the last line of do_scsi_command():
return 0;
> Will this value be returned to UDC
> driver, so that UDC driver can set the Halt feature for the bulk-in
> endpoint and send a STALL packet? For now, UDC driver does not set
> Halt when unknown SCSI command is received.
Look at finish_reply(), near the end of the DATA_DIR_TO_HOST case:
/*
* For Bulk-only, mark the end of the data with a short
* packet. If we are allowed to stall, halt the bulk-in
* endpoint. (Note: This violates the Bulk-Only Transport
* specification, which requires us to pad the data if we
* don't halt the endpoint. Presumably nobody will mind.)
*/
else {
bh->inreq->zero = 1;
start_transfer(fsg, fsg->bulk_in, bh->inreq,
&bh->inreq_busy, &bh->state);
fsg->next_buffhd_to_fill = bh->next;
if (mod_data.can_stall)
rc = halt_bulk_in_endpoint(fsg);
}
And read the fist line in halt_bulk_in_endpoint():
rc = fsg_set_halt(fsg, fsg->bulk_in);
And finally, read the last line of fsg_set_halt():
return usb_ep_set_halt(ep);
That's when your UDC is supposed to set the Halt feature -- when its
usb_ep_set_halt() function is called. If the controller is busy at
this time because the bulk-in buffer is full, and it is unable to set
the Halt feature, then usb_ep_set_halt() should return -EAGAIN -- see
the documentation for usb_ep_set_halt in include/linux/usb/gadget.h.
Alan Stern
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html