Hi, >> 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 >
Thanks for the detailed write-up. I have checked the UDC driver set_halt(), it is called by the gadget driver. The full ascii text of usbmon trace for one usb session is also attached. This usbmon trace shows a few EOVERFLOW(-75) error. I don't know why EOVERFLOW error happened. victor
scsi_read_10_again10.log
Description: Binary data