u8 fifo_buf [FIFO_SIZE];
u16 devstatus;
+ struct hcd_dev *hdev;
+
/*
* MASTER/HOST side support
*/
struct completion released;
unsigned resuming:1;
unsigned long re_timeout;
-
- struct usb_device *udev;
};
static struct dummy *the_controller;
struct dummy_ep *ep;
/* prevent any more requests */
+ dum->hdev = 0;
dum->address = 0;
- /* The timer is left running so that outstanding URBs can fail */
+ /* this might not succeed ... */
+ del_timer (&dum->timer);
/* nuke any pending requests first, so driver i/o is quiesced */
list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list)
driver_unregister (&driver->driver);
+ del_timer_sync (&dum->timer);
return 0;
}
EXPORT_SYMBOL (usb_gadget_unregister_driver);
dum = container_of (hcd, struct dummy, hcd);
spin_lock_irqsave (&dum->lock, flags);
- 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");
-
+ dum->hdev = urb->dev->hcpriv;
urb->hcpriv = dum;
if (usb_pipetype (urb->pipe) == PIPE_CONTROL)
urb->error_count = 1; /* mark as a new urb */
static void dummy_timer (unsigned long _dum)
{
struct dummy *dum = (struct dummy *) _dum;
- struct hcd_dev *hdev;
+ struct hcd_dev *hdev = dum->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:
/* 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;
/* want a 1 msec delay here */
if (!list_empty (&hdev->urb_list))
- mod_timer (&dum->timer, jiffies + msecs_to_jiffies(1));
- else {
- usb_put_dev (dum->udev);
- dum->udev = NULL;
- }
+ mod_timer (&dum->timer, jiffies + 1);
spin_unlock_irqrestore (&dum->lock, flags);
}
struct urb *urb;
size_t size = 0;
unsigned long flags;
- struct hcd_dev *hdev;
spin_lock_irqsave (&dum->lock, flags);
- if (dum->udev) {
- hdev = dum->udev->hcpriv;
- list_for_each_entry (urb, &hdev->urb_list, urb_list) {
+ if (dum->hdev) {
+ list_for_each_entry (urb, &dum->hdev->urb_list, urb_list) {
size_t temp;
temp = show_urb (buf, PAGE_SIZE - size, urb);