ChangeSet 1.1325.4.11, 2003/09/23 17:18:18-07:00, [EMAIL PROTECTED]
[PATCH] USB: usb gadgetfs updates
Some small updates:
- Sometimes read requests can be satisfied directly from
the OUT fifo. This fixes a bug where the return code
from usb_ep_queue() overwrite the transfer status, which
in that case was set _before_ that call returned.
(Synchronous behavior; not the usual async completion.)
- In the same vein, usb_ep_dequeue() doesn't need to be
synchronous -- though so far most controller drivers
have implemented it that way. So drop the spinlock
before the wait_event() sleep.
- Some debug messages are more useful AFTER the event
than before.
- The only descriptor fetches user mode drivers will
need to handle are for string descriptors. Stall all
other requests, like ones for other-speed configs
on single-speed devices.
drivers/usb/gadget/inode.c | 34 +++++++++++++++++++++-------------
1 files changed, 21 insertions(+), 13 deletions(-)
diff -Nru a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
--- a/drivers/usb/gadget/inode.c Thu Sep 25 14:31:44 2003
+++ b/drivers/usb/gadget/inode.c Thu Sep 25 14:31:44 2003
@@ -354,6 +354,7 @@
ep_io (struct ep_data *epdata, void *buf, unsigned len)
{
DECLARE_COMPLETION (done);
+ int value;
spin_lock_irq (&epdata->dev->lock);
if (likely (epdata->ep != NULL)) {
@@ -363,14 +364,12 @@
req->complete = epio_complete;
req->buf = buf;
req->length = len;
- epdata->status = usb_ep_queue (epdata->ep, req, GFP_ATOMIC);
+ value = usb_ep_queue (epdata->ep, req, GFP_ATOMIC);
} else
- epdata->status = -ENODEV;
+ value = -ENODEV;
spin_unlock_irq (&epdata->dev->lock);
- if (epdata->status == 0) {
- int value;
-
+ if (likely (value == 0)) {
value = wait_event_interruptible (done.wait, done.done);
if (value != 0) {
spin_lock_irq (&epdata->dev->lock);
@@ -378,17 +377,21 @@
DBG (epdata->dev, "%s i/o interrupted\n",
epdata->name);
usb_ep_dequeue (epdata->ep, epdata->req);
+ spin_unlock_irq (&epdata->dev->lock);
+
wait_event (done.wait, done.done);
- if (epdata->status == 0)
- epdata->status = value;
+ if (epdata->status == -ECONNRESET)
+ epdata->status = -EINTR;
} else {
+ spin_unlock_irq (&epdata->dev->lock);
+
DBG (epdata->dev, "endpoint gone\n");
epdata->status = -ENODEV;
}
- spin_unlock_irq (&epdata->dev->lock);
}
+ return epdata->status;
}
- return epdata->status;
+ return value;
}
@@ -424,10 +427,12 @@
if (unlikely (!kbuf))
goto free1;
- VDEBUG (data->dev, "%s read %d OUT\n", data->name, len);
value = ep_io (data, kbuf, len);
+ VDEBUG (data->dev, "%s read %d OUT, status %d\n",
+ data->name, len, value);
if (value >= 0 && copy_to_user (buf, kbuf, value))
value = -EFAULT;
+
free1:
up (&data->lock);
kfree (kbuf);
@@ -470,8 +475,9 @@
goto free1;
}
- VDEBUG (data->dev, "%s write %d IN\n", data->name, len);
value = ep_io (data, kbuf, len);
+ VDEBUG (data->dev, "%s write %d IN, status %d\n",
+ data->name, len, value);
free1:
up (&data->lock);
kfree (kbuf);
@@ -1200,9 +1206,11 @@
if (value >= 0)
value = min (ctrl->wLength, (u16) value);
break;
-
- default:
+ case USB_DT_STRING:
goto unrecognized;
+
+ default: // all others are errors
+ break;
}
break;
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel