]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/usb/gadget/dummy_hcd.c
Merge branch 'for-paul-38-rebased' of git://gitorious.org/linux-omap-dss2/linux
[mv-sheeva.git] / drivers / usb / gadget / dummy_hcd.c
index 1d2a2abbfa803e16ba5cb0d4a7f1bd010eca268e..13b9f47feecd6e3e4719444f8c730b9e2f2129dc 100644 (file)
@@ -1197,6 +1197,139 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address)
 #define Ep_Request     (USB_TYPE_STANDARD | USB_RECIP_ENDPOINT)
 #define Ep_InRequest   (Ep_Request | USB_DIR_IN)
 
+
+/**
+ * handle_control_request() - handles all control transfers
+ * @dum: pointer to dummy (the_controller)
+ * @urb: the urb request to handle
+ * @setup: pointer to the setup data for a USB device control
+ *      request
+ * @status: pointer to request handling status
+ *
+ * Return 0 - if the request was handled
+ *       1 - if the request wasn't handles
+ *       error code on error
+ */
+static int handle_control_request(struct dummy *dum, struct urb *urb,
+                                 struct usb_ctrlrequest *setup,
+                                 int *status)
+{
+       struct dummy_ep         *ep2;
+       int                     ret_val = 1;
+       unsigned        w_index;
+       unsigned        w_value;
+
+       w_index = le16_to_cpu(setup->wIndex);
+       w_value = le16_to_cpu(setup->wValue);
+       switch (setup->bRequest) {
+       case USB_REQ_SET_ADDRESS:
+               if (setup->bRequestType != Dev_Request)
+                       break;
+               dum->address = w_value;
+               *status = 0;
+               dev_dbg(udc_dev(dum), "set_address = %d\n",
+                               w_value);
+               ret_val = 0;
+               break;
+       case USB_REQ_SET_FEATURE:
+               if (setup->bRequestType == Dev_Request) {
+                       ret_val = 0;
+                       switch (w_value) {
+                       case USB_DEVICE_REMOTE_WAKEUP:
+                               break;
+                       case USB_DEVICE_B_HNP_ENABLE:
+                               dum->gadget.b_hnp_enable = 1;
+                               break;
+                       case USB_DEVICE_A_HNP_SUPPORT:
+                               dum->gadget.a_hnp_support = 1;
+                               break;
+                       case USB_DEVICE_A_ALT_HNP_SUPPORT:
+                               dum->gadget.a_alt_hnp_support = 1;
+                               break;
+                       default:
+                               ret_val = -EOPNOTSUPP;
+                       }
+                       if (ret_val == 0) {
+                               dum->devstatus |= (1 << w_value);
+                               *status = 0;
+                       }
+               } else if (setup->bRequestType == Ep_Request) {
+                       /* endpoint halt */
+                       ep2 = find_endpoint(dum, w_index);
+                       if (!ep2 || ep2->ep.name == ep0name) {
+                               ret_val = -EOPNOTSUPP;
+                               break;
+                       }
+                       ep2->halted = 1;
+                       ret_val = 0;
+                       *status = 0;
+               }
+               break;
+       case USB_REQ_CLEAR_FEATURE:
+               if (setup->bRequestType == Dev_Request) {
+                       ret_val = 0;
+                       switch (w_value) {
+                       case USB_DEVICE_REMOTE_WAKEUP:
+                               w_value = USB_DEVICE_REMOTE_WAKEUP;
+                               break;
+                       default:
+                               ret_val = -EOPNOTSUPP;
+                               break;
+                       }
+                       if (ret_val == 0) {
+                               dum->devstatus &= ~(1 << w_value);
+                               *status = 0;
+                       }
+               } else if (setup->bRequestType == Ep_Request) {
+                       /* endpoint halt */
+                       ep2 = find_endpoint(dum, w_index);
+                       if (!ep2) {
+                               ret_val = -EOPNOTSUPP;
+                               break;
+                       }
+                       if (!ep2->wedged)
+                               ep2->halted = 0;
+                       ret_val = 0;
+                       *status = 0;
+               }
+               break;
+       case USB_REQ_GET_STATUS:
+               if (setup->bRequestType == Dev_InRequest
+                               || setup->bRequestType == Intf_InRequest
+                               || setup->bRequestType == Ep_InRequest) {
+                       char *buf;
+                       /*
+                        * device: remote wakeup, selfpowered
+                        * interface: nothing
+                        * endpoint: halt
+                        */
+                       buf = (char *)urb->transfer_buffer;
+                       if (urb->transfer_buffer_length > 0) {
+                               if (setup->bRequestType == Ep_InRequest) {
+                                       ep2 = find_endpoint(dum, w_index);
+                                       if (!ep2) {
+                                               ret_val = -EOPNOTSUPP;
+                                               break;
+                                       }
+                                       buf[0] = ep2->halted;
+                               } else if (setup->bRequestType ==
+                                          Dev_InRequest) {
+                                       buf[0] = (u8)dum->devstatus;
+                               } else
+                                       buf[0] = 0;
+                       }
+                       if (urb->transfer_buffer_length > 1)
+                               buf[1] = 0;
+                       urb->actual_length = min_t(u32, 2,
+                               urb->transfer_buffer_length);
+                       ret_val = 0;
+                       *status = 0;
+               }
+               break;
+       }
+       return ret_val;
+}
+
 /* drive both sides of the transfers; looks like irq handlers to
  * both drivers except the callbacks aren't in_irq().
  */
