]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/usb/gadget/function/f_sourcesink.c
Merge remote-tracking branch 'target-updates/for-next'
[karo-tx-linux.git] / drivers / usb / gadget / function / f_sourcesink.c
index 68efa01bdf4df192c692b4aafca429af9b98e0a9..9f3ced62d9162c991c03b0db68d10fd0cbe06ea9 100644 (file)
@@ -50,6 +50,13 @@ struct f_sourcesink {
        struct usb_ep           *iso_in_ep;
        struct usb_ep           *iso_out_ep;
        int                     cur_alt;
+
+       unsigned pattern;
+       unsigned isoc_interval;
+       unsigned isoc_maxpacket;
+       unsigned isoc_mult;
+       unsigned isoc_maxburst;
+       unsigned buflen;
 };
 
 static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
@@ -57,13 +64,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
        return container_of(f, struct f_sourcesink, function);
 }
 
-static unsigned pattern;
-static unsigned isoc_interval;
-static unsigned isoc_maxpacket;
-static unsigned isoc_mult;
-static unsigned isoc_maxburst;
-static unsigned buflen;
-
 /*-------------------------------------------------------------------------*/
 
 static struct usb_interface_descriptor source_sink_intf_alt0 = {
@@ -298,7 +298,9 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
 
 static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len)
 {
-       return alloc_ep_req(ep, len, buflen);
+       struct f_sourcesink             *ss = ep->driver_data;
+
+       return alloc_ep_req(ep, len, ss->buflen);
 }
 
 void free_ep_req(struct usb_ep *ep, struct usb_request *req)
@@ -357,22 +359,22 @@ autoconf_fail:
                goto autoconf_fail;
 
        /* sanity check the isoc module parameters */
-       if (isoc_interval < 1)
-               isoc_interval = 1;
-       if (isoc_interval > 16)
-               isoc_interval = 16;
-       if (isoc_mult > 2)
-               isoc_mult = 2;
-       if (isoc_maxburst > 15)
-               isoc_maxburst = 15;
+       if (ss->isoc_interval < 1)
+               ss->isoc_interval = 1;
+       if (ss->isoc_interval > 16)
+               ss->isoc_interval = 16;
+       if (ss->isoc_mult > 2)
+               ss->isoc_mult = 2;
+       if (ss->isoc_maxburst > 15)
+               ss->isoc_maxburst = 15;
 
        /* fill in the FS isoc descriptors from the module parameters */
-       fs_iso_source_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
-                                               1023 : isoc_maxpacket;
-       fs_iso_source_desc.bInterval = isoc_interval;
-       fs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket > 1023 ?
-                                               1023 : isoc_maxpacket;
-       fs_iso_sink_desc.bInterval = isoc_interval;
+       fs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
+                                               1023 : ss->isoc_maxpacket;
+       fs_iso_source_desc.bInterval = ss->isoc_interval;
+       fs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket > 1023 ?
+                                               1023 : ss->isoc_maxpacket;
+       fs_iso_sink_desc.bInterval = ss->isoc_interval;
 
        /* allocate iso endpoints */
        ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_source_desc);
@@ -394,8 +396,8 @@ no_iso:
                ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL;
        }
 
-       if (isoc_maxpacket > 1024)
-               isoc_maxpacket = 1024;
+       if (ss->isoc_maxpacket > 1024)
+               ss->isoc_maxpacket = 1024;
 
        /* support high speed hardware */
        hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress;
@@ -406,15 +408,15 @@ no_iso:
         * We assume that the user knows what they are doing and won't
         * give parameters that their UDC doesn't support.
         */
-       hs_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
-       hs_iso_source_desc.wMaxPacketSize |= isoc_mult << 11;
-       hs_iso_source_desc.bInterval = isoc_interval;
+       hs_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
+       hs_iso_source_desc.wMaxPacketSize |= ss->isoc_mult << 11;
+       hs_iso_source_desc.bInterval = ss->isoc_interval;
        hs_iso_source_desc.bEndpointAddress =
                fs_iso_source_desc.bEndpointAddress;
 
-       hs_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
-       hs_iso_sink_desc.wMaxPacketSize |= isoc_mult << 11;
-       hs_iso_sink_desc.bInterval = isoc_interval;
+       hs_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
+       hs_iso_sink_desc.wMaxPacketSize |= ss->isoc_mult << 11;
+       hs_iso_sink_desc.bInterval = ss->isoc_interval;
        hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
        /* support super speed hardware */
@@ -428,21 +430,21 @@ no_iso:
         * We assume that the user knows what they are doing and won't
         * give parameters that their UDC doesn't support.
         */
