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

Reply via email to