@@ -1299,14 +1432,8 @@ restart:
                if (ep == &dum->ep [0] && ep->setup_stage) {
                        struct usb_ctrlrequest          setup;
                        int                             value = 1;
-                       struct dummy_ep                 *ep2;
-                       unsigned                        w_index;
-                       unsigned                        w_value;
 
                        setup = *(struct usb_ctrlrequest*) urb->setup_packet;
-                       w_index = le16_to_cpu(setup.wIndex);
-                       w_value = le16_to_cpu(setup.wValue);
-
                        /* paranoia, in case of stale queued data */
                        list_for_each_entry (req, &ep->queue, queue) {
                                list_del_init (&req->queue);
@@ -1328,117 +1455,9 @@ restart:
                        ep->last_io = jiffies;
                        ep->setup_stage = 0;
                        ep->halted = 0;
-                       switch (setup.bRequest) {
-                       case USB_REQ_SET_ADDRESS:
-                               if (setup.bRequestType != Dev_Request)
-                                       break;
-                               dum->address = w_value;
-                               status = 0;
-                               dev_dbg (udc_dev(dum), "set_address = %d\n",
-                                               w_value);
-                               value = 0;
-                               break;
-                       case USB_REQ_SET_FEATURE:
-                               if (setup.bRequestType == Dev_Request) {
-                                       value = 0;
-                                       switch (w_value) {
-                                       case USB_DEVICE_REMOTE_WAKEUP:
-                                               break;
-                                       case USB_DEVICE_B_HNP_ENABLE:
-                                               dum->gadget.b_hnp_enable = 1;
-                                               break;
-                                       case USB_DEVICE_A_HNP_SUPPORT:
-                                               dum->gadget.a_hnp_support = 1;
-                                               break;
-                                       case USB_DEVICE_A_ALT_HNP_SUPPORT:
-                                               dum->gadget.a_alt_hnp_support
-                                                       = 1;
-                                               break;
-                                       default:
-                                               value = -EOPNOTSUPP;
-                                       }
-                                       if (value == 0) {
-                                               dum->devstatus |=
-                                                       (1 << w_value);
-                                               status = 0;
-                                       }
 
-                               } else if (setup.bRequestType == Ep_Request) {
-                                       // endpoint halt
-                                       ep2 = find_endpoint (dum, w_index);
-                                       if (!ep2 || ep2->ep.name == ep0name) {
-                                               value = -EOPNOTSUPP;
-                                               break;
-                                       }
-                                       ep2->halted = 1;
-                                       value = 0;
-                                       status = 0;
-                               }
-                               break;
-                       case USB_REQ_CLEAR_FEATURE:
-                               if (setup.bRequestType == Dev_Request) {
-                                       switch (w_value) {
-                                       case USB_DEVICE_REMOTE_WAKEUP:
-                                               dum->devstatus &= ~(1 <<
-                                                       USB_DEVICE_REMOTE_WAKEUP);
-                                               value = 0;
-                                               status = 0;
-                                               break;
-                                       default:
-                                               value = -EOPNOTSUPP;
-                                               break;
-                                       }
-                               } else if (setup.bRequestType == Ep_Request) {
-                                       // endpoint halt
-                                       ep2 = find_endpoint (dum, w_index);
-                                       if (!ep2) {
-                                               value = -EOPNOTSUPP;
-                                               break;
-                                       }
-                                       if (!ep2->wedged)
-                                               ep2->halted = 0;
-                                       value = 0;
-                                       status = 0;
-                               }
-                               break;
-                       case USB_REQ_GET_STATUS:
-                               if (setup.bRequestType == Dev_InRequest
-                                               || setup.bRequestType
-                                                       == Intf_InRequest
-                                               || setup.bRequestType
-                                                       == Ep_InRequest
-                                               ) {
-                                       char *buf;
-
-                                       // device: remote wakeup, selfpowered
-                                       // interface: nothing
-                                       // endpoint: halt
-                                       buf = (char *)urb->transfer_buffer;
-                                       if (urb->transfer_buffer_length > 0) {
-                                               if (setup.bRequestType ==
-                                                               Ep_InRequest) {
-       ep2 = find_endpoint (dum, w_index);
-       if (!ep2) {
-               value = -EOPNOTSUPP;
-               break;
-       }
-       buf [0] = ep2->halted;
-                                               } else if (setup.bRequestType ==
-                                                               Dev_InRequest) {
-                                                       buf [0] = (u8)
-                                                               dum->devstatus;
-                                               } else
-                                                       buf [0] = 0;
-                                       }
-                                       if (urb->transfer_buffer_length > 1)
-                                               buf [1] = 0;
-                                       urb->actual_length = min_t(u32, 2,
-                                               urb->transfer_buffer_length);
-                                       value = 0;
-                                       status = 0;
-                               }
-                               break;
-                       }
+                       value = handle_control_request(dum, urb, &setup,
+                                                      &status);
 
                        /* gadget driver handles all other requests.  block
                         * until setup() returns; no reentrancy issues etc.