-       ss_iso_source_desc.wMaxPacketSize = isoc_maxpacket;
-       ss_iso_source_desc.bInterval = isoc_interval;
-       ss_iso_source_comp_desc.bmAttributes = isoc_mult;
-       ss_iso_source_comp_desc.bMaxBurst = isoc_maxburst;
-       ss_iso_source_comp_desc.wBytesPerInterval =
-               isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+       ss_iso_source_desc.wMaxPacketSize = ss->isoc_maxpacket;
+       ss_iso_source_desc.bInterval = ss->isoc_interval;
+       ss_iso_source_comp_desc.bmAttributes = ss->isoc_mult;
+       ss_iso_source_comp_desc.bMaxBurst = ss->isoc_maxburst;
+       ss_iso_source_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
+               (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
        ss_iso_source_desc.bEndpointAddress =
                fs_iso_source_desc.bEndpointAddress;
 
-       ss_iso_sink_desc.wMaxPacketSize = isoc_maxpacket;
-       ss_iso_sink_desc.bInterval = isoc_interval;
-       ss_iso_sink_comp_desc.bmAttributes = isoc_mult;
-       ss_iso_sink_comp_desc.bMaxBurst = isoc_maxburst;
-       ss_iso_sink_comp_desc.wBytesPerInterval =
-               isoc_maxpacket * (isoc_mult + 1) * (isoc_maxburst + 1);
+       ss_iso_sink_desc.wMaxPacketSize = ss->isoc_maxpacket;
+       ss_iso_sink_desc.bInterval = ss->isoc_interval;
+       ss_iso_sink_comp_desc.bmAttributes = ss->isoc_mult;
+       ss_iso_sink_comp_desc.bMaxBurst = ss->isoc_maxburst;
+       ss_iso_sink_comp_desc.wBytesPerInterval = ss->isoc_maxpacket *
+               (ss->isoc_mult + 1) * (ss->isoc_maxburst + 1);
        ss_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress;
 
        ret = usb_assign_descriptors(f, fs_source_sink_descs,
@@ -482,11 +484,11 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req)
        struct usb_composite_dev *cdev = ss->function.config->cdev;
        int max_packet_size = le16_to_cpu(ss->out_ep->desc->wMaxPacketSize);
 
-       if (pattern == 2)
+       if (ss->pattern == 2)
                return 0;
 
        for (i = 0; i < req->actual; i++, buf++) {
-               switch (pattern) {
+               switch (ss->pattern) {
 
                /* all-zeroes has no synchronization issues */
                case 0:
@@ -518,8 +520,9 @@ static void reinit_write_data(struct usb_ep *ep, struct usb_request *req)
        unsigned        i;
        u8              *buf = req->buf;
        int max_packet_size = le16_to_cpu(ep->desc->wMaxPacketSize);
+       struct f_sourcesink *ss = ep->driver_data;
 
-       switch (pattern) {
+       switch (ss->pattern) {
        case 0:
                memset(req->buf, 0, req->length);
                break;
@@ -549,7 +552,7 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)
        case 0:                         /* normal completion? */
                if (ep == ss->out_ep) {
                        check_read_data(ss, req);
-                       if (pattern != 2)
+                       if (ss->pattern != 2)
                                memset(req->buf, 0x55, req->length);
                }
                break;
@@ -598,15 +601,16 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
                if (is_iso) {
                        switch (speed) {
                        case USB_SPEED_SUPER:
-                               size = isoc_maxpacket * (isoc_mult + 1) *
-                                               (isoc_maxburst + 1);
+                               size = ss->isoc_maxpacket *
+                                               (ss->isoc_mult + 1) *
+                                               (ss->isoc_maxburst + 1);
                                break;
                        case USB_SPEED_HIGH:
-                               size = isoc_maxpacket * (isoc_mult + 1);
+                               size = ss->isoc_maxpacket * (ss->isoc_mult + 1);
                                break;
                        default:
-                               size = isoc_maxpacket > 1023 ?
-                                               1023 : isoc_maxpacket;
+                               size = ss->isoc_maxpacket > 1023 ?
+                                               1023 : ss->isoc_maxpacket;
                                break;
                        }
                        ep = is_in ? ss->iso_in_ep : ss->iso_out_ep;
@@ -622,7 +626,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in,
                req->complete = source_sink_complete;
                if (is_in)
                        reinit_write_data(ep, req);
-               else if (pattern != 2)
+               else if (ss->pattern != 2)
                        memset(req->buf, 0x55, req->length);
 
                status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@ -859,12 +863,12 @@ static struct usb_function *source_sink_alloc_func(
        ss_opts->refcnt++;
        mutex_unlock(&ss_opts->lock);
 
-       pattern = ss_opts->pattern;
-       isoc_interval = ss_opts->isoc_interval;
-       isoc_maxpacket = ss_opts->isoc_maxpacket;
-       isoc_mult = ss_opts->isoc_mult;
-       isoc_maxburst = ss_opts->isoc_maxburst;
-       buflen = ss_opts->bulk_buflen;
+       ss->pattern = ss_opts->pattern;
+       ss->isoc_interval = ss_opts->isoc_interval;
+       ss->isoc_maxpacket = ss_opts->isoc_maxpacket;
+       ss->isoc_mult = ss_opts->isoc_mult;
+       ss->isoc_maxburst = ss_opts->isoc_maxburst;
+       ss->buflen = ss_opts->bulk_buflen;
 
        ss->function.name = "source/sink";
        ss->function.bind = sourcesink_bind;
@@ -885,9 +889,6 @@ static inline struct f_ss_opts *to_f_ss_opts(struct config_item *item)
                            func_inst.group);
 }
 
-CONFIGFS_ATTR_STRUCT(f_ss_opts);
-CONFIGFS_ATTR_OPS(f_ss_opts);
-
 static void ss_attr_release(struct config_item *item)
 {
        struct f_ss_opts *ss_opts = to_f_ss_opts(item);
@@ -897,12 +898,11 @@ static void ss_attr_release(struct config_item *item)
 
 static struct configfs_item_operations ss_item_ops = {
        .release                = ss_attr_release,
-       .show_attribute         = f_ss_opts_attr_show,
-       .store_attribute        = f_ss_opts_attr_store,
 };
 
-static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_pattern_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -912,9 +912,10 @@ static ssize_t f_ss_opts_pattern_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_pattern_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_pattern_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -940,13 +941,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_pattern =
-       __CONFIGFS_ATTR(pattern, S_IRUGO | S_IWUSR,
-                       f_ss_opts_pattern_show,
-                       f_ss_opts_pattern_store);
+CONFIGFS_ATTR(f_ss_opts_, pattern);
 
-static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_interval_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -956,9 +955,10 @@ static ssize_t f_ss_opts_isoc_interval_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_interval_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_interval_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -984,13 +984,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_interval =
-       __CONFIGFS_ATTR(isoc_interval, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_interval_show,
-                       f_ss_opts_isoc_interval_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_interval);
 
-static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_maxpacket_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1000,9 +998,10 @@ static ssize_t f_ss_opts_isoc_maxpacket_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_maxpacket_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_maxpacket_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u16 num;
 
@@ -1028,13 +1027,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_maxpacket =
-       __CONFIGFS_ATTR(isoc_maxpacket, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_maxpacket_show,
-                       f_ss_opts_isoc_maxpacket_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_maxpacket);
 
-static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_mult_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1044,9 +1041,10 @@ static ssize_t f_ss_opts_isoc_mult_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_mult_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_mult_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -1072,13 +1070,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_mult =
-       __CONFIGFS_ATTR(isoc_mult, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_mult_show,
-                       f_ss_opts_isoc_mult_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_mult);
 
-static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_isoc_maxburst_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1088,9 +1084,10 @@ static ssize_t f_ss_opts_isoc_maxburst_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_isoc_maxburst_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_isoc_maxburst_store(struct config_item *item,
                                       const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u8 num;
 
@@ -1116,13 +1113,11 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_isoc_maxburst =
-       __CONFIGFS_ATTR(isoc_maxburst, S_IRUGO | S_IWUSR,
-                       f_ss_opts_isoc_maxburst_show,
-                       f_ss_opts_isoc_maxburst_store);
+CONFIGFS_ATTR(f_ss_opts_, isoc_maxburst);
 
-static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
+static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, char *page)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int result;
 
        mutex_lock(&opts->lock);
@@ -1132,9 +1127,10 @@ static ssize_t f_ss_opts_bulk_buflen_show(struct f_ss_opts *opts, char *page)
        return result;
 }
 
-static ssize_t f_ss_opts_bulk_buflen_store(struct f_ss_opts *opts,
+static ssize_t f_ss_opts_bulk_buflen_store(struct config_item *item,
                                           const char *page, size_t len)
 {
+       struct f_ss_opts *opts = to_f_ss_opts(item);
        int ret;
        u32 num;
 
@@ -1155,18 +1151,15 @@ end:
        return ret;
 }
 
-static struct f_ss_opts_attribute f_ss_opts_bulk_buflen =
-       __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR,
-                       f_ss_opts_bulk_buflen_show,
-                       f_ss_opts_bulk_buflen_store);
+CONFIGFS_ATTR(f_ss_opts_, bulk_buflen);
 
 static struct configfs_attribute *ss_attrs[] = {
-       &f_ss_opts_pattern.attr,
-       &f_ss_opts_isoc_interval.attr,
-       &f_ss_opts_isoc_maxpacket.attr,
-       &f_ss_opts_isoc_mult.attr,
-       &f_ss_opts_isoc_maxburst.attr,
-       &f_ss_opts_bulk_buflen.attr,
+       &f_ss_opts_attr_pattern,
+       &f_ss_opts_attr_isoc_interval,
+       &f_ss_opts_attr_isoc_maxpacket,
+       &f_ss_opts_attr_isoc_mult,
+       &f_ss_opts_attr_isoc_maxburst,
+       &f_ss_opts_attr_bulk_buflen,
        NULL,
 };