diff options
Diffstat (limited to 'drivers/usb/gadget/net2280.c')
-rw-r--r-- | drivers/usb/gadget/net2280.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index d954daa8e9e0..0b590831582c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -1040,6 +1040,7 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
1040 | 1040 | ||
1041 | } /* else the irq handler advances the queue. */ | 1041 | } /* else the irq handler advances the queue. */ |
1042 | 1042 | ||
1043 | ep->responded = 1; | ||
1043 | if (req) | 1044 | if (req) |
1044 | list_add_tail (&req->queue, &ep->queue); | 1045 | list_add_tail (&req->queue, &ep->queue); |
1045 | done: | 1046 | done: |
@@ -1774,8 +1775,8 @@ static DEVICE_ATTR (queues, S_IRUGO, show_queues, NULL); | |||
1774 | 1775 | ||
1775 | #else | 1776 | #else |
1776 | 1777 | ||
1777 | #define device_create_file(a,b) do {} while (0) | 1778 | #define device_create_file(a,b) (0) |
1778 | #define device_remove_file device_create_file | 1779 | #define device_remove_file(a,b) do { } while (0) |
1779 | 1780 | ||
1780 | #endif | 1781 | #endif |
1781 | 1782 | ||
@@ -2044,8 +2045,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2044 | return retval; | 2045 | return retval; |
2045 | } | 2046 | } |
2046 | 2047 | ||
2047 | device_create_file (&dev->pdev->dev, &dev_attr_function); | 2048 | retval = device_create_file (&dev->pdev->dev, &dev_attr_function); |
2048 | device_create_file (&dev->pdev->dev, &dev_attr_queues); | 2049 | if (retval) goto err_unbind; |
2050 | retval = device_create_file (&dev->pdev->dev, &dev_attr_queues); | ||
2051 | if (retval) goto err_func; | ||
2049 | 2052 | ||
2050 | /* ... then enable host detection and ep0; and we're ready | 2053 | /* ... then enable host detection and ep0; and we're ready |
2051 | * for set_configuration as well as eventual disconnect. | 2054 | * for set_configuration as well as eventual disconnect. |
@@ -2060,6 +2063,14 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2060 | 2063 | ||
2061 | /* pci writes may still be posted */ | 2064 | /* pci writes may still be posted */ |
2062 | return 0; | 2065 | return 0; |
2066 | |||
2067 | err_func: | ||
2068 | device_remove_file (&dev->pdev->dev, &dev_attr_function); | ||
2069 | err_unbind: | ||
2070 | driver->unbind (&dev->gadget); | ||
2071 | dev->gadget.dev.driver = NULL; | ||
2072 | dev->driver = NULL; | ||
2073 | return retval; | ||
2063 | } | 2074 | } |
2064 | EXPORT_SYMBOL (usb_gadget_register_driver); | 2075 | EXPORT_SYMBOL (usb_gadget_register_driver); |
2065 | 2076 | ||
@@ -2178,7 +2189,8 @@ static void handle_ep_small (struct net2280_ep *ep) | |||
2178 | ep->stopped = 1; | 2189 | ep->stopped = 1; |
2179 | set_halt (ep); | 2190 | set_halt (ep); |
2180 | mode = 2; | 2191 | mode = 2; |
2181 | } else if (!req && !ep->stopped) | 2192 | } else if (ep->responded && |
2193 | !req && !ep->stopped) | ||
2182 | write_fifo (ep, NULL); | 2194 | write_fifo (ep, NULL); |
2183 | } | 2195 | } |
2184 | } else { | 2196 | } else { |
@@ -2193,7 +2205,7 @@ static void handle_ep_small (struct net2280_ep *ep) | |||
2193 | } else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) | 2205 | } else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) |
2194 | && req | 2206 | && req |
2195 | && req->req.actual == req->req.length) | 2207 | && req->req.actual == req->req.length) |
2196 | || !req) { | 2208 | || (ep->responded && !req)) { |
2197 | ep->dev->protocol_stall = 1; | 2209 | ep->dev->protocol_stall = 1; |
2198 | set_halt (ep); | 2210 | set_halt (ep); |
2199 | ep->stopped = 1; | 2211 | ep->stopped = 1; |
@@ -2459,6 +2471,7 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2459 | /* we made the hardware handle most lowlevel requests; | 2471 | /* we made the hardware handle most lowlevel requests; |
2460 | * everything else goes uplevel to the gadget code. | 2472 | * everything else goes uplevel to the gadget code. |
2461 | */ | 2473 | */ |
2474 | ep->responded = 1; | ||
2462 | switch (u.r.bRequest) { | 2475 | switch (u.r.bRequest) { |
2463 | case USB_REQ_GET_STATUS: { | 2476 | case USB_REQ_GET_STATUS: { |
2464 | struct net2280_ep *e; | 2477 | struct net2280_ep *e; |
@@ -2527,6 +2540,7 @@ delegate: | |||
2527 | u.r.bRequestType, u.r.bRequest, | 2540 | u.r.bRequestType, u.r.bRequest, |
2528 | w_value, w_index, w_length, | 2541 | w_value, w_index, w_length, |
2529 | readl (&ep->regs->ep_cfg)); | 2542 | readl (&ep->regs->ep_cfg)); |
2543 | ep->responded = 0; | ||
2530 | spin_unlock (&dev->lock); | 2544 | spin_unlock (&dev->lock); |
2531 | tmp = dev->driver->setup (&dev->gadget, &u.r); | 2545 | tmp = dev->driver->setup (&dev->gadget, &u.r); |
2532 | spin_lock (&dev->lock); | 2546 | spin_lock (&dev->lock); |
@@ -2974,8 +2988,10 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2974 | : "disabled"); | 2988 | : "disabled"); |
2975 | the_controller = dev; | 2989 | the_controller = dev; |
2976 | 2990 | ||
2977 | device_register (&dev->gadget.dev); | 2991 | retval = device_register (&dev->gadget.dev); |
2978 | device_create_file (&pdev->dev, &dev_attr_registers); | 2992 | if (retval) goto done; |
2993 | retval = device_create_file (&pdev->dev, &dev_attr_registers); | ||
2994 | if (retval) goto done; | ||
2979 | 2995 | ||
2980 | return 0; | 2996 | return 0; |
2981 | 2997 | ||