ChangeSet 1.1722.83.2, 2004/06/02 13:18:53-07:00, stern@rowland.harvard.edu [PATCH] USB: Fix disconnect bug in dummy_hcd Greg: This patch fixes a bug in disconnect handling for the dummy_hcd driver. After a disconnect the driver would still accept URBs for endpoint 0, leading to an oops. It also improves the ad-hoc technique used by the driver to track its gadget's struct usb_device and fixes the way port-power changes are handled. Please apply. Alan Stern Signed-off-by: Greg Kroah-Hartman drivers/usb/gadget/dummy_hcd.c | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff -Nru a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c --- a/drivers/usb/gadget/dummy_hcd.c Fri Jun 18 11:07:23 2004 +++ b/drivers/usb/gadget/dummy_hcd.c Fri Jun 18 11:07:23 2004 @@ -825,8 +825,7 @@ dum = container_of (hcd, struct dummy, hcd); spin_lock_irqsave (&dum->lock, flags); - if (!dum->hdev) - dum->hdev = urb->dev->hcpriv; + dum->hdev = urb->dev->hcpriv; urb->hcpriv = dum; if (usb_pipetype (urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ @@ -994,10 +993,17 @@ return limit; } +#define is_active(dum) ((dum->port_status & \ + (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE | \ + USB_PORT_STAT_SUSPEND)) \ + == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) + static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) { int i; + if (!is_active (dum)) + return NULL; if ((address & ~USB_DIR_IN) == 0) return &dum->ep [0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { @@ -1011,6 +1017,8 @@ return NULL; } +#undef is_active + #define Dev_Request (USB_TYPE_STANDARD | USB_RECIP_DEVICE) #define Dev_InRequest (Dev_Request | USB_DIR_IN) #define Intf_Request (USB_TYPE_STANDARD | USB_RECIP_INTERFACE) @@ -1404,9 +1412,8 @@ break; case USB_PORT_FEAT_POWER: dum->port_status = 0; - dum->address = 0; - dum->hdev = 0; dum->resuming = 0; + stop_activity(dum, dum->driver); break; default: dum->port_status &= ~(1 << wValue);