ChangeSet 1.1760.26.11, 2004/06/24 10:43:02-07:00, [EMAIL PROTECTED] [PATCH] USB: usb gadget drivers should be stricter about ZLPs
Some USB device controllers make it easy to handle all the various ways hosts interpret the USB spec about when control-IN transfers need to send a ZLP ... they can just send one if the host asks, or start the status stage whenever the host thinks it's time. Other controllers make it hard to be forgiving in those cases. This patch updates all the gadget drivers to explicitly set the req->zero flag to reflect whether the USB spec says a ZLP "must" be sent by the device. "Forgiving" drivers won't notice the change, but the others need to see this information passed down from the gadget driver. Signed-off-by: David Brownell <[EMAIL PROTECTED]> Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]> drivers/usb/gadget/ether.c | 2 ++ drivers/usb/gadget/file_storage.c | 2 ++ drivers/usb/gadget/inode.c | 2 ++ drivers/usb/gadget/serial.c | 2 ++ drivers/usb/gadget/zero.c | 2 ++ 5 files changed, 10 insertions(+) diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c --- a/drivers/usb/gadget/ether.c 2004-06-29 16:26:00 -07:00 +++ b/drivers/usb/gadget/ether.c 2004-06-29 16:26:00 -07:00 @@ -1597,6 +1597,8 @@ /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; + req->zero = value < ctrl->wLength + && (value % gadget->ep0->maxpacket) == 0; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DEBUG (dev, "ep_queue --> %d\n", value); diff -Nru a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c --- a/drivers/usb/gadget/file_storage.c 2004-06-29 16:26:00 -07:00 +++ b/drivers/usb/gadget/file_storage.c 2004-06-29 16:26:00 -07:00 @@ -1465,6 +1465,8 @@ /* Respond with data/status or defer until later? */ if (rc >= 0 && rc != DELAYED_STATUS) { fsg->ep0req->length = rc; + fsg->ep0req->zero = rc < ctrl->wLength + && (rc % gadget->ep0->maxpacket) == 0; fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out"); rc = ep0_queue(fsg); diff -Nru a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c --- a/drivers/usb/gadget/inode.c 2004-06-29 16:26:00 -07:00 +++ b/drivers/usb/gadget/inode.c 2004-06-29 16:26:00 -07:00 @@ -1320,6 +1320,8 @@ /* proceed with data transfer and status phases? */ if (value >= 0 && dev->state != STATE_SETUP) { req->length = value; + req->zero = value < ctrl->wLength + && (value % gadget->ep0->maxpacket) == 0; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); diff -Nru a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c --- a/drivers/usb/gadget/serial.c 2004-06-29 16:26:00 -07:00 +++ b/drivers/usb/gadget/serial.c 2004-06-29 16:26:00 -07:00 @@ -1573,6 +1573,8 @@ /* respond with data transfer before status phase? */ if (ret >= 0) { req->length = ret; + req->zero = ret < ctrl->wLength + && (ret % gadget->ep0->maxpacket) == 0; ret = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC); if (ret < 0) { printk(KERN_ERR diff -Nru a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c --- a/drivers/usb/gadget/zero.c 2004-06-29 16:26:00 -07:00 +++ b/drivers/usb/gadget/zero.c 2004-06-29 16:26:00 -07:00 @@ -1037,6 +1037,8 @@ /* respond with data transfer before status phase? */ if (value >= 0) { req->length = value; + req->zero = value < ctrl->wLength + && (value % gadget->ep0->maxpacket) == 0; value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); if (value < 0) { DBG (dev, "ep_queue --> %d\n", value); ------------------------------------------------------- This SF.Net email sponsored by Black Hat Briefings & Training. Attend Black Hat Briefings & Training, Las Vegas July 24-29 - digital self defense, top technical experts, no vendor pitches, unmatched networking opportunities. Visit www.blackhat.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel