ChangeSet 1.1760.26.9, 2004/06/24 10:42:03-07:00, [EMAIL PROTECTED]
[PATCH] USB: Imiprove usb_device tracking in dummy_hcd
A tricky problem the dummy_hcd driver has to solve is keeping track of the
usb_device structure that corresponds to a registered gadget. Right now
that's not done very robustly. This patch stores the address of the
structure when a new URB is submitted and also acquires a reference to
make sure that completing the final URB won't deallocate the structure
before dummy_hcd is through with it.
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
drivers/usb/gadget/dummy_hcd.c | 38 ++++++++++++++++++++++++++------------
1 files changed, 26 insertions(+), 12 deletions(-)
diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c 2004-06-29 16:26:11 -07:00
+++ b/drivers/usb/gadget/dummy_hcd.c 2004-06-29 16:26:11 -07:00
@@ -146,8 +146,6 @@
u8 fifo_buf [FIFO_SIZE];
u16 devstatus;
- struct hcd_dev *hdev;
-
/*
* MASTER/HOST side support
*/
@@ -159,6 +157,8 @@
struct completion released;
unsigned resuming:1;
unsigned long re_timeout;
+
+ struct usb_device *udev;
};
static struct dummy *the_controller;
@@ -822,7 +822,12 @@
dum = container_of (hcd, struct dummy, hcd);
spin_lock_irqsave (&dum->lock, flags);
- dum->hdev = urb->dev->hcpriv;
+ if (!dum->udev) {
+ dum->udev = urb->dev;
+ usb_get_dev (dum->udev);
+ } else if (unlikely (dum->udev != urb->dev))
+ dev_err (hardware, "usb_device address has changed!\n");
+
urb->hcpriv = dum;
if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
urb->error_count = 1; /* mark as a new urb */
@@ -1029,17 +1034,12 @@
static void dummy_timer (unsigned long _dum)
{
struct dummy *dum = (struct dummy *) _dum;
- struct hcd_dev *hdev = dum->hdev;
+ struct hcd_dev *hdev;
struct list_head *entry, *tmp;
unsigned long flags;
int limit, total;
int i;
- if (!hdev) {
- dev_err (hardware, "timer fired with device gone?\n");
- return;
- }
-
/* simplistic model for one frame's bandwidth */
switch (dum->gadget.speed) {
case USB_SPEED_LOW:
@@ -1060,6 +1060,14 @@
/* look at each urb queued by the host side driver */
spin_lock_irqsave (&dum->lock, flags);
+
+ if (!dum->udev) {
+ dev_err (hardware, "timer fired with no URBs pending?\n");
+ spin_unlock_irqrestore (&dum->lock, flags);
+ return;
+ }
+ hdev = dum->udev->hcpriv;
+
for (i = 0; i < DUMMY_ENDPOINTS; i++) {
if (!ep_name [i])
break;
@@ -1331,7 +1339,11 @@
/* want a 1 msec delay here */
if (!list_empty (&hdev->urb_list))
- mod_timer (&dum->timer, jiffies + 1);
+ mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
+ else {
+ usb_put_dev (dum->udev);
+ dum->udev = NULL;
+ }
spin_unlock_irqrestore (&dum->lock, flags);
}
@@ -1568,10 +1580,12 @@
struct urb *urb;
size_t size = 0;
unsigned long flags;
+ struct hcd_dev *hdev;
spin_lock_irqsave (&dum->lock, flags);
- if (dum->hdev) {
- list_for_each_entry (urb, &dum->hdev->urb_list, urb_list) {
+ if (dum->udev) {
+ hdev = dum->udev->hcpriv;
+ list_for_each_entry (urb, &hdev->urb_list, urb_list) {
size_t temp;
temp = show_urb (buf, PAGE_SIZE - size, urb);
-------------------------------------------------------
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