usb: gadget: move ep_matches() from epautoconf to udc-core
authorRobert Baldyga <r.baldyga@samsung.com>
Thu, 6 Aug 2015 12:11:11 +0000 (14:11 +0200)
committerFelipe Balbi <balbi@ti.com>
Thu, 6 Aug 2015 14:32:57 +0000 (09:32 -0500)
Move ep_matches() function to udc-core and rename it to
usb_gadget_ep_match_desc(). This function can be used by UDC drivers
in 'match_ep' callback to avoid writing lots of repetitive code.

Replace all calls of ep_matches() with usb_gadget_ep_match_desc().

Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
drivers/usb/gadget/epautoconf.c
drivers/usb/gadget/udc/udc-core.c
include/linux/usb/gadget.h

index f000c73..d49af4f 100644 (file)
 
 #include "gadget_chips.h"
 
-static int
-ep_matches (
-       struct usb_gadget               *gadget,
-       struct usb_ep                   *ep,
-       struct usb_endpoint_descriptor  *desc,
-       struct usb_ss_ep_comp_descriptor *ep_comp
-)
-{
-       u8              type;
-       u16             max;
-       int             num_req_streams = 0;
-
-       /* endpoint already claimed? */
-       if (ep->claimed)
-               return 0;
-
-       type = usb_endpoint_type(desc);
-       max = 0x7ff & usb_endpoint_maxp(desc);
-
-       if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in)
-               return 0;
-       if (usb_endpoint_dir_out(desc) && !ep->caps.dir_out)
-               return 0;
-
-       if (max > ep->maxpacket_limit)
-               return 0;
-
-       /* "high bandwidth" works only at high speed */
-       if (!gadget_is_dualspeed(gadget) && usb_endpoint_maxp(desc) & (3<<11))
-               return 0;
-
-       switch (type) {
-       case USB_ENDPOINT_XFER_CONTROL:
-               /* only support ep0 for portable CONTROL traffic */
-               return 0;
-       case USB_ENDPOINT_XFER_ISOC:
-               if (!ep->caps.type_iso)
-                       return 0;
-               /* ISO:  limit 1023 bytes full speed,
-                * 1024 high/super speed
-                */
-               if (!gadget_is_dualspeed(gadget) && max > 1023)
-                       return 0;
-               break;
-       case USB_ENDPOINT_XFER_BULK:
-               if (!ep->caps.type_bulk)
-                       return 0;
-               if (ep_comp && gadget_is_superspeed(gadget)) {
-                       /* Get the number of required streams from the
-                        * EP companion descriptor and see if the EP
-                        * matches it
-                        */
-                       num_req_streams = ep_comp->bmAttributes & 0x1f;
-                       if (num_req_streams > ep->max_streams)
-                               return 0;
-               }
-               break;
-       case USB_ENDPOINT_XFER_INT:
-               /* Bulk endpoints handle interrupt transfers,
-                * except the toggle-quirky iso-synch kind
-                */
-               if (!ep->caps.type_int && !ep->caps.type_bulk)
-                       return 0;
-               /* INT:  limit 64 bytes full speed,
-                * 1024 high/super speed
-                */
-               if (!gadget_is_dualspeed(gadget) && max > 64)
-                       return 0;
-               break;
-       }
-
-       /* MATCH!! */
-
-       return 1;
-}
-
 static struct usb_ep *
 find_ep (struct usb_gadget *gadget, const char *name)
 {
@@ -180,10 +104,12 @@ struct usb_ep *usb_ep_autoconfig_ss(
                if (type == USB_ENDPOINT_XFER_INT) {
                        /* ep-e, ep-f are PIO with only 64 byte fifos */
                        ep = find_ep(gadget, "ep-e");
-                       if (ep && ep_matches(gadget, ep, desc, ep_comp))
+                       if (ep && usb_gadget_ep_match_desc(gadget,
+                                       ep, desc, ep_comp))
                                goto found_ep;
                        ep = find_ep(gadget, "ep-f");
-                       if (ep && ep_matches(gadget, ep, desc, ep_comp))
+                       if (ep && usb_gadget_ep_match_desc(gadget,
+                                       ep, desc, ep_comp))
                                goto found_ep;
                }
 
@@ -191,20 +117,21 @@ struct usb_ep *usb_ep_autoconfig_ss(
                snprintf(name, sizeof(name), "ep%d%s", usb_endpoint_num(desc),
                                usb_endpoint_dir_in(desc) ? "in" : "out");
                ep = find_ep(gadget, name);
-               if (ep && ep_matches(gadget, ep, desc, ep_comp))
+               if (ep && usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
                        goto found_ep;
        } else if (gadget_is_goku (gadget)) {
                if (USB_ENDPOINT_XFER_INT == type) {
                        /* single buffering is enough */
                        ep = find_ep(gadget, "ep3-bulk");
-                       if (ep && ep_matches(gadget, ep, desc, ep_comp))
+                       if (ep && usb_gadget_ep_match_desc(gadget,
+                                       ep, desc, ep_comp))
                                goto found_ep;
                } else if (USB_ENDPOINT_XFER_BULK == type
                                && (USB_DIR_IN & desc->bEndpointAddress)) {
                        /* DMA may be available */
                        ep = find_ep(gadget, "ep2-bulk");
-                       if (ep && ep_matches(gadget, ep, desc,
-                                             ep_comp))
+                       if (ep && usb_gadget_ep_match_desc(gadget,
+                                       ep, desc, ep_comp))
                                goto found_ep;
                }
 
@@ -223,14 +150,14 @@ struct usb_ep *usb_ep_autoconfig_ss(
                                ep = find_ep(gadget, "ep2out");
                } else
                        ep = NULL;
-               if (ep && ep_matches(gadget, ep, desc, ep_comp))
+               if (ep && usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
                        goto found_ep;
 #endif
        }
 
        /* Second, look at endpoints until an unclaimed one looks usable */
        list_for_each_entry (ep, &gadget->ep_list, ep_list) {
-               if (ep_matches(gadget, ep, desc, ep_comp))
+               if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
                        goto found_ep;
        }
 
index 362ee8a..b6427d1 100644 (file)
@@ -131,6 +131,75 @@ EXPORT_SYMBOL_GPL(usb_gadget_giveback_request);
 
 /* ------------------------------------------------------------------------- */
 
+int usb_gadget_ep_match_desc(struct usb_gadget *gadget,
+               struct usb_ep *ep, struct usb_endpoint_descriptor *desc,
+               struct usb_ss_ep_comp_descriptor *ep_comp)
+{
+       u8              type;
+       u16             max;
+       int             num_req_streams = 0;
+
+       /* endpoint already claimed? */
+       if (ep->claimed)
+               return 0;
+
+       type = usb_endpoint_type(desc);
+       max = 0x7ff & usb_endpoint_maxp(desc);
+
+       if (usb_endpoint_dir_in(desc) && !ep->caps.dir_in)
+               return 0;
+       if (usb_endpoint_dir_out(desc) && !ep->caps.dir_out)
+               return 0;
+
+       if (max > ep->maxpacket_limit)
+               return 0;
+
+       /* "high bandwidth" works only at high speed */
+       if (!gadget_is_dualspeed(gadget) && usb_endpoint_maxp(desc) & (3<<11))
+               return 0;
+
+       switch (type) {
+       case USB_ENDPOINT_XFER_CONTROL:
+               /* only support ep0 for portable CONTROL traffic */
+               return 0;
+       case USB_ENDPOINT_XFER_ISOC:
+               if (!ep->caps.type_iso)
+                       return 0;
+               /* ISO:  limit 1023 bytes full speed, 1024 high/super speed */
+               if (!gadget_is_dualspeed(gadget) && max > 1023)
+                       return 0;
+               break;
+       case USB_ENDPOINT_XFER_BULK:
+               if (!ep->caps.type_bulk)
+                       return 0;
+               if (ep_comp && gadget_is_superspeed(gadget)) {
+                       /* Get the number of required streams from the
+                        * EP companion descriptor and see if the EP
+                        * matches it
+                        */
+                       num_req_streams = ep_comp->bmAttributes & 0x1f;
+                       if (num_req_streams > ep->max_streams)
+                               return 0;
+               }
+               break;
+       case USB_ENDPOINT_XFER_INT:
+               /* Bulk endpoints handle interrupt transfers,
+                * except the toggle-quirky iso-synch kind
+                */
+               if (!ep->caps.type_int && !ep->caps.type_bulk)
+                       return 0;
+               /* INT:  limit 64 bytes full speed, 1024 high/super speed */
+               if (!gadget_is_dualspeed(gadget) && max > 64)
+                       return 0;
+               break;
+       }
+
+       return 1;
+}
+EXPORT_SYMBOL_GPL(usb_gadget_ep_match_desc);
+
+/* ------------------------------------------------------------------------- */
+
 static void usb_gadget_state_work(struct work_struct *work)
 {
        struct usb_gadget *gadget = work_to_gadget(work);
index 303214b..e04fd63 100644 (file)
@@ -1204,6 +1204,14 @@ extern void usb_gadget_giveback_request(struct usb_ep *ep,
 
 /*-------------------------------------------------------------------------*/
 
+/* utility to check if endpoint caps match descriptor needs */
+
+extern int usb_gadget_ep_match_desc(struct usb_gadget *gadget,
+               struct usb_ep *ep, struct usb_endpoint_descriptor *desc,
+               struct usb_ss_ep_comp_descriptor *ep_comp);
+
+/*-------------------------------------------------------------------------*/
+
 /* utility to update vbus status for udc core, it may be scheduled */
 extern void usb_udc_vbus_handler(struct usb_gadget *gadget, bool status);