diff options
Diffstat (limited to 'drivers/usb/gadget')
38 files changed, 1114 insertions, 1574 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bcf83c0a6..33834aa09 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -113,7 +113,7 @@ config USB_GADGET_VBUS_DRAW config USB_GADGET_STORAGE_NUM_BUFFERS int "Number of storage pipeline buffers" - range 2 4 + range 2 32 default 2 help Usually 2 buffers are enough to establish a good buffering diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index b47449983..8b14c2a13 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -839,9 +839,7 @@ int usb_add_config(struct usb_composite_dev *cdev, } } - /* set_alt(), or next bind(), sets up - * ep->driver_data as needed. - */ + /* set_alt(), or next bind(), sets up ep->claimed as needed */ usb_ep_autoconfig_reset(cdev->gadget); done: @@ -1506,6 +1504,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) } else { cdev->desc.bcdUSB = cpu_to_le16(0x0210); } + } else { + cdev->desc.bcdUSB = cpu_to_le16(0x0200); } value = min(w_length, (u16) sizeof cdev->desc); diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 294eb74fb..163d305e1 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -64,6 +64,11 @@ struct gadget_info { char qw_sign[OS_STRING_QW_SIGN_LEN]; }; +static inline struct gadget_info *to_gadget_info(struct config_item *item) +{ + return container_of(to_config_group(item), struct gadget_info, group); +} + struct config_usb_cfg { struct config_group group; struct config_group strings_group; @@ -74,6 +79,12 @@ struct config_usb_cfg { struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1]; }; +static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item) +{ + return container_of(to_config_group(item), struct config_usb_cfg, + group); +} + struct gadget_strings { struct usb_gadget_strings stringtab_dev; struct usb_string strings[USB_GADGET_FIRST_AVAIL_IDX]; @@ -117,32 +128,25 @@ static int usb_string_copy(const char *s, char **s_copy) return 0; } -CONFIGFS_ATTR_STRUCT(gadget_info); -CONFIGFS_ATTR_STRUCT(config_usb_cfg); - -#define GI_DEVICE_DESC_ITEM_ATTR(name) \ - static struct gadget_info_attribute gadget_cdev_desc_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ - gadget_dev_desc_##name##_show, \ - gadget_dev_desc_##name##_store) - #define GI_DEVICE_DESC_SIMPLE_R_u8(__name) \ - static ssize_t gadget_dev_desc_##__name##_show(struct gadget_info *gi, \ +static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \ char *page) \ { \ - return sprintf(page, "0x%02x\n", gi->cdev.desc.__name); \ + return sprintf(page, "0x%02x\n", \ + to_gadget_info(item)->cdev.desc.__name); \ } #define GI_DEVICE_DESC_SIMPLE_R_u16(__name) \ - static ssize_t gadget_dev_desc_##__name##_show(struct gadget_info *gi, \ +static ssize_t gadget_dev_desc_##__name##_show(struct config_item *item, \ char *page) \ { \ - return sprintf(page, "0x%04x\n", le16_to_cpup(&gi->cdev.desc.__name)); \ + return sprintf(page, "0x%04x\n", \ + le16_to_cpup(&to_gadget_info(item)->cdev.desc.__name)); \ } #define GI_DEVICE_DESC_SIMPLE_W_u8(_name) \ - static ssize_t gadget_dev_desc_##_name##_store(struct gadget_info *gi, \ +static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ u8 val; \ @@ -150,12 +154,12 @@ CONFIGFS_ATTR_STRUCT(config_usb_cfg); ret = kstrtou8(page, 0, &val); \ if (ret) \ return ret; \ - gi->cdev.desc._name = val; \ + to_gadget_info(item)->cdev.desc._name = val; \ return len; \ } #define GI_DEVICE_DESC_SIMPLE_W_u16(_name) \ - static ssize_t gadget_dev_desc_##_name##_store(struct gadget_info *gi, \ +static ssize_t gadget_dev_desc_##_name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ u16 val; \ @@ -163,7 +167,7 @@ CONFIGFS_ATTR_STRUCT(config_usb_cfg); ret = kstrtou16(page, 0, &val); \ if (ret) \ return ret; \ - gi->cdev.desc._name = cpu_to_le16p(&val); \ + to_gadget_info(item)->cdev.desc._name = cpu_to_le16p(&val); \ return len; \ } @@ -193,7 +197,7 @@ static ssize_t is_valid_bcd(u16 bcd_val) return 0; } -static ssize_t gadget_dev_desc_bcdDevice_store(struct gadget_info *gi, +static ssize_t gadget_dev_desc_bcdDevice_store(struct config_item *item, const char *page, size_t len) { u16 bcdDevice; @@ -206,11 +210,11 @@ static ssize_t gadget_dev_desc_bcdDevice_store(struct gadget_info *gi, if (ret) return ret; - gi->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice); + to_gadget_info(item)->cdev.desc.bcdDevice = cpu_to_le16(bcdDevice); return len; } -static ssize_t gadget_dev_desc_bcdUSB_store(struct gadget_info *gi, +static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item, const char *page, size_t len) { u16 bcdUSB; @@ -223,13 +227,13 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct gadget_info *gi, if (ret) return ret; - gi->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB); + to_gadget_info(item)->cdev.desc.bcdUSB = cpu_to_le16(bcdUSB); return len; } -static ssize_t gadget_dev_desc_UDC_show(struct gadget_info *gi, char *page) +static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) { - return sprintf(page, "%s\n", gi->udc_name ?: ""); + return sprintf(page, "%s\n", to_gadget_info(item)->udc_name ?: ""); } static int unregister_gadget(struct gadget_info *gi) @@ -247,9 +251,10 @@ static int unregister_gadget(struct gadget_info *gi) return 0; } -static ssize_t gadget_dev_desc_UDC_store(struct gadget_info *gi, +static ssize_t gadget_dev_desc_UDC_store(struct config_item *item, const char *page, size_t len) { + struct gadget_info *gi = to_gadget_info(item); char *name; int ret; @@ -283,34 +288,29 @@ err: return ret; } -GI_DEVICE_DESC_ITEM_ATTR(bDeviceClass); -GI_DEVICE_DESC_ITEM_ATTR(bDeviceSubClass); -GI_DEVICE_DESC_ITEM_ATTR(bDeviceProtocol); -GI_DEVICE_DESC_ITEM_ATTR(bMaxPacketSize0); -GI_DEVICE_DESC_ITEM_ATTR(idVendor); -GI_DEVICE_DESC_ITEM_ATTR(idProduct); -GI_DEVICE_DESC_ITEM_ATTR(bcdDevice); -GI_DEVICE_DESC_ITEM_ATTR(bcdUSB); -GI_DEVICE_DESC_ITEM_ATTR(UDC); +CONFIGFS_ATTR(gadget_dev_desc_, bDeviceClass); +CONFIGFS_ATTR(gadget_dev_desc_, bDeviceSubClass); +CONFIGFS_ATTR(gadget_dev_desc_, bDeviceProtocol); +CONFIGFS_ATTR(gadget_dev_desc_, bMaxPacketSize0); +CONFIGFS_ATTR(gadget_dev_desc_, idVendor); +CONFIGFS_ATTR(gadget_dev_desc_, idProduct); +CONFIGFS_ATTR(gadget_dev_desc_, bcdDevice); +CONFIGFS_ATTR(gadget_dev_desc_, bcdUSB); +CONFIGFS_ATTR(gadget_dev_desc_, UDC); static struct configfs_attribute *gadget_root_attrs[] = { - &gadget_cdev_desc_bDeviceClass.attr, - &gadget_cdev_desc_bDeviceSubClass.attr, - &gadget_cdev_desc_bDeviceProtocol.attr, - &gadget_cdev_desc_bMaxPacketSize0.attr, - &gadget_cdev_desc_idVendor.attr, - &gadget_cdev_desc_idProduct.attr, - &gadget_cdev_desc_bcdDevice.attr, - &gadget_cdev_desc_bcdUSB.attr, - &gadget_cdev_desc_UDC.attr, + &gadget_dev_desc_attr_bDeviceClass, + &gadget_dev_desc_attr_bDeviceSubClass, + &gadget_dev_desc_attr_bDeviceProtocol, + &gadget_dev_desc_attr_bMaxPacketSize0, + &gadget_dev_desc_attr_idVendor, + &gadget_dev_desc_attr_idProduct, + &gadget_dev_desc_attr_bcdDevice, + &gadget_dev_desc_attr_bcdUSB, + &gadget_dev_desc_attr_UDC, NULL, }; -static inline struct gadget_info *to_gadget_info(struct config_item *item) -{ - return container_of(to_config_group(item), struct gadget_info, group); -} - static inline struct gadget_strings *to_gadget_strings(struct config_item *item) { return container_of(to_config_group(item), struct gadget_strings, @@ -324,12 +324,6 @@ static inline struct gadget_config_name *to_gadget_config_name( group); } -static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item *item) -{ - return container_of(to_config_group(item), struct config_usb_cfg, - group); -} - static inline struct usb_function_instance *to_usb_function_instance( struct config_item *item) { @@ -348,12 +342,8 @@ static void gadget_info_attr_release(struct config_item *item) kfree(gi); } -CONFIGFS_ATTR_OPS(gadget_info); - static struct configfs_item_operations gadget_root_item_ops = { .release = gadget_info_attr_release, - .show_attribute = gadget_info_attr_show, - .store_attribute = gadget_info_attr_store, }; static void gadget_config_attr_release(struct config_item *item) @@ -454,24 +444,20 @@ static int config_usb_cfg_unlink( return 0; } -CONFIGFS_ATTR_OPS(config_usb_cfg); - static struct configfs_item_operations gadget_config_item_ops = { .release = gadget_config_attr_release, - .show_attribute = config_usb_cfg_attr_show, - .store_attribute = config_usb_cfg_attr_store, .allow_link = config_usb_cfg_link, .drop_link = config_usb_cfg_unlink, }; -static ssize_t gadget_config_desc_MaxPower_show(struct config_usb_cfg *cfg, +static ssize_t gadget_config_desc_MaxPower_show(struct config_item *item, char *page) { - return sprintf(page, "%u\n", cfg->c.MaxPower); + return sprintf(page, "%u\n", to_config_usb_cfg(item)->c.MaxPower); } -static ssize_t gadget_config_desc_MaxPower_store(struct config_usb_cfg *cfg, +static ssize_t gadget_config_desc_MaxPower_store(struct config_item *item, const char *page, size_t len) { u16 val; @@ -481,17 +467,18 @@ static ssize_t gadget_config_desc_MaxPower_store(struct config_usb_cfg *cfg, return ret; if (DIV_ROUND_UP(val, 8) > 0xff) return -ERANGE; - cfg->c.MaxPower = val; + to_config_usb_cfg(item)->c.MaxPower = val; return len; } -static ssize_t gadget_config_desc_bmAttributes_show(struct config_usb_cfg *cfg, +static ssize_t gadget_config_desc_bmAttributes_show(struct config_item *item, char *page) { - return sprintf(page, "0x%02x\n", cfg->c.bmAttributes); + return sprintf(page, "0x%02x\n", + to_config_usb_cfg(item)->c.bmAttributes); } -static ssize_t gadget_config_desc_bmAttributes_store(struct config_usb_cfg *cfg, +static ssize_t gadget_config_desc_bmAttributes_store(struct config_item *item, const char *page, size_t len) { u8 val; @@ -504,22 +491,16 @@ static ssize_t gadget_config_desc_bmAttributes_store(struct config_usb_cfg *cfg, if (val & ~(USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER | USB_CONFIG_ATT_WAKEUP)) return -EINVAL; - cfg->c.bmAttributes = val; + to_config_usb_cfg(item)->c.bmAttributes = val; return len; } -#define CFG_CONFIG_DESC_ITEM_ATTR(name) \ - static struct config_usb_cfg_attribute gadget_usb_cfg_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ - gadget_config_desc_##name##_show, \ - gadget_config_desc_##name##_store) - -CFG_CONFIG_DESC_ITEM_ATTR(MaxPower); -CFG_CONFIG_DESC_ITEM_ATTR(bmAttributes); +CONFIGFS_ATTR(gadget_config_desc_, MaxPower); +CONFIGFS_ATTR(gadget_config_desc_, bmAttributes); static struct configfs_attribute *gadget_config_attrs[] = { - &gadget_usb_cfg_MaxPower.attr, - &gadget_usb_cfg_bmAttributes.attr, + &gadget_config_desc_attr_MaxPower, + &gadget_config_desc_attr_bmAttributes, NULL, }; @@ -616,11 +597,10 @@ static struct config_item_type functions_type = { .ct_owner = THIS_MODULE, }; -CONFIGFS_ATTR_STRUCT(gadget_config_name); GS_STRINGS_RW(gadget_config_name, configuration); static struct configfs_attribute *gadget_config_name_langid_attrs[] = { - &gadget_config_name_configuration.attr, + &gadget_config_name_attr_configuration, NULL, }; @@ -719,15 +699,14 @@ static struct config_item_type config_desc_type = { .ct_owner = THIS_MODULE, }; -CONFIGFS_ATTR_STRUCT(gadget_strings); GS_STRINGS_RW(gadget_strings, manufacturer); GS_STRINGS_RW(gadget_strings, product); GS_STRINGS_RW(gadget_strings, serialnumber); static struct configfs_attribute *gadget_strings_langid_attrs[] = { - &gadget_strings_manufacturer.attr, - &gadget_strings_product.attr, - &gadget_strings_serialnumber.attr, + &gadget_strings_attr_manufacturer, + &gadget_strings_attr_product, + &gadget_strings_attr_serialnumber, NULL, }; @@ -751,27 +730,25 @@ static inline struct os_desc *to_os_desc(struct config_item *item) return container_of(to_config_group(item), struct os_desc, group); } -CONFIGFS_ATTR_STRUCT(os_desc); -CONFIGFS_ATTR_OPS(os_desc); - -static ssize_t os_desc_use_show(struct os_desc *os_desc, char *page) +static inline struct gadget_info *os_desc_item_to_gadget_info( + struct config_item *item) { - struct gadget_info *gi; - - gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + return to_gadget_info(to_os_desc(item)->group.cg_item.ci_parent); +} - return sprintf(page, "%d", gi->use_os_desc); +static ssize_t os_desc_use_show(struct config_item *item, char *page) +{ + return sprintf(page, "%d", + os_desc_item_to_gadget_info(item)->use_os_desc); } -static ssize_t os_desc_use_store(struct os_desc *os_desc, const char *page, +static ssize_t os_desc_use_store(struct config_item *item, const char *page, size_t len) { - struct gadget_info *gi; + struct gadget_info *gi = os_desc_item_to_gadget_info(item); int ret; bool use; - gi = to_gadget_info(os_desc->group.cg_item.ci_parent); - mutex_lock(&gi->lock); ret = strtobool(page, &use); if (!ret) { @@ -783,29 +760,19 @@ static ssize_t os_desc_use_store(struct os_desc *os_desc, const char *page, return ret; } -static struct os_desc_attribute os_desc_use = - __CONFIGFS_ATTR(use, S_IRUGO | S_IWUSR, - os_desc_use_show, - os_desc_use_store); - -static ssize_t os_desc_b_vendor_code_show(struct os_desc *os_desc, char *page) +static ssize_t os_desc_b_vendor_code_show(struct config_item *item, char *page) { - struct gadget_info *gi; - - gi = to_gadget_info(os_desc->group.cg_item.ci_parent); - - return sprintf(page, "%d", gi->b_vendor_code); + return sprintf(page, "%d", + os_desc_item_to_gadget_info(item)->b_vendor_code); } -static ssize_t os_desc_b_vendor_code_store(struct os_desc *os_desc, +static ssize_t os_desc_b_vendor_code_store(struct config_item *item, const char *page, size_t len) { - struct gadget_info *gi; + struct gadget_info *gi = os_desc_item_to_gadget_info(item); int ret; u8 b_vendor_code; - gi = to_gadget_info(os_desc->group.cg_item.ci_parent); - mutex_lock(&gi->lock); ret = kstrtou8(page, 0, &b_vendor_code); if (!ret) { @@ -817,29 +784,20 @@ static ssize_t os_desc_b_vendor_code_store(struct os_desc *os_desc, return ret; } -static struct os_desc_attribute os_desc_b_vendor_code = - __CONFIGFS_ATTR(b_vendor_code, S_IRUGO | S_IWUSR, - os_desc_b_vendor_code_show, - os_desc_b_vendor_code_store); - -static ssize_t os_desc_qw_sign_show(struct os_desc *os_desc, char *page) +static ssize_t os_desc_qw_sign_show(struct config_item *item, char *page) { - struct gadget_info *gi; - - gi = to_gadget_info(os_desc->group.cg_item.ci_parent); + struct gadget_info *gi = os_desc_item_to_gadget_info(item); memcpy(page, gi->qw_sign, OS_STRING_QW_SIGN_LEN); - return OS_STRING_QW_SIGN_LEN; } -static ssize_t os_desc_qw_sign_store(struct os_desc *os_desc, const char *page, +static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page, size_t len) { - struct gadget_info *gi; + struct gadget_info *gi = os_desc_item_to_gadget_info(item); int res, l; - gi = to_gadget_info(os_desc->group.cg_item.ci_parent); l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1); if (page[l - 1] == '\n') --l; @@ -855,15 +813,14 @@ static ssize_t os_desc_qw_sign_store(struct os_desc *os_desc, const char *page, return res; } -static struct os_desc_attribute os_desc_qw_sign = - __CONFIGFS_ATTR(qw_sign, S_IRUGO | S_IWUSR, - os_desc_qw_sign_show, - os_desc_qw_sign_store); +CONFIGFS_ATTR(os_desc_, use); +CONFIGFS_ATTR(os_desc_, b_vendor_code); +CONFIGFS_ATTR(os_desc_, qw_sign); static struct configfs_attribute *os_desc_attrs[] = { - &os_desc_use.attr, - &os_desc_b_vendor_code.attr, - &os_desc_qw_sign.attr, + &os_desc_attr_use, + &os_desc_attr_b_vendor_code, + &os_desc_attr_qw_sign, NULL, }; @@ -926,8 +883,6 @@ static int os_desc_unlink(struct config_item *os_desc_ci, static struct configfs_item_operations os_desc_ops = { .release = os_desc_attr_release, - .show_attribute = os_desc_attr_show, - .store_attribute = os_desc_attr_store, .allow_link = os_desc_link, .drop_link = os_desc_unlink, }; @@ -938,28 +893,21 @@ static struct config_item_type os_desc_type = { .ct_owner = THIS_MODULE, }; -CONFIGFS_ATTR_STRUCT(usb_os_desc); -CONFIGFS_ATTR_OPS(usb_os_desc); - - static inline struct usb_os_desc_ext_prop *to_usb_os_desc_ext_prop(struct config_item *item) { return container_of(item, struct usb_os_desc_ext_prop, item); } -CONFIGFS_ATTR_STRUCT(usb_os_desc_ext_prop); -CONFIGFS_ATTR_OPS(usb_os_desc_ext_prop); - -static ssize_t ext_prop_type_show(struct usb_os_desc_ext_prop *ext_prop, - char *page) +static ssize_t ext_prop_type_show(struct config_item *item, char *page) { - return sprintf(page, "%d", ext_prop->type); + return sprintf(page, "%d", to_usb_os_desc_ext_prop(item)->type); } -static ssize_t ext_prop_type_store(struct usb_os_desc_ext_prop *ext_prop, +static ssize_t ext_prop_type_store(struct config_item *item, const char *page, size_t len) { + struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent); u8 type; int ret; @@ -997,9 +945,9 @@ end: return ret; } -static ssize_t ext_prop_data_show(struct usb_os_desc_ext_prop *ext_prop, - char *page) +static ssize_t ext_prop_data_show(struct config_item *item, char *page) { + struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); int len = ext_prop->data_len; if (ext_prop->type == USB_EXT_PROP_UNICODE || @@ -1011,9 +959,10 @@ static ssize_t ext_prop_data_show(struct usb_os_desc_ext_prop *ext_prop, return len; } -static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop, +static ssize_t ext_prop_data_store(struct config_item *item, const char *page, size_t len) { + struct usb_os_desc_ext_prop *ext_prop = to_usb_os_desc_ext_prop(item); struct usb_os_desc *desc = to_usb_os_desc(ext_prop->item.ci_parent); char *new_data; size_t ret_len = len; @@ -1044,17 +993,12 @@ static ssize_t ext_prop_data_store(struct usb_os_desc_ext_prop *ext_prop, return ret_len; } -static struct usb_os_desc_ext_prop_attribute ext_prop_type = - __CONFIGFS_ATTR(type, S_IRUGO | S_IWUSR, - ext_prop_type_show, ext_prop_type_store); - -static struct usb_os_desc_ext_prop_attribute ext_prop_data = - __CONFIGFS_ATTR(data, S_IRUGO | S_IWUSR, - ext_prop_data_show, ext_prop_data_store); +CONFIGFS_ATTR(ext_prop_, type); +CONFIGFS_ATTR(ext_prop_, data); static struct configfs_attribute *ext_prop_attrs[] = { - &ext_prop_type.attr, - &ext_prop_data.attr, + &ext_prop_attr_type, + &ext_prop_attr_data, NULL, }; @@ -1067,8 +1011,6 @@ static void usb_os_desc_ext_prop_release(struct config_item *item) static struct configfs_item_operations ext_prop_ops = { .release = usb_os_desc_ext_prop_release, - .show_attribute = usb_os_desc_ext_prop_attr_show, - .store_attribute = usb_os_desc_ext_prop_attr_store, }; static struct config_item *ext_prop_make( @@ -1137,21 +1079,17 @@ static struct configfs_group_operations interf_grp_ops = { .drop_item = &ext_prop_drop, }; -static struct configfs_item_operations interf_item_ops = { - .show_attribute = usb_os_desc_attr_show, - .store_attribute = usb_os_desc_attr_store, -}; - -static ssize_t interf_grp_compatible_id_show(struct usb_os_desc *desc, +static ssize_t interf_grp_compatible_id_show(struct config_item *item, char *page) { - memcpy(page, desc->ext_compat_id, 8); + memcpy(page, to_usb_os_desc(item)->ext_compat_id, 8); return 8; } -static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc, +static ssize_t interf_grp_compatible_id_store(struct config_item *item, const char *page, size_t len) { + struct usb_os_desc *desc = to_usb_os_desc(item); int l; l = min_t(int, 8, len); @@ -1167,21 +1105,17 @@ static ssize_t interf_grp_compatible_id_store(struct usb_os_desc *desc, return len; } -static struct usb_os_desc_attribute interf_grp_attr_compatible_id = - __CONFIGFS_ATTR(compatible_id, S_IRUGO | S_IWUSR, - interf_grp_compatible_id_show, - interf_grp_compatible_id_store); - -static ssize_t interf_grp_sub_compatible_id_show(struct usb_os_desc *desc, +static ssize_t interf_grp_sub_compatible_id_show(struct config_item *item, char *page) { - memcpy(page, desc->ext_compat_id + 8, 8); + memcpy(page, to_usb_os_desc(item)->ext_compat_id + 8, 8); return 8; } -static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc, +static ssize_t interf_grp_sub_compatible_id_store(struct config_item *item, const char *page, size_t len) { + struct usb_os_desc *desc = to_usb_os_desc(item); int l; l = min_t(int, 8, len); @@ -1197,14 +1131,12 @@ static ssize_t interf_grp_sub_compatible_id_store(struct usb_os_desc *desc, return len; } -static struct usb_os_desc_attribute interf_grp_attr_sub_compatible_id = - __CONFIGFS_ATTR(sub_compatible_id, S_IRUGO | S_IWUSR, - interf_grp_sub_compatible_id_show, - interf_grp_sub_compatible_id_store); +CONFIGFS_ATTR(interf_grp_, compatible_id); +CONFIGFS_ATTR(interf_grp_, sub_compatible_id); static struct configfs_attribute *interf_grp_attrs[] = { - &interf_grp_attr_compatible_id.attr, - &interf_grp_attr_sub_compatible_id.attr, + &interf_grp_attr_compatible_id, + &interf_grp_attr_sub_compatible_id, NULL }; @@ -1242,7 +1174,6 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent, f_default_groups[0] = os_desc_group; os_desc_group->default_groups = interface_groups; - interface_type->ct_item_ops = &interf_item_ops; interface_type->ct_group_ops = &interf_grp_ops; interface_type->ct_attrs = interf_grp_attrs; interface_type->ct_owner = owner; diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 6399c106a..30fdab0ae 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -53,13 +53,13 @@ * the restrictions that may apply. Some combinations of driver * and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value * is initialized as if the endpoint were used at full speed and * the bmAttribute field in the ep companion descriptor is * updated with the assigned number of streams if it is * different from the original value. To prevent the endpoint - * from being returned by a later autoconfig call, claim it by + * from being returned by a later autoconfig call, claims it by * assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. @@ -154,10 +154,10 @@ EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss); * USB controller, and it can't know all the restrictions that may apply. * Some combinations of driver and hardware won't be able to autoconfigure. * - * On success, this returns an un-claimed usb_ep, and modifies the endpoint + * On success, this returns an claimed usb_ep, and modifies the endpoint * descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value * is initialized as if the endpoint were used at full speed. To prevent - * the endpoint from being returned by a later autoconfig call, claim it + * the endpoint from being returned by a later autoconfig call, claims it * by assigning ep->claimed to true. * * On failure, this returns a null endpoint descriptor. @@ -172,6 +172,23 @@ struct usb_ep *usb_ep_autoconfig( EXPORT_SYMBOL_GPL(usb_ep_autoconfig); /** + * usb_ep_autoconfig_release - releases endpoint and set it to initial state + * @ep: endpoint which should be released + * + * This function can be used during function bind for endpoints obtained + * from usb_ep_autoconfig(). It unclaims endpoint claimed by + * usb_ep_autoconfig() to make it available for other functions. Endpoint + * which was released is no longer invalid and shouldn't be used in + * context of function which released it. + */ +void usb_ep_autoconfig_release(struct usb_ep *ep) +{ + ep->claimed = false; + ep->driver_data = NULL; +} +EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release); + +/** * usb_ep_autoconfig_reset - reset endpoint autoconfig state * @gadget: device for which autoconfig state will be reset * diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index be9df09fd..2fa1e80a3 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -428,21 +428,18 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ if (intf == acm->ctrl_id) { - if (acm->notify->driver_data) { - dev_vdbg(&cdev->gadget->dev, - "reset acm control interface %d\n", intf); - usb_ep_disable(acm->notify); - } + dev_vdbg(&cdev->gadget->dev, + "reset acm control interface %d\n", intf); + usb_ep_disable(acm->notify); if (!acm->notify->desc) if (config_ep_by_speed(cdev->gadget, f, acm->notify)) return -EINVAL; usb_ep_enable(acm->notify); - acm->notify->driver_data = acm; } else if (intf == acm->data_id) { - if (acm->port.in->driver_data) { + if (acm->notify->enabled) { dev_dbg(&cdev->gadget->dev, "reset acm ttyGS%d\n", acm->port_num); gserial_disconnect(&acm->port); @@ -475,7 +472,6 @@ static void acm_disable(struct usb_function *f) dev_dbg(&cdev->gadget->dev, "acm ttyGS%d deactivated\n", acm->port_num); gserial_disconnect(&acm->port); usb_ep_disable(acm->notify); - acm->notify->driver_data = NULL; } /*-------------------------------------------------------------------------*/ @@ -655,19 +651,16 @@ acm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; acm->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_out_desc); if (!ep) goto fail; acm->port.out = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &acm_fs_notify_desc); if (!ep) goto fail; acm->notify = ep; - ep->driver_data = cdev; /* claim */ /* allocate notification */ acm->notify_req = gs_alloc_req(ep, @@ -709,14 +702,6 @@ fail: if (acm->notify_req) gs_free_req(acm->notify, acm->notify_req); - /* we might as well release our claims on endpoints */ - if (acm->notify) - acm->notify->driver_data = NULL; - if (acm->port.out) - acm->port.out->driver_data = NULL; - if (acm->port.in) - acm->port.in->driver_data = NULL; - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); return status; @@ -776,21 +761,6 @@ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_serial_opts); -static ssize_t f_acm_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct f_serial_opts *opts = to_f_serial_opts(item); - struct f_serial_opts_attribute *f_serial_opts_attr = - container_of(attr, struct f_serial_opts_attribute, attr); - ssize_t ret = 0; - - if (f_serial_opts_attr->show) - ret = f_serial_opts_attr->show(opts, page); - return ret; -} - static void acm_attr_release(struct config_item *item) { struct f_serial_opts *opts = to_f_serial_opts(item); @@ -800,20 +770,17 @@ static void acm_attr_release(struct config_item *item) static struct configfs_item_operations acm_item_ops = { .release = acm_attr_release, - .show_attribute = f_acm_attr_show, }; -static ssize_t f_acm_port_num_show(struct f_serial_opts *opts, char *page) +static ssize_t f_acm_port_num_show(struct config_item *item, char *page) { - return sprintf(page, "%u\n", opts->port_num); + return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num); } -static struct f_serial_opts_attribute f_acm_port_num = - __CONFIGFS_ATTR_RO(port_num, f_acm_port_num_show); - +CONFIGFS_ATTR_RO(f_acm_port_, num); static struct configfs_attribute *acm_attrs[] = { - &f_acm_port_num.attr, + &f_acm_port_attr_num, NULL, }; diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 7b7424f10..7ad60ee41 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -541,24 +541,21 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt != 0) goto fail; - if (ecm->notify->driver_data) { - VDBG(cdev, "reset ecm control %d\n", intf); - usb_ep_disable(ecm->notify); - } + VDBG(cdev, "reset ecm control %d\n", intf); + usb_ep_disable(ecm->notify); if (!(ecm->notify->desc)) { VDBG(cdev, "init ecm ctrl %d\n", intf); if (config_ep_by_speed(cdev->gadget, f, ecm->notify)) goto fail; } usb_ep_enable(ecm->notify); - ecm->notify->driver_data = ecm; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ecm->data_id) { if (alt > 1) goto fail; - if (ecm->port.in_ep->driver_data) { + if (ecm->port.in_ep->enabled) { DBG(cdev, "reset ecm\n"); gether_disconnect(&ecm->port); } @@ -618,7 +615,7 @@ static int ecm_get_alt(struct usb_function *f, unsigned intf) if (intf == ecm->ctrl_id) return 0; - return ecm->port.in_ep->driver_data ? 1 : 0; + return ecm->port.in_ep->enabled ? 1 : 0; } static void ecm_disable(struct usb_function *f) @@ -628,14 +625,11 @@ static void ecm_disable(struct usb_function *f) DBG(cdev, "ecm deactivated\n"); - if (ecm->port.in_ep->driver_data) + if (ecm->port.in_ep->enabled) gether_disconnect(&ecm->port); - if (ecm->notify->driver_data) { - usb_ep_disable(ecm->notify); - ecm->notify->driver_data = NULL; - ecm->notify->desc = NULL; - } + usb_ep_disable(ecm->notify); + ecm->notify->desc = NULL; } /*-------------------------------------------------------------------------*/ @@ -750,13 +744,11 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ecm->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc); if (!ep) goto fail; ecm->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is *OPTIONAL* but we * don't treat it that way. It's simpler, and some newer CDC @@ -766,7 +758,6 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ecm->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -820,14 +811,6 @@ fail: usb_ep_free_request(ecm->notify, ecm->notify_req); } - /* we might as well release our claims on endpoints */ - if (ecm->notify) - ecm->notify->driver_data = NULL; - if (ecm->port.out_ep) - ecm->port.out_ep->driver_data = NULL; - if (ecm->port.in_ep) - ecm->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -855,10 +838,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ecm); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ecm); static struct configfs_attribute *ecm_attrs[] = { - &f_ecm_opts_dev_addr.attr, - &f_ecm_opts_host_addr.attr, - &f_ecm_opts_qmult.attr, - &f_ecm_opts_ifname.attr, + &ecm_opts_attr_dev_addr, + &ecm_opts_attr_host_addr, + &ecm_opts_attr_qmult, + &ecm_opts_attr_ifname, NULL, }; diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index c9e90de5b..cad35a502 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -195,11 +195,8 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; if (intf == eem->ctrl_id) { - - if (eem->port.in_ep->driver_data) { - DBG(cdev, "reset eem\n"); - gether_disconnect(&eem->port); - } + DBG(cdev, "reset eem\n"); + gether_disconnect(&eem->port); if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) { DBG(cdev, "init eem\n"); @@ -237,7 +234,7 @@ static void eem_disable(struct usb_function *f) DBG(cdev, "eem deactivated\n"); - if (eem->port.in_ep->driver_data) + if (eem->port.in_ep->enabled) gether_disconnect(&eem->port); } @@ -293,13 +290,11 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; eem->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &eem_fs_out_desc); if (!ep) goto fail; eem->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -325,11 +320,6 @@ static int eem_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - if (eem->port.out_ep) - eem->port.out_ep->driver_data = NULL; - if (eem->port.in_ep) - eem->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -555,10 +545,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(eem); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(eem); static struct configfs_attribute *eem_attrs[] = { - &f_eem_opts_dev_addr.attr, - &f_eem_opts_host_addr.attr, - &f_eem_opts_qmult.attr, - &f_eem_opts_ifname.attr, + &eem_opts_attr_dev_addr, + &eem_opts_attr_host_addr, + &eem_opts_attr_qmult, + &eem_opts_attr_ifname, NULL, }; diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index adc6d52ef..cf43e9e18 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -423,7 +423,7 @@ static ssize_t __ffs_ep0_read_events(struct ffs_data *ffs, char __user *buf, spin_unlock_irq(&ffs->ev.waitq.lock); mutex_unlock(&ffs->mutex); - return unlikely(__copy_to_user(buf, events, size)) ? -EFAULT : size; + return unlikely(copy_to_user(buf, events, size)) ? -EFAULT : size; } static ssize_t ffs_ep0_read(struct file *file, char __user *buf, @@ -513,7 +513,7 @@ static ssize_t ffs_ep0_read(struct file *file, char __user *buf, /* unlocks spinlock */ ret = __ffs_ep0_queue_wait(ffs, data, len); - if (likely(ret > 0) && unlikely(__copy_to_user(buf, data, len))) + if (likely(ret > 0) && unlikely(copy_to_user(buf, data, len))) ret = -EFAULT; goto done_mutex; @@ -3493,7 +3493,7 @@ static char *ffs_prepare_buffer(const char __user *buf, size_t len) if (unlikely(!data)) return ERR_PTR(-ENOMEM); - if (unlikely(__copy_from_user(data, buf, len))) { + if (unlikely(copy_from_user(data, buf, len))) { kfree(data); return ERR_PTR(-EFAULT); } diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6df9715a4..99285b416 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -492,10 +492,7 @@ static void hidg_disable(struct usb_function *f) struct f_hidg_req_list *list, *next; usb_ep_disable(hidg->in_ep); - hidg->in_ep->driver_data = NULL; - usb_ep_disable(hidg->out_ep); - hidg->out_ep->driver_data = NULL; list_for_each_entry_safe(list, next, &hidg->completed_out_req, list) { list_del(&list->list); @@ -513,8 +510,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->in_ep != NULL) { /* restart endpoint */ - if (hidg->in_ep->driver_data != NULL) - usb_ep_disable(hidg->in_ep); + usb_ep_disable(hidg->in_ep); status = config_ep_by_speed(f->config->cdev->gadget, f, hidg->in_ep); @@ -533,8 +529,7 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (hidg->out_ep != NULL) { /* restart endpoint */ - if (hidg->out_ep->driver_data != NULL) - usb_ep_disable(hidg->out_ep); + usb_ep_disable(hidg->out_ep); status = config_ep_by_speed(f->config->cdev->gadget, f, hidg->out_ep); @@ -566,7 +561,6 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) hidg->out_ep->name, status); } else { usb_ep_disable(hidg->out_ep); - hidg->out_ep->driver_data = NULL; status = -ENOMEM; goto fail; } @@ -614,13 +608,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_in_ep_desc); if (!ep) goto fail; - ep->driver_data = c->cdev; /* claim */ hidg->in_ep = ep; ep = usb_ep_autoconfig(c->cdev->gadget, &hidg_fs_out_ep_desc); if (!ep) goto fail; - ep->driver_data = c->cdev; /* claim */ hidg->out_ep = ep; /* preallocate request and buffer */ @@ -713,9 +705,6 @@ static inline struct f_hid_opts *to_f_hid_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_hid_opts); -CONFIGFS_ATTR_OPS(f_hid_opts); - static void hid_attr_release(struct config_item *item) { struct f_hid_opts *opts = to_f_hid_opts(item); @@ -725,13 +714,12 @@ static void hid_attr_release(struct config_item *item) static struct configfs_item_operations hidg_item_ops = { .release = hid_attr_release, - .show_attribute = f_hid_opts_attr_show, - .store_attribute = f_hid_opts_attr_store, }; #define F_HID_OPT(name, prec, limit) \ -static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\ +static ssize_t f_hid_opts_##name##_show(struct config_item *item, char *page)\ { \ + struct f_hid_opts *opts = to_f_hid_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -741,9 +729,10 @@ static ssize_t f_hid_opts_##name##_show(struct f_hid_opts *opts, char *page)\ return result; \ } \ \ -static ssize_t f_hid_opts_##name##_store(struct f_hid_opts *opts, \ +static ssize_t f_hid_opts_##name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct f_hid_opts *opts = to_f_hid_opts(item); \ int ret; \ u##prec num; \ \ @@ -769,16 +758,15 @@ end: \ return ret; \ } \ \ -static struct f_hid_opts_attribute f_hid_opts_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_hid_opts_##name##_show,\ - f_hid_opts_##name##_store) +CONFIGFS_ATTR(f_hid_opts_, name) F_HID_OPT(subclass, 8, 255); F_HID_OPT(protocol, 8, 255); F_HID_OPT(report_length, 16, 65535); -static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) +static ssize_t f_hid_opts_report_desc_show(struct config_item *item, char *page) { + struct f_hid_opts *opts = to_f_hid_opts(item); int result; mutex_lock(&opts->lock); @@ -789,9 +777,10 @@ static ssize_t f_hid_opts_report_desc_show(struct f_hid_opts *opts, char *page) return result; } -static ssize_t f_hid_opts_report_desc_store(struct f_hid_opts *opts, +static ssize_t f_hid_opts_report_desc_store(struct config_item *item, const char *page, size_t len) { + struct f_hid_opts *opts = to_f_hid_opts(item); int ret = -EBUSY; char *d; @@ -818,16 +807,13 @@ end: return ret; } -static struct f_hid_opts_attribute f_hid_opts_report_desc = - __CONFIGFS_ATTR(report_desc, S_IRUGO | S_IWUSR, - f_hid_opts_report_desc_show, - f_hid_opts_report_desc_store); +CONFIGFS_ATTR(f_hid_opts_, report_desc); static struct configfs_attribute *hid_attrs[] = { - &f_hid_opts_subclass.attr, - &f_hid_opts_protocol.attr, - &f_hid_opts_report_length.attr, - &f_hid_opts_report_desc.attr, + &f_hid_opts_attr_subclass, + &f_hid_opts_attr_protocol, + &f_hid_opts_attr_report_length, + &f_hid_opts_attr_report_desc, NULL, }; diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 6e2fe63b9..ddc3aad88 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -34,6 +34,9 @@ struct f_loopback { struct usb_ep *in_ep; struct usb_ep *out_ep; + + unsigned qlen; + unsigned buflen; }; static inline struct f_loopback *func_to_loop(struct usb_function *f) @@ -41,13 +44,10 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f) return container_of(f, struct f_loopback, function); } -static unsigned qlen; -static unsigned buflen; - /*-------------------------------------------------------------------------*/ static struct usb_interface_descriptor loopback_intf = { - .bLength = sizeof loopback_intf, + .bLength = sizeof(loopback_intf), .bDescriptorType = USB_DT_INTERFACE, .bNumEndpoints = 2, @@ -195,12 +195,10 @@ autoconf_fail: f->name, cdev->gadget->name); return -ENODEV; } - loop->in_ep->driver_data = cdev; /* claim */ loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc); if (!loop->out_ep) goto autoconf_fail; - loop->out_ep->driver_data = cdev; /* claim */ /* support high speed hardware */ hs_loop_source_desc.bEndpointAddress = @@ -245,22 +243,38 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) int status = req->status; switch (status) { - case 0: /* normal completion? */ if (ep == loop->out_ep) { - req->zero = (req->actual < req->length); - req->length = req->actual; + /* + * We received some data from the host so let's + * queue it so host can read the from our in ep + */ + struct usb_request *in_req = req->context; + + in_req->zero = (req->actual < req->length); + in_req->length = req->actual; + ep = loop->in_ep; + req = in_req; + } else { + /* + * We have just looped back a bunch of data + * to host. Now let's wait for some more data. + */ + req = req->context; + ep = loop->out_ep; } - /* queue the buffer for some later OUT packet */ - req->length = buflen; + /* queue the buffer back to host or for next bunch of data */ status = usb_ep_queue(ep, req, GFP_ATOMIC); - if (status == 0) + if (status == 0) { return; + } else { + ERROR(cdev, "Unable to loop back buffer to %s: %d\n", + ep->name, status); + goto free_req; + } /* "should never get here" */ - /* FALLTHROUGH */ - default: ERROR(cdev, "%s loop complete --> %d, %d/%d\n", ep->name, status, req->actual, req->length); @@ -274,6 +288,10 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ +free_req: + usb_ep_free_request(ep == loop->in_ep ? + loop->out_ep : loop->in_ep, + req->context); free_ep_req(ep, req); return; } @@ -290,53 +308,77 @@ static void disable_loopback(struct f_loopback *loop) static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) { - return alloc_ep_req(ep, len, buflen); + struct f_loopback *loop = ep->driver_data; + + return alloc_ep_req(ep, len, loop->buflen); } -static int enable_endpoint(struct usb_composite_dev *cdev, struct f_loopback *loop, - struct usb_ep *ep) +static int alloc_requests(struct usb_composite_dev *cdev, + struct f_loopback *loop) { - struct usb_request *req; - unsigned i; - int result; - - /* - * one endpoint writes data back IN to the host while another endpoint - * just reads OUT packets - */ - result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); - if (result) - goto fail0; - result = usb_ep_enable(ep); - if (result < 0) - goto fail0; - ep->driver_data = loop; + struct usb_request *in_req, *out_req; + int i; + int result = 0; /* * allocate a bunch of read buffers and queue them all at once. - * we buffer at most 'qlen' transfers; fewer if any need more - * than 'buflen' bytes each. + * we buffer at most 'qlen' transfers; We allocate buffers only + * for out transfer and reuse them in IN transfers to implement + * our loopback functionality */ - for (i = 0; i < qlen && result == 0; i++) { - req = lb_alloc_ep_req(ep, 0); - if (!req) - goto fail1; + for (i = 0; i < loop->qlen && result == 0; i++) { + result = -ENOMEM; + + in_req = usb_ep_alloc_request(loop->in_ep, GFP_ATOMIC); + if (!in_req) + goto fail; + + out_req = lb_alloc_ep_req(loop->out_ep, 0); + if (!out_req) + goto fail_in; + + in_req->complete = loopback_complete; + out_req->complete = loopback_complete; - req->complete = loopback_complete; - result = usb_ep_queue(ep, req, GFP_ATOMIC); + in_req->buf = out_req->buf; + /* length will be set in complete routine */ + in_req->context = out_req; + out_req->context = in_req; + + result = usb_ep_queue(loop->out_ep, out_req, GFP_ATOMIC); if (result) { ERROR(cdev, "%s queue req --> %d\n", - ep->name, result); - goto fail1; + loop->out_ep->name, result); + goto fail_out; } } return 0; -fail1: - usb_ep_disable(ep); +fail_out: + free_ep_req(loop->out_ep, out_req); +fail_in: + usb_ep_free_request(loop->in_ep, in_req); +fail: + return result; +} + +static int enable_endpoint(struct usb_composite_dev *cdev, + struct f_loopback *loop, struct usb_ep *ep) +{ + int result; + + result = config_ep_by_speed(cdev->gadget, &(loop->function), ep); + if (result) + goto out; -fail0: + result = usb_ep_enable(ep); + if (result < 0) + goto out; + ep->driver_data = loop; + result = 0; + +out: return result; } @@ -347,13 +389,24 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop) result = enable_endpoint(cdev, loop, loop->in_ep); if (result) - return result; + goto out; result = enable_endpoint(cdev, loop, loop->out_ep); if (result) - return result; + goto disable_in; + + result = alloc_requests(cdev, loop); + if (result) + goto disable_out; DBG(cdev, "%s enabled\n", loop->function.name); + return 0; + +disable_out: + usb_ep_disable(loop->out_ep); +disable_in: + usb_ep_disable(loop->in_ep); +out: return result; } @@ -364,8 +417,7 @@ static int loopback_set_alt(struct usb_function *f, struct usb_composite_dev *cdev = f->config->cdev; /* we know alt is zero */ - if (loop->in_ep->driver_data) - disable_loopback(loop); + disable_loopback(loop); return enable_loopback(cdev, loop); } @@ -391,10 +443,10 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi) lb_opts->refcnt++; mutex_unlock(&lb_opts->lock); - buflen = lb_opts->bulk_buflen; - qlen = lb_opts->qlen; - if (!qlen) - qlen = 32; + loop->buflen = lb_opts->bulk_buflen; + loop->qlen = lb_opts->qlen; + if (!loop->qlen) + loop->qlen = 32; loop->function.name = "loopback"; loop->function.bind = loopback_bind; @@ -413,9 +465,6 @@ static inline struct f_lb_opts *to_f_lb_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_lb_opts); -CONFIGFS_ATTR_OPS(f_lb_opts); - static void lb_attr_release(struct config_item *item) { struct f_lb_opts *lb_opts = to_f_lb_opts(item); @@ -425,24 +474,24 @@ static void lb_attr_release(struct config_item *item) static struct configfs_item_operations lb_item_ops = { .release = lb_attr_release, - .show_attribute = f_lb_opts_attr_show, - .store_attribute = f_lb_opts_attr_store, }; -static ssize_t f_lb_opts_qlen_show(struct f_lb_opts *opts, char *page) +static ssize_t f_lb_opts_qlen_show(struct config_item *item, char *page) { + struct f_lb_opts *opts = to_f_lb_opts(item); int result; mutex_lock(&opts->lock); - result = sprintf(page, "%d", opts->qlen); + result = sprintf(page, "%d\n", opts->qlen); mutex_unlock(&opts->lock); return result; } -static ssize_t f_lb_opts_qlen_store(struct f_lb_opts *opts, +static ssize_t f_lb_opts_qlen_store(struct config_item *item, const char *page, size_t len) { + struct f_lb_opts *opts = to_f_lb_opts(item); int ret; u32 num; @@ -463,25 +512,24 @@ end: return ret; } -static struct f_lb_opts_attribute f_lb_opts_qlen = - __CONFIGFS_ATTR(qlen, S_IRUGO | S_IWUSR, - f_lb_opts_qlen_show, - f_lb_opts_qlen_store); +CONFIGFS_ATTR(f_lb_opts_, qlen); -static ssize_t f_lb_opts_bulk_buflen_show(struct f_lb_opts *opts, char *page) +static ssize_t f_lb_opts_bulk_buflen_show(struct config_item *item, char *page) { + struct f_lb_opts *opts = to_f_lb_opts(item); int result; mutex_lock(&opts->lock); - result = sprintf(page, "%d", opts->bulk_buflen); + result = sprintf(page, "%d\n", opts->bulk_buflen); mutex_unlock(&opts->lock); return result; } -static ssize_t f_lb_opts_bulk_buflen_store(struct f_lb_opts *opts, +static ssize_t f_lb_opts_bulk_buflen_store(struct config_item *item, const char *page, size_t len) { + struct f_lb_opts *opts = to_f_lb_opts(item); int ret; u32 num; @@ -502,14 +550,11 @@ end: return ret; } -static struct f_lb_opts_attribute f_lb_opts_bulk_buflen = - __CONFIGFS_ATTR(buflen, S_IRUGO | S_IWUSR, - f_lb_opts_bulk_buflen_show, - f_lb_opts_bulk_buflen_store); +CONFIGFS_ATTR(f_lb_opts_, bulk_buflen); static struct configfs_attribute *lb_attrs[] = { - &f_lb_opts_qlen.attr, - &f_lb_opts_bulk_buflen.attr, + &f_lb_opts_attr_qlen, + &f_lb_opts_attr_bulk_buflen, NULL, }; diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index a6eb537d7..223ccf89d 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -2258,12 +2258,10 @@ reset: /* Disable the endpoints */ if (fsg->bulk_in_enabled) { usb_ep_disable(fsg->bulk_in); - fsg->bulk_in->driver_data = NULL; fsg->bulk_in_enabled = 0; } if (fsg->bulk_out_enabled) { usb_ep_disable(fsg->bulk_out); - fsg->bulk_out->driver_data = NULL; fsg->bulk_out_enabled = 0; } @@ -2347,7 +2345,6 @@ static void fsg_disable(struct usb_function *f) static void handle_exception(struct fsg_common *common) { - siginfo_t info; int i; struct fsg_buffhd *bh; enum fsg_state old_state; @@ -2359,8 +2356,7 @@ static void handle_exception(struct fsg_common *common) * into a high-priority EXIT exception. */ for (;;) { - int sig = - dequeue_signal_lock(current, ¤t->blocked, &info); + int sig = kernel_dequeue_signal(NULL); if (!sig) break; if (sig != SIGUSR1) { @@ -2662,10 +2658,12 @@ EXPORT_SYMBOL_GPL(fsg_common_put); /* check if fsg_num_buffers is within a valid range */ static inline int fsg_num_buffers_validate(unsigned int fsg_num_buffers) { - if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4) +#define FSG_MAX_NUM_BUFFERS 32 + + if (fsg_num_buffers >= 2 && fsg_num_buffers <= FSG_MAX_NUM_BUFFERS) return 0; pr_err("fsg_num_buffers %u is out of range (%d to %d)\n", - fsg_num_buffers, 2, 4); + fsg_num_buffers, 2, FSG_MAX_NUM_BUFFERS); return -EINVAL; } @@ -3070,13 +3068,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_in_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_in = ep; ep = usb_ep_autoconfig(gadget, &fsg_fs_bulk_out_desc); if (!ep) goto autoconf_fail; - ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; /* Assume endpoint addresses are the same for both speeds */ @@ -3144,9 +3140,6 @@ static inline struct fsg_opts *to_fsg_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(fsg_lun_opts); -CONFIGFS_ATTR_OPS(fsg_lun_opts); - static void fsg_lun_attr_release(struct config_item *item) { struct fsg_lun_opts *lun_opts; @@ -3157,110 +3150,93 @@ static void fsg_lun_attr_release(struct config_item *item) static struct configfs_item_operations fsg_lun_item_ops = { .release = fsg_lun_attr_release, - .show_attribute = fsg_lun_opts_attr_show, - .store_attribute = fsg_lun_opts_attr_store, }; -static ssize_t fsg_lun_opts_file_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_file_show(struct config_item *item, char *page) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_show_file(opts->lun, &fsg_opts->common->filesem, page); } -static ssize_t fsg_lun_opts_file_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_file_store(struct config_item *item, const char *page, size_t len) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_store_file(opts->lun, &fsg_opts->common->filesem, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_file = - __CONFIGFS_ATTR(file, S_IRUGO | S_IWUSR, fsg_lun_opts_file_show, - fsg_lun_opts_file_store); +CONFIGFS_ATTR(fsg_lun_opts_, file); -static ssize_t fsg_lun_opts_ro_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_ro_show(struct config_item *item, char *page) { - return fsg_show_ro(opts->lun, page); + return fsg_show_ro(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_ro_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_ro_store(struct config_item *item, const char *page, size_t len) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_store_ro(opts->lun, &fsg_opts->common->filesem, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_ro = - __CONFIGFS_ATTR(ro, S_IRUGO | S_IWUSR, fsg_lun_opts_ro_show, - fsg_lun_opts_ro_store); +CONFIGFS_ATTR(fsg_lun_opts_, ro); -static ssize_t fsg_lun_opts_removable_show(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_removable_show(struct config_item *item, char *page) { - return fsg_show_removable(opts->lun, page); + return fsg_show_removable(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_removable_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_removable_store(struct config_item *item, const char *page, size_t len) { - return fsg_store_removable(opts->lun, page, len); + return fsg_store_removable(to_fsg_lun_opts(item)->lun, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_removable = - __CONFIGFS_ATTR(removable, S_IRUGO | S_IWUSR, - fsg_lun_opts_removable_show, - fsg_lun_opts_removable_store); +CONFIGFS_ATTR(fsg_lun_opts_, removable); -static ssize_t fsg_lun_opts_cdrom_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_cdrom_show(struct config_item *item, char *page) { - return fsg_show_cdrom(opts->lun, page); + return fsg_show_cdrom(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_cdrom_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_cdrom_store(struct config_item *item, const char *page, size_t len) { - struct fsg_opts *fsg_opts; - - fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); + struct fsg_lun_opts *opts = to_fsg_lun_opts(item); + struct fsg_opts *fsg_opts = to_fsg_opts(opts->group.cg_item.ci_parent); return fsg_store_cdrom(opts->lun, &fsg_opts->common->filesem, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_cdrom = - __CONFIGFS_ATTR(cdrom, S_IRUGO | S_IWUSR, fsg_lun_opts_cdrom_show, - fsg_lun_opts_cdrom_store); +CONFIGFS_ATTR(fsg_lun_opts_, cdrom); -static ssize_t fsg_lun_opts_nofua_show(struct fsg_lun_opts *opts, char *page) +static ssize_t fsg_lun_opts_nofua_show(struct config_item *item, char *page) { - return fsg_show_nofua(opts->lun, page); + return fsg_show_nofua(to_fsg_lun_opts(item)->lun, page); } -static ssize_t fsg_lun_opts_nofua_store(struct fsg_lun_opts *opts, +static ssize_t fsg_lun_opts_nofua_store(struct config_item *item, const char *page, size_t len) { - return fsg_store_nofua(opts->lun, page, len); + return fsg_store_nofua(to_fsg_lun_opts(item)->lun, page, len); } -static struct fsg_lun_opts_attribute fsg_lun_opts_nofua = - __CONFIGFS_ATTR(nofua, S_IRUGO | S_IWUSR, fsg_lun_opts_nofua_show, - fsg_lun_opts_nofua_store); +CONFIGFS_ATTR(fsg_lun_opts_, nofua); static struct configfs_attribute *fsg_lun_attrs[] = { - &fsg_lun_opts_file.attr, - &fsg_lun_opts_ro.attr, - &fsg_lun_opts_removable.attr, - &fsg_lun_opts_cdrom.attr, - &fsg_lun_opts_nofua.attr, + &fsg_lun_opts_attr_file, + &fsg_lun_opts_attr_ro, + &fsg_lun_opts_attr_removable, + &fsg_lun_opts_attr_cdrom, + &fsg_lun_opts_attr_nofua, NULL, }; @@ -3352,9 +3328,6 @@ static void fsg_lun_drop(struct config_group *group, struct config_item *item) config_item_put(item); } -CONFIGFS_ATTR_STRUCT(fsg_opts); -CONFIGFS_ATTR_OPS(fsg_opts); - static void fsg_attr_release(struct config_item *item) { struct fsg_opts *opts = to_fsg_opts(item); @@ -3364,12 +3337,11 @@ static void fsg_attr_release(struct config_item *item) static struct configfs_item_operations fsg_item_ops = { .release = fsg_attr_release, - .show_attribute = fsg_opts_attr_show, - .store_attribute = fsg_opts_attr_store, }; -static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page) +static ssize_t fsg_opts_stall_show(struct config_item *item, char *page) { + struct fsg_opts *opts = to_fsg_opts(item); int result; mutex_lock(&opts->lock); @@ -3379,9 +3351,10 @@ static ssize_t fsg_opts_stall_show(struct fsg_opts *opts, char *page) return result; } -static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page, +static ssize_t fsg_opts_stall_store(struct config_item *item, const char *page, size_t len) { + struct fsg_opts *opts = to_fsg_opts(item); int ret; bool stall; @@ -3403,13 +3376,12 @@ static ssize_t fsg_opts_stall_store(struct fsg_opts *opts, const char *page, return ret; } -static struct fsg_opts_attribute fsg_opts_stall = - __CONFIGFS_ATTR(stall, S_IRUGO | S_IWUSR, fsg_opts_stall_show, - fsg_opts_stall_store); +CONFIGFS_ATTR(fsg_opts_, stall); #ifdef CONFIG_USB_GADGET_DEBUG_FILES -static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page) +static ssize_t fsg_opts_num_buffers_show(struct config_item *item, char *page) { + struct fsg_opts *opts = to_fsg_opts(item); int result; mutex_lock(&opts->lock); @@ -3419,9 +3391,10 @@ static ssize_t fsg_opts_num_buffers_show(struct fsg_opts *opts, char *page) return result; } -static ssize_t fsg_opts_num_buffers_store(struct fsg_opts *opts, +static ssize_t fsg_opts_num_buffers_store(struct config_item *item, const char *page, size_t len) { + struct fsg_opts *opts = to_fsg_opts(item); int ret; u8 num; @@ -3446,17 +3419,13 @@ end: return ret; } -static struct fsg_opts_attribute fsg_opts_num_buffers = - __CONFIGFS_ATTR(num_buffers, S_IRUGO | S_IWUSR, - fsg_opts_num_buffers_show, - fsg_opts_num_buffers_store); - +CONFIGFS_ATTR(fsg_opts_, num_buffers); #endif static struct configfs_attribute *fsg_attrs[] = { - &fsg_opts_stall.attr, + &fsg_opts_attr_stall, #ifdef CONFIG_USB_GADGET_DEBUG_FILES - &fsg_opts_num_buffers.attr, + &fsg_opts_attr_num_buffers, #endif NULL, }; diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index a287a4829..898a57031 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -302,8 +302,7 @@ static int f_midi_start_ep(struct f_midi *midi, int err; struct usb_composite_dev *cdev = f->config->cdev; - if (ep->driver_data) - usb_ep_disable(ep); + usb_ep_disable(ep); err = config_ep_by_speed(midi->gadget, f, ep); if (err) { @@ -341,8 +340,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) return err; - if (midi->out_ep->driver_data) - usb_ep_disable(midi->out_ep); + usb_ep_disable(midi->out_ep); err = config_ep_by_speed(midi->gadget, f, midi->out_ep); if (err) { @@ -372,6 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (err) { ERROR(midi, "%s queue req: %d\n", midi->out_ep->name, err); + free_ep_req(midi->out_ep, req); } } @@ -547,10 +546,16 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req) } } - if (req->length > 0) - usb_ep_queue(ep, req, GFP_ATOMIC); - else + if (req->length > 0 && ep->enabled) { + int err; + + err = usb_ep_queue(ep, req, GFP_ATOMIC); + if (err < 0) + ERROR(midi, "%s queue req: %d\n", + midi->in_ep->name, err); + } else { free_ep_req(ep, req); + } } static void f_midi_in_tasklet(unsigned long data) @@ -757,12 +762,10 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) midi->in_ep = usb_ep_autoconfig(cdev->gadget, &bulk_in_desc); if (!midi->in_ep) goto fail; - midi->in_ep->driver_data = cdev; /* claim */ midi->out_ep = usb_ep_autoconfig(cdev->gadget, &bulk_out_desc); if (!midi->out_ep) goto fail; - midi->out_ep->driver_data = cdev; /* claim */ /* allocate temporary function list */ midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(*midi_function), @@ -889,12 +892,6 @@ fail_f_midi: fail: f_midi_unregister_card(midi); fail_register: - /* we might as well release our claims on endpoints */ - if (midi->out_ep) - midi->out_ep->driver_data = NULL; - if (midi->in_ep) - midi->in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -906,9 +903,6 @@ static inline struct f_midi_opts *to_f_midi_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_midi_opts); -CONFIGFS_ATTR_OPS(f_midi_opts); - static void midi_attr_release(struct config_item *item) { struct f_midi_opts *opts = to_f_midi_opts(item); @@ -918,13 +912,12 @@ static void midi_attr_release(struct config_item *item) static struct configfs_item_operations midi_item_ops = { .release = midi_attr_release, - .show_attribute = f_midi_opts_attr_show, - .store_attribute = f_midi_opts_attr_store, }; #define F_MIDI_OPT(name, test_limit, limit) \ -static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \ +static ssize_t f_midi_opts_##name##_show(struct config_item *item, char *page) \ { \ + struct f_midi_opts *opts = to_f_midi_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -934,9 +927,10 @@ static ssize_t f_midi_opts_##name##_show(struct f_midi_opts *opts, char *page) \ return result; \ } \ \ -static ssize_t f_midi_opts_##name##_store(struct f_midi_opts *opts, \ +static ssize_t f_midi_opts_##name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct f_midi_opts *opts = to_f_midi_opts(item); \ int ret; \ u32 num; \ \ @@ -962,9 +956,7 @@ end: \ return ret; \ } \ \ -static struct f_midi_opts_attribute f_midi_opts_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, f_midi_opts_##name##_show, \ - f_midi_opts_##name##_store) +CONFIGFS_ATTR(f_midi_opts_, name); F_MIDI_OPT(index, true, SNDRV_CARDS); F_MIDI_OPT(buflen, false, 0); @@ -972,8 +964,9 @@ F_MIDI_OPT(qlen, false, 0); F_MIDI_OPT(in_ports, true, MAX_PORTS); F_MIDI_OPT(out_ports, true, MAX_PORTS); -static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page) +static ssize_t f_midi_opts_id_show(struct config_item *item, char *page) { + struct f_midi_opts *opts = to_f_midi_opts(item); int result; mutex_lock(&opts->lock); @@ -989,9 +982,10 @@ static ssize_t f_midi_opts_id_show(struct f_midi_opts *opts, char *page) return result; } -static ssize_t f_midi_opts_id_store(struct f_midi_opts *opts, +static ssize_t f_midi_opts_id_store(struct config_item *item, const char *page, size_t len) { + struct f_midi_opts *opts = to_f_midi_opts(item); int ret; char *c; @@ -1016,17 +1010,15 @@ end: return ret; } -static struct f_midi_opts_attribute f_midi_opts_id = - __CONFIGFS_ATTR(id, S_IRUGO | S_IWUSR, f_midi_opts_id_show, - f_midi_opts_id_store); +CONFIGFS_ATTR(f_midi_opts_, id); static struct configfs_attribute *midi_attrs[] = { - &f_midi_opts_index.attr, - &f_midi_opts_buflen.attr, - &f_midi_opts_qlen.attr, - &f_midi_opts_in_ports.attr, - &f_midi_opts_out_ports.attr, - &f_midi_opts_id.attr, + &f_midi_opts_attr_index, + &f_midi_opts_attr_buflen, + &f_midi_opts_attr_qlen, + &f_midi_opts_attr_in_ports, + &f_midi_opts_attr_out_ports, + &f_midi_opts_attr_id, NULL, }; diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 3f05c6bd5..7ad798ace 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -586,7 +586,7 @@ static void ncm_ep0out_complete(struct usb_ep *ep, struct usb_request *req) unsigned in_size; struct usb_function *f = req->context; struct f_ncm *ncm = func_to_ncm(f); - struct usb_composite_dev *cdev = ep->driver_data; + struct usb_composite_dev *cdev = f->config->cdev; req->context = NULL; if (req->status || req->actual != req->length) { @@ -803,10 +803,8 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt != 0) goto fail; - if (ncm->notify->driver_data) { - DBG(cdev, "reset ncm control %d\n", intf); - usb_ep_disable(ncm->notify); - } + DBG(cdev, "reset ncm control %d\n", intf); + usb_ep_disable(ncm->notify); if (!(ncm->notify->desc)) { DBG(cdev, "init ncm ctrl %d\n", intf); @@ -814,14 +812,13 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) goto fail; } usb_ep_enable(ncm->notify); - ncm->notify->driver_data = ncm; /* Data interface has two altsettings, 0 and 1 */ } else if (intf == ncm->data_id) { if (alt > 1) goto fail; - if (ncm->port.in_ep->driver_data) { + if (ncm->port.in_ep->enabled) { DBG(cdev, "reset ncm\n"); ncm->timer_stopping = true; ncm->netdev = NULL; @@ -885,7 +882,7 @@ static int ncm_get_alt(struct usb_function *f, unsigned intf) if (intf == ncm->ctrl_id) return 0; - return ncm->port.in_ep->driver_data ? 1 : 0; + return ncm->port.in_ep->enabled ? 1 : 0; } static struct sk_buff *package_for_tx(struct f_ncm *ncm) @@ -1276,15 +1273,14 @@ static void ncm_disable(struct usb_function *f) DBG(cdev, "ncm deactivated\n"); - if (ncm->port.in_ep->driver_data) { + if (ncm->port.in_ep->enabled) { ncm->timer_stopping = true; ncm->netdev = NULL; gether_disconnect(&ncm->port); } - if (ncm->notify->driver_data) { + if (ncm->notify->enabled) { usb_ep_disable(ncm->notify); - ncm->notify->driver_data = NULL; ncm->notify->desc = NULL; } } @@ -1402,19 +1398,16 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; ncm->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_out_desc); if (!ep) goto fail; ncm->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_ncm_notify_desc); if (!ep) goto fail; ncm->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -1468,14 +1461,6 @@ fail: usb_ep_free_request(ncm->notify, ncm->notify_req); } - /* we might as well release our claims on endpoints */ - if (ncm->notify) - ncm->notify->driver_data = NULL; - if (ncm->port.out_ep) - ncm->port.out_ep->driver_data = NULL; - if (ncm->port.in_ep) - ncm->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -1503,10 +1488,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(ncm); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(ncm); static struct configfs_attribute *ncm_attrs[] = { - &f_ncm_opts_dev_addr.attr, - &f_ncm_opts_host_addr.attr, - &f_ncm_opts_qmult.attr, - &f_ncm_opts_ifname.attr, + &ncm_opts_attr_dev_addr, + &ncm_opts_attr_host_addr, + &ncm_opts_attr_qmult, + &ncm_opts_attr_ifname, NULL, }; diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index 546042605..d6396e090 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -206,7 +206,7 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt > 1) goto fail; - if (obex->port.in->driver_data) { + if (obex->port.in->enabled) { dev_dbg(&cdev->gadget->dev, "reset obex ttyGS%d\n", obex->port_num); gserial_disconnect(&obex->port); @@ -348,13 +348,11 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; obex->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc); if (!ep) goto fail; obex->port.out = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -378,12 +376,6 @@ static int obex_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (obex->port.out) - obex->port.out->driver_data = NULL; - if (obex->port.in) - obex->port.in->driver_data = NULL; - ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status); return status; @@ -395,22 +387,6 @@ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_serial_opts); -static ssize_t f_obex_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct f_serial_opts *opts = to_f_serial_opts(item); - struct f_serial_opts_attribute *f_serial_opts_attr = - container_of(attr, struct f_serial_opts_attribute, attr); - ssize_t ret = 0; - - if (f_serial_opts_attr->show) - ret = f_serial_opts_attr->show(opts, page); - - return ret; -} - static void obex_attr_release(struct config_item *item) { struct f_serial_opts *opts = to_f_serial_opts(item); @@ -420,19 +396,17 @@ static void obex_attr_release(struct config_item *item) static struct configfs_item_operations obex_item_ops = { .release = obex_attr_release, - .show_attribute = f_obex_attr_show, }; -static ssize_t f_obex_port_num_show(struct f_serial_opts *opts, char *page) +static ssize_t f_obex_port_num_show(struct config_item *item, char *page) { - return sprintf(page, "%u\n", opts->port_num); + return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num); } -static struct f_serial_opts_attribute f_obex_port_num = - __CONFIGFS_ATTR_RO(port_num, f_obex_port_num_show); +CONFIGFS_ATTR_RO(f_obex_, port_num); static struct configfs_attribute *acm_attrs[] = { - &f_obex_port_num.attr, + &f_obex_attr_port_num, NULL, }; diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index c0c3ef272..157441dbf 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -418,7 +418,7 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) spin_lock(&port->lock); - if (fp->in_ep->driver_data) + if (fp->in_ep->enabled) __pn_reset(f); if (alt == 1) { @@ -530,13 +530,11 @@ static int pn_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto err; fp->out_ep = ep; - ep->driver_data = fp; /* Claim */ ep = usb_ep_autoconfig(gadget, &pn_fs_source_desc); if (!ep) goto err; fp->in_ep = ep; - ep->driver_data = fp; /* Claim */ pn_hs_sink_desc.bEndpointAddress = pn_fs_sink_desc.bEndpointAddress; pn_hs_source_desc.bEndpointAddress = pn_fs_source_desc.bEndpointAddress; @@ -575,10 +573,6 @@ err_req: usb_ep_free_request(fp->out_ep, fp->out_reqv[i]); usb_free_all_descriptors(f); err: - if (fp->out_ep) - fp->out_ep->driver_data = NULL; - if (fp->in_ep) - fp->in_ep->driver_data = NULL; ERROR(cdev, "USB CDC Phonet: cannot autoconfigure\n"); return status; } @@ -589,21 +583,6 @@ static inline struct f_phonet_opts *to_f_phonet_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_phonet_opts); -static ssize_t f_phonet_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct f_phonet_opts *opts = to_f_phonet_opts(item); - struct f_phonet_opts_attribute *f_phonet_opts_attr = - container_of(attr, struct f_phonet_opts_attribute, attr); - ssize_t ret = 0; - - if (f_phonet_opts_attr->show) - ret = f_phonet_opts_attr->show(opts, page); - return ret; -} - static void phonet_attr_release(struct config_item *item) { struct f_phonet_opts *opts = to_f_phonet_opts(item); @@ -613,19 +592,17 @@ static void phonet_attr_release(struct config_item *item) static struct configfs_item_operations phonet_item_ops = { .release = phonet_attr_release, - .show_attribute = f_phonet_attr_show, }; -static ssize_t f_phonet_ifname_show(struct f_phonet_opts *opts, char *page) +static ssize_t f_phonet_ifname_show(struct config_item *item, char *page) { - return gether_get_ifname(opts->net, page, PAGE_SIZE); + return gether_get_ifname(to_f_phonet_opts(item)->net, page, PAGE_SIZE); } -static struct f_phonet_opts_attribute f_phonet_ifname = - __CONFIGFS_ATTR_RO(ifname, f_phonet_ifname_show); +CONFIGFS_ATTR_RO(f_phonet_, ifname); static struct configfs_attribute *phonet_attrs[] = { - &f_phonet_ifname.attr, + &f_phonet_attr_ifname, NULL, }; diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 8e2b6bea0..0fbfb2b2a 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1039,12 +1039,10 @@ autoconf_fail: cdev->gadget->name); return -ENODEV; } - in_ep->driver_data = in_ep; /* claim */ out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc); if (!out_ep) goto autoconf_fail; - out_ep->driver_data = out_ep; /* claim */ /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; @@ -1148,9 +1146,6 @@ static inline struct f_printer_opts func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_printer_opts); -CONFIGFS_ATTR_OPS(f_printer_opts); - static void printer_attr_release(struct config_item *item) { struct f_printer_opts *opts = to_f_printer_opts(item); @@ -1160,13 +1155,12 @@ static void printer_attr_release(struct config_item *item) static struct configfs_item_operations printer_item_ops = { .release = printer_attr_release, - .show_attribute = f_printer_opts_attr_show, - .store_attribute = f_printer_opts_attr_store, }; -static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts, +static ssize_t f_printer_opts_pnp_string_show(struct config_item *item, char *page) { + struct f_printer_opts *opts = to_f_printer_opts(item); int result; mutex_lock(&opts->lock); @@ -1176,9 +1170,10 @@ static ssize_t f_printer_opts_pnp_string_show(struct f_printer_opts *opts, return result; } -static ssize_t f_printer_opts_pnp_string_store(struct f_printer_opts *opts, +static ssize_t f_printer_opts_pnp_string_store(struct config_item *item, const char *page, size_t len) { + struct f_printer_opts *opts = to_f_printer_opts(item); int result, l; mutex_lock(&opts->lock); @@ -1191,14 +1186,12 @@ static ssize_t f_printer_opts_pnp_string_store(struct f_printer_opts *opts, return result; } -static struct f_printer_opts_attribute f_printer_opts_pnp_string = - __CONFIGFS_ATTR(pnp_string, S_IRUGO | S_IWUSR, - f_printer_opts_pnp_string_show, - f_printer_opts_pnp_string_store); +CONFIGFS_ATTR(f_printer_opts_, pnp_string); -static ssize_t f_printer_opts_q_len_show(struct f_printer_opts *opts, +static ssize_t f_printer_opts_q_len_show(struct config_item *item, char *page) { + struct f_printer_opts *opts = to_f_printer_opts(item); int result; mutex_lock(&opts->lock); @@ -1208,9 +1201,10 @@ static ssize_t f_printer_opts_q_len_show(struct f_printer_opts *opts, return result; } -static ssize_t f_printer_opts_q_len_store(struct f_printer_opts *opts, +static ssize_t f_printer_opts_q_len_store(struct config_item *item, const char *page, size_t len) { + struct f_printer_opts *opts = to_f_printer_opts(item); int ret; u16 num; @@ -1231,13 +1225,11 @@ end: return ret; } -static struct f_printer_opts_attribute f_printer_opts_q_len = - __CONFIGFS_ATTR(q_len, S_IRUGO | S_IWUSR, f_printer_opts_q_len_show, - f_printer_opts_q_len_store); +CONFIGFS_ATTR(f_printer_opts_, q_len); static struct configfs_attribute *printer_attrs[] = { - &f_printer_opts_pnp_string.attr, - &f_printer_opts_q_len.attr, + &f_printer_opts_attr_pnp_string, + &f_printer_opts_attr_q_len, NULL, }; diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 32985dade..e587767e3 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -543,22 +543,20 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0 */ if (intf == rndis->ctrl_id) { - if (rndis->notify->driver_data) { - VDBG(cdev, "reset rndis control %d\n", intf); - usb_ep_disable(rndis->notify); - } + VDBG(cdev, "reset rndis control %d\n", intf); + usb_ep_disable(rndis->notify); + if (!rndis->notify->desc) { VDBG(cdev, "init rndis ctrl %d\n", intf); if (config_ep_by_speed(cdev->gadget, f, rndis->notify)) goto fail; } usb_ep_enable(rndis->notify); - rndis->notify->driver_data = rndis; } else if (intf == rndis->data_id) { struct net_device *net; - if (rndis->port.in_ep->driver_data) { + if (rndis->port.in_ep->enabled) { DBG(cdev, "reset rndis\n"); gether_disconnect(&rndis->port); } @@ -612,7 +610,7 @@ static void rndis_disable(struct usb_function *f) struct f_rndis *rndis = func_to_rndis(f); struct usb_composite_dev *cdev = f->config->cdev; - if (!rndis->notify->driver_data) + if (!rndis->notify->enabled) return; DBG(cdev, "rndis deactivated\n"); @@ -621,7 +619,6 @@ static void rndis_disable(struct usb_function *f) gether_disconnect(&rndis->port); usb_ep_disable(rndis->notify); - rndis->notify->driver_data = NULL; } /*-------------------------------------------------------------------------*/ @@ -745,13 +742,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; rndis->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc); if (!ep) goto fail; rndis->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* NOTE: a status/notification endpoint is, strictly speaking, * optional. We don't treat it that way though! It's simpler, @@ -761,7 +756,6 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; rndis->notify = ep; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -829,14 +823,6 @@ fail: usb_ep_free_request(rndis->notify, rndis->notify_req); } - /* we might as well release our claims on endpoints */ - if (rndis->notify) - rndis->notify->driver_data = NULL; - if (rndis->port.out_ep) - rndis->port.out_ep->driver_data = NULL; - if (rndis->port.in_ep) - rndis->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -878,10 +864,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(rndis); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(rndis); static struct configfs_attribute *rndis_attrs[] = { - &f_rndis_opts_dev_addr.attr, - &f_rndis_opts_host_addr.attr, - &f_rndis_opts_qmult.attr, - &f_rndis_opts_ifname.attr, + &rndis_opts_attr_dev_addr, + &rndis_opts_attr_host_addr, + &rndis_opts_attr_qmult, + &rndis_opts_attr_ifname, NULL, }; diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 1d162e200..6bb44d613 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -153,7 +153,7 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (gser->port.in->driver_data) { + if (gser->port.in->enabled) { dev_dbg(&cdev->gadget->dev, "reset generic ttyGS%d\n", gser->port_num); gserial_disconnect(&gser->port); @@ -219,13 +219,11 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; gser->port.in = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &gser_fs_out_desc); if (!ep) goto fail; gser->port.out = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -249,12 +247,6 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (gser->port.out) - gser->port.out->driver_data = NULL; - if (gser->port.in) - gser->port.in->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -266,22 +258,6 @@ static inline struct f_serial_opts *to_f_serial_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_serial_opts); -static ssize_t f_serial_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct f_serial_opts *opts = to_f_serial_opts(item); - struct f_serial_opts_attribute *f_serial_opts_attr = - container_of(attr, struct f_serial_opts_attribute, attr); - ssize_t ret = 0; - - if (f_serial_opts_attr->show) - ret = f_serial_opts_attr->show(opts, page); - - return ret; -} - static void serial_attr_release(struct config_item *item) { struct f_serial_opts *opts = to_f_serial_opts(item); @@ -291,19 +267,17 @@ static void serial_attr_release(struct config_item *item) static struct configfs_item_operations serial_item_ops = { .release = serial_attr_release, - .show_attribute = f_serial_attr_show, }; -static ssize_t f_serial_port_num_show(struct f_serial_opts *opts, char *page) +static ssize_t f_serial_port_num_show(struct config_item *item, char *page) { - return sprintf(page, "%u\n", opts->port_num); + return sprintf(page, "%u\n", to_f_serial_opts(item)->port_num); } -static struct f_serial_opts_attribute f_serial_port_num = - __CONFIGFS_ATTR_RO(port_num, f_serial_port_num_show); +CONFIGFS_ATTR_RO(f_serial_, port_num); static struct configfs_attribute *acm_attrs[] = { - &f_serial_port_num.attr, + &f_serial_attr_port_num, NULL, }; diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index cbfaf86fe..9f3ced62d 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -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) @@ -311,13 +313,9 @@ static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep) { int value; - if (ep->driver_data) { - value = usb_ep_disable(ep); - if (value < 0) - DBG(cdev, "disable %s --> %d\n", - ep->name, value); - ep->driver_data = NULL; - } + value = usb_ep_disable(ep); + if (value < 0) + DBG(cdev, "disable %s --> %d\n", ep->name, value); } void disable_endpoints(struct usb_composite_dev *cdev, @@ -355,42 +353,37 @@ autoconf_fail: f->name, cdev->gadget->name); return -ENODEV; } - ss->in_ep->driver_data = cdev; /* claim */ ss->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc); if (!ss->out_ep) goto autoconf_fail; - ss->out_ep->driver_data = cdev; /* claim */ /* 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); if (!ss->iso_in_ep) goto no_iso; - ss->iso_in_ep->driver_data = cdev; /* claim */ ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, &fs_iso_sink_desc); - if (ss->iso_out_ep) { - ss->iso_out_ep->driver_data = cdev; /* claim */ - } else { - ss->iso_in_ep->driver_data = NULL; + if (!ss->iso_out_ep) { + usb_ep_autoconfig_release(ss->iso_in_ep); ss->iso_in_ep = NULL; no_iso: /* @@ -403,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; @@ -415,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 */ @@ -437,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, @@ -489,12 +482,13 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) unsigned i; u8 *buf = req->buf; 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: @@ -510,7 +504,7 @@ static int check_read_data(struct f_sourcesink *ss, struct usb_request *req) * stutter for any reason, including buffer duplication...) */ case 1: - if (*buf == (u8)(i % 63)) + if (*buf == (u8)((i % max_packet_size) % 63)) continue; break; } @@ -525,14 +519,16 @@ 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; case 1: for (i = 0; i < req->length; i++) - *buf++ = (u8) (i % 63); + *buf++ = (u8) ((i % max_packet_size) % 63); break; case 2: break; @@ -556,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; @@ -605,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; @@ -629,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); @@ -683,7 +680,6 @@ enable_source_sink(struct usb_composite_dev *cdev, struct f_sourcesink *ss, fail: ep = ss->in_ep; usb_ep_disable(ep); - ep->driver_data = NULL; return result; } @@ -702,7 +698,6 @@ fail: fail2: ep = ss->out_ep; usb_ep_disable(ep); - ep->driver_data = NULL; goto fail; } @@ -724,10 +719,8 @@ fail2: if (result < 0) { fail3: ep = ss->iso_in_ep; - if (ep) { + if (ep) usb_ep_disable(ep); - ep->driver_data = NULL; - } goto fail2; } } @@ -746,7 +739,6 @@ fail3: result = source_sink_start_ep(ss, false, true, speed); if (result < 0) { usb_ep_disable(ep); - ep->driver_data = NULL; goto fail3; } } @@ -763,8 +755,7 @@ static int sourcesink_set_alt(struct usb_function *f, struct f_sourcesink *ss = func_to_ss(f); struct usb_composite_dev *cdev = f->config->cdev; - if (ss->in_ep->driver_data) - disable_source_sink(ss); + disable_source_sink(ss); return enable_source_sink(cdev, ss, alt); } @@ -872,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; @@ -898,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); @@ -910,24 +898,24 @@ 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); - result = sprintf(page, "%u", opts->pattern); + result = sprintf(page, "%u\n", opts->pattern); mutex_unlock(&opts->lock); 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; @@ -953,25 +941,24 @@ 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); - result = sprintf(page, "%u", opts->isoc_interval); + result = sprintf(page, "%u\n", opts->isoc_interval); mutex_unlock(&opts->lock); 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; @@ -997,25 +984,24 @@ 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); - result = sprintf(page, "%u", opts->isoc_maxpacket); + result = sprintf(page, "%u\n", opts->isoc_maxpacket); mutex_unlock(&opts->lock); 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; @@ -1041,25 +1027,24 @@ 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); - result = sprintf(page, "%u", opts->isoc_mult); + result = sprintf(page, "%u\n", opts->isoc_mult); mutex_unlock(&opts->lock); 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; @@ -1085,25 +1070,24 @@ 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); - result = sprintf(page, "%u", opts->isoc_maxburst); + result = sprintf(page, "%u\n", opts->isoc_maxburst); mutex_unlock(&opts->lock); 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; @@ -1129,25 +1113,24 @@ 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); - result = sprintf(page, "%u", opts->bulk_buflen); + result = sprintf(page, "%u\n", opts->bulk_buflen); mutex_unlock(&opts->lock); 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; @@ -1168,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, }; diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index e3dfa675f..829c78de9 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -262,7 +262,7 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (geth->port.in_ep->driver_data) { + if (geth->port.in_ep->enabled) { DBG(cdev, "reset cdc subset\n"); gether_disconnect(&geth->port); } @@ -343,13 +343,11 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) if (!ep) goto fail; geth->port.in_ep = ep; - ep->driver_data = cdev; /* claim */ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc); if (!ep) goto fail; geth->port.out_ep = ep; - ep->driver_data = cdev; /* claim */ /* support all relevant hardware speeds... we expect that when * hardware is dual speed, all bulk-capable endpoints work at @@ -380,12 +378,6 @@ geth_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: - /* we might as well release our claims on endpoints */ - if (geth->port.out_ep) - geth->port.out_ep->driver_data = NULL; - if (geth->port.in_ep) - geth->port.in_ep->driver_data = NULL; - ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -413,10 +405,10 @@ USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(gether); USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(gether); static struct configfs_attribute *gether_attrs[] = { - &f_gether_opts_dev_addr.attr, - &f_gether_opts_host_addr.attr, - &f_gether_opts_qmult.attr, - &f_gether_opts_ifname.attr, + &gether_opts_attr_dev_addr, + &gether_opts_attr_host_addr, + &gether_opts_attr_qmult, + &gether_opts_attr_ifname, NULL, }; diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 7856b3394..6a2346b99 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -593,7 +593,6 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return err; usb_ep_enable(out_ep); - out_ep->driver_data = audio; audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(audio->copy_buf)) return -ENOMEM; @@ -718,7 +717,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) goto fail; audio->out_ep = ep; audio->out_ep->desc = &as_out_ep_desc; - ep->driver_data = cdev; /* claim */ status = -ENOMEM; @@ -730,8 +728,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) fail: gaudio_cleanup(&audio->card); - if (ep) - ep->driver_data = NULL; return status; } @@ -773,9 +769,6 @@ static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_uac1_opts); -CONFIGFS_ATTR_OPS(f_uac1_opts); - static void f_uac1_attr_release(struct config_item *item) { struct f_uac1_opts *opts = to_f_uac1_opts(item); @@ -785,14 +778,13 @@ static void f_uac1_attr_release(struct config_item *item) static struct configfs_item_operations f_uac1_item_ops = { .release = f_uac1_attr_release, - .show_attribute = f_uac1_opts_attr_show, - .store_attribute = f_uac1_opts_attr_store, }; #define UAC1_INT_ATTRIBUTE(name) \ -static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \ +static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ char *page) \ { \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -802,9 +794,10 @@ static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \ return result; \ } \ \ -static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts, \ +static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ int ret; \ u32 num; \ \ @@ -826,19 +819,17 @@ end: \ return ret; \ } \ \ -static struct f_uac1_opts_attribute f_uac1_opts_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ - f_uac1_opts_##name##_show, \ - f_uac1_opts_##name##_store) +CONFIGFS_ATTR(f_uac1_opts_, name) UAC1_INT_ATTRIBUTE(req_buf_size); UAC1_INT_ATTRIBUTE(req_count); UAC1_INT_ATTRIBUTE(audio_buf_size); #define UAC1_STR_ATTRIBUTE(name) \ -static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \ +static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ char *page) \ { \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -848,9 +839,10 @@ static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \ return result; \ } \ \ -static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts, \ +static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ int ret = -EBUSY; \ char *tmp; \ \ @@ -874,22 +866,19 @@ end: \ return ret; \ } \ \ -static struct f_uac1_opts_attribute f_uac1_opts_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ - f_uac1_opts_##name##_show, \ - f_uac1_opts_##name##_store) +CONFIGFS_ATTR(f_uac1_opts_, name) UAC1_STR_ATTRIBUTE(fn_play); UAC1_STR_ATTRIBUTE(fn_cap); UAC1_STR_ATTRIBUTE(fn_cntl); static struct configfs_attribute *f_uac1_attrs[] = { - &f_uac1_opts_req_buf_size.attr, - &f_uac1_opts_req_count.attr, - &f_uac1_opts_audio_buf_size.attr, - &f_uac1_opts_fn_play.attr, - &f_uac1_opts_fn_cap.attr, - &f_uac1_opts_fn_cntl.attr, + &f_uac1_opts_attr_req_buf_size, + &f_uac1_opts_attr_req_count, + &f_uac1_opts_attr_audio_buf_size, + &f_uac1_opts_attr_fn_play, + &f_uac1_opts_attr_fn_cap, + &f_uac1_opts_attr_fn_cntl, NULL, }; diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f8de7ea2a..044ca79d3 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1081,14 +1081,12 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); goto err; } - agdev->out_ep->driver_data = agdev; agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); if (!agdev->in_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); goto err; } - agdev->in_ep->driver_data = agdev; uac2->p_prm.uac2 = uac2; uac2->c_prm.uac2 = uac2; @@ -1132,10 +1130,6 @@ err_free_descs: err: kfree(agdev->uac2.p_prm.rbuf); kfree(agdev->uac2.c_prm.rbuf); - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; return -EINVAL; } @@ -1445,9 +1439,6 @@ static inline struct f_uac2_opts *to_f_uac2_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_uac2_opts); -CONFIGFS_ATTR_OPS(f_uac2_opts); - static void f_uac2_attr_release(struct config_item *item) { struct f_uac2_opts *opts = to_f_uac2_opts(item); @@ -1457,14 +1448,13 @@ static void f_uac2_attr_release(struct config_item *item) static struct configfs_item_operations f_uac2_item_ops = { .release = f_uac2_attr_release, - .show_attribute = f_uac2_opts_attr_show, - .store_attribute = f_uac2_opts_attr_store, }; #define UAC2_ATTRIBUTE(name) \ -static ssize_t f_uac2_opts_##name##_show(struct f_uac2_opts *opts, \ +static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \ char *page) \ { \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -1474,9 +1464,10 @@ static ssize_t f_uac2_opts_##name##_show(struct f_uac2_opts *opts, \ return result; \ } \ \ -static ssize_t f_uac2_opts_##name##_store(struct f_uac2_opts *opts, \ +static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ int ret; \ u32 num; \ \ @@ -1498,10 +1489,7 @@ end: \ return ret; \ } \ \ -static struct f_uac2_opts_attribute f_uac2_opts_##name = \ - __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ - f_uac2_opts_##name##_show, \ - f_uac2_opts_##name##_store) +CONFIGFS_ATTR(f_uac2_opts_, name) UAC2_ATTRIBUTE(p_chmask); UAC2_ATTRIBUTE(p_srate); @@ -1511,12 +1499,12 @@ UAC2_ATTRIBUTE(c_srate); UAC2_ATTRIBUTE(c_ssize); static struct configfs_attribute *f_uac2_attrs[] = { - &f_uac2_opts_p_chmask.attr, - &f_uac2_opts_p_srate.attr, - &f_uac2_opts_p_ssize.attr, - &f_uac2_opts_c_chmask.attr, - &f_uac2_opts_c_srate.attr, - &f_uac2_opts_c_ssize.attr, + &f_uac2_opts_attr_p_chmask, + &f_uac2_opts_attr_p_srate, + &f_uac2_opts_attr_p_ssize, + &f_uac2_opts_attr_c_chmask, + &f_uac2_opts_attr_c_srate, + &f_uac2_opts_attr_c_ssize, NULL, }; @@ -1583,11 +1571,6 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) prm = &agdev->uac2.c_prm; kfree(prm->rbuf); usb_free_all_descriptors(f); - - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; } static struct usb_function *afunc_alloc(struct usb_function_instance *fi) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index 743be3460..29b41b5de 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -280,7 +280,7 @@ uvc_function_get_alt(struct usb_function *f, unsigned interface) else if (interface != uvc->streaming_intf) return -EINVAL; else - return uvc->video.ep->driver_data ? 1 : 0; + return uvc->video.ep->enabled ? 1 : 0; } static int @@ -298,18 +298,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (alt) return -EINVAL; - if (uvc->control_ep->driver_data) { - INFO(cdev, "reset UVC Control\n"); - usb_ep_disable(uvc->control_ep); - uvc->control_ep->driver_data = NULL; - } + INFO(cdev, "reset UVC Control\n"); + usb_ep_disable(uvc->control_ep); if (!uvc->control_ep->desc) if (config_ep_by_speed(cdev->gadget, f, uvc->control_ep)) return -EINVAL; usb_ep_enable(uvc->control_ep); - uvc->control_ep->driver_data = uvc; if (uvc->state == UVC_STATE_DISCONNECTED) { memset(&v4l2_event, 0, sizeof(v4l2_event)); @@ -336,10 +332,8 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (uvc->state != UVC_STATE_STREAMING) return 0; - if (uvc->video.ep) { + if (uvc->video.ep) usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMOFF; @@ -355,18 +349,14 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt) if (!uvc->video.ep) return -EINVAL; - if (uvc->video.ep->driver_data) { - INFO(cdev, "reset UVC\n"); - usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } + INFO(cdev, "reset UVC\n"); + usb_ep_disable(uvc->video.ep); ret = config_ep_by_speed(f->config->cdev->gadget, &(uvc->func), uvc->video.ep); if (ret) return ret; usb_ep_enable(uvc->video.ep); - uvc->video.ep->driver_data = uvc; memset(&v4l2_event, 0, sizeof(v4l2_event)); v4l2_event.type = UVC_EVENT_STREAMON; @@ -392,15 +382,8 @@ uvc_function_disable(struct usb_function *f) uvc->state = UVC_STATE_DISCONNECTED; - if (uvc->video.ep->driver_data) { - usb_ep_disable(uvc->video.ep); - uvc->video.ep->driver_data = NULL; - } - - if (uvc->control_ep->driver_data) { - usb_ep_disable(uvc->control_ep); - uvc->control_ep->driver_data = NULL; - } + usb_ep_disable(uvc->video.ep); + usb_ep_disable(uvc->control_ep); } /* -------------------------------------------------------------------------- @@ -651,7 +634,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } uvc->control_ep = ep; - ep->driver_data = uvc; if (gadget_is_superspeed(c->cdev->gadget)) ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep, @@ -666,7 +648,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) goto error; } uvc->video.ep = ep; - ep->driver_data = uvc; uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address; uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address; @@ -755,11 +736,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) error: v4l2_device_unregister(&uvc->v4l2_dev); - if (uvc->control_ep) - uvc->control_ep->driver_data = NULL; - if (uvc->video.ep) - uvc->video.ep->driver_data = NULL; - if (uvc->control_req) usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); @@ -886,8 +862,6 @@ static void uvc_unbind(struct usb_configuration *c, struct usb_function *f) video_unregister_device(&uvc->vdev); v4l2_device_unregister(&uvc->v4l2_dev); - uvc->control_ep->driver_data = NULL; - uvc->video.ep->driver_data = NULL; usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); kfree(uvc->control_buf); diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index f1fd777ef..6554322af 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -48,6 +48,11 @@ #define UETH__VERSION "29-May-2008" +/* Experiments show that both Linux and Windows hosts allow up to 16k + * frame sizes. Set the max size to 15k+52 to prevent allocating 32k + * blocks and still have efficient handling. */ +#define GETHER_MAX_ETH_FRAME_LEN 15412 + struct eth_dev { /* lock is held while accessing port_usb */ @@ -146,7 +151,7 @@ static int ueth_change_mtu(struct net_device *net, int new_mtu) spin_lock_irqsave(&dev->lock, flags); if (dev->port_usb) status = -EBUSY; - else if (new_mtu <= ETH_HLEN || new_mtu > ETH_FRAME_LEN) + else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) status = -ERANGE; else net->mtu = new_mtu; @@ -294,7 +299,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) while (skb2) { if (status < 0 || ETH_HLEN > skb2->len - || skb2->len > VLAN_ETH_FRAME_LEN) { + || skb2->len > GETHER_MAX_ETH_FRAME_LEN) { dev->net->stats.rx_errors++; dev->net->stats.rx_length_errors++; DBG(dev, "rx length %d\n", skb2->len); @@ -1144,7 +1149,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - link->in_ep->driver_data = NULL; link->in_ep->desc = NULL; usb_ep_disable(link->out_ep); @@ -1159,7 +1163,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - link->out_ep->driver_data = NULL; link->out_ep->desc = NULL; /* finish forgetting about this USB link episode */ diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index bcbd30146..4f47289fc 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -17,9 +17,6 @@ #define __U_ETHER_CONFIGFS_H #define USB_ETHERNET_CONFIGFS_ITEM(_f_) \ - CONFIGFS_ATTR_STRUCT(f_##_f_##_opts); \ - CONFIGFS_ATTR_OPS(f_##_f_##_opts); \ - \ static void _f_##_attr_release(struct config_item *item) \ { \ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ @@ -29,14 +26,13 @@ \ static struct configfs_item_operations _f_##_item_ops = { \ .release = _f_##_attr_release, \ - .show_attribute = f_##_f_##_opts_attr_show, \ - .store_attribute = f_##_f_##_opts_attr_store, \ } #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \ - static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \ char *page) \ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -46,9 +42,10 @@ return result; \ } \ \ - static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_dev_addr_store(struct config_item *item, \ const char *page, size_t len)\ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int ret; \ \ mutex_lock(&opts->lock); \ @@ -64,15 +61,13 @@ return ret; \ } \ \ - static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \ - __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, \ - _f_##_opts_dev_addr_show, \ - _f_##_opts_dev_addr_store) + CONFIGFS_ATTR(_f_##_opts_, dev_addr) #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \ - static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \ char *page) \ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -82,9 +77,10 @@ return result; \ } \ \ - static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_host_addr_store(struct config_item *item, \ const char *page, size_t len)\ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int ret; \ \ mutex_lock(&opts->lock); \ @@ -100,15 +96,13 @@ return ret; \ } \ \ - static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \ - __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, \ - _f_##_opts_host_addr_show, \ - _f_##_opts_host_addr_store) + CONFIGFS_ATTR(_f_##_opts_, host_addr) #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \ - static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_qmult_show(struct config_item *item, \ char *page) \ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ unsigned qmult; \ \ mutex_lock(&opts->lock); \ @@ -117,9 +111,10 @@ return sprintf(page, "%d", qmult); \ } \ \ - static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_qmult_store(struct config_item *item, \ const char *page, size_t len)\ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ u8 val; \ int ret; \ \ @@ -140,15 +135,13 @@ out: \ return ret; \ } \ \ - static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult = \ - __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, \ - _f_##_opts_qmult_show, \ - _f_##_opts_qmult_store) + CONFIGFS_ATTR(_f_##_opts_, qmult) #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \ - static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \ + static ssize_t _f_##_opts_ifname_show(struct config_item *item, \ char *page) \ { \ + struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int ret; \ \ mutex_lock(&opts->lock); \ @@ -158,7 +151,6 @@ out: \ return ret; \ } \ \ - static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname = \ - __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show) + CONFIGFS_ATTR_RO(_f_##_opts_, ifname) #endif /* __U_ETHER_CONFIGFS_H */ diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 8d77b2b50..15a4229ec 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -114,6 +114,7 @@ struct gs_port { struct gs_buf port_write_buf; wait_queue_head_t drain_wait; /* wait while writes drain */ bool write_busy; + wait_queue_head_t close_wait; /* REVISIT this state ... */ struct usb_cdc_line_coding port_line_coding; /* 8-N-1 etc */ @@ -876,7 +877,6 @@ static void gs_close(struct tty_struct *tty, struct file *file) else gs_buf_clear(&port->port_write_buf); - tty->driver_data = NULL; port->port.tty = NULL; port->openclose = false; @@ -884,7 +884,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) pr_debug("gs_close: ttyGS%d (%p,%p) done!\n", port->port_num, tty, file); - wake_up(&port->port.close_wait); + wake_up(&port->close_wait); exit: spin_unlock_irq(&port->port_lock); } @@ -1044,6 +1044,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) tty_port_init(&port->port); spin_lock_init(&port->port_lock); init_waitqueue_head(&port->drain_wait); + init_waitqueue_head(&port->close_wait); tasklet_init(&port->push, gs_rx_push, (unsigned long) port); @@ -1074,7 +1075,7 @@ static void gserial_free_port(struct gs_port *port) { tasklet_kill(&port->push); /* wait for old opens to finish */ - wait_event(port->port.close_wait, gs_closed(port)); + wait_event(port->close_wait, gs_closed(port)); WARN_ON(port->port_usb != NULL); tty_port_destroy(&port->port); kfree(port); @@ -1224,7 +1225,6 @@ int gserial_connect(struct gserial *gser, u8 port_num) fail_out: usb_ep_disable(gser->in); - gser->in->driver_data = NULL; return status; } EXPORT_SYMBOL_GPL(gserial_connect); @@ -1269,10 +1269,7 @@ void gserial_disconnect(struct gserial *gser) /* disable endpoints, aborting down any active I/O */ usb_ep_disable(gser->out); - gser->out->driver_data = NULL; - usb_ep_disable(gser->in); - gser->in->driver_data = NULL; /* finally, free any unused/unusable I/O buffers */ spin_lock_irqsave(&port->port_lock, flags); diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 3c0467bcb..ad8c9b055 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -17,19 +17,21 @@ #define UVCG_STREAMING_CONTROL_SIZE 1 -#define CONFIGFS_ATTR_OPS_RO(_item) \ -static ssize_t _item##_attr_show(struct config_item *item, \ - struct configfs_attribute *attr, \ - char *page) \ -{ \ - struct _item *_item = to_##_item(item); \ - struct _item##_attribute *_item##_attr = \ - container_of(attr, struct _item##_attribute, attr); \ - ssize_t ret = 0; \ - \ - if (_item##_attr->show) \ - ret = _item##_attr->show(_item, page); \ - return ret; \ +#define UVC_ATTR(prefix, cname, aname) \ +static struct configfs_attribute prefix##attr_##cname = { \ + .ca_name = __stringify(aname), \ + .ca_mode = S_IRUGO | S_IWUGO, \ + .ca_owner = THIS_MODULE, \ + .show = prefix##cname##_show, \ + .store = prefix##cname##_store, \ +} + +#define UVC_ATTR_RO(prefix, cname, aname) \ +static struct configfs_attribute prefix##attr_##cname = { \ + .ca_name = __stringify(aname), \ + .ca_mode = S_IRUGO, \ + .ca_owner = THIS_MODULE, \ + .show = prefix##cname##_show, \ } static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item); @@ -48,18 +50,11 @@ static struct uvcg_control_header *to_uvcg_control_header(struct config_item *it return container_of(item, struct uvcg_control_header, item); } -CONFIGFS_ATTR_STRUCT(uvcg_control_header); -CONFIGFS_ATTR_OPS(uvcg_control_header); - -static struct configfs_item_operations uvcg_control_header_item_ops = { - .show_attribute = uvcg_control_header_attr_show, - .store_attribute = uvcg_control_header_attr_store, -}; - #define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ static ssize_t uvcg_control_header_##cname##_show( \ - struct uvcg_control_header *ch, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_control_header *ch = to_uvcg_control_header(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ @@ -79,9 +74,10 @@ static ssize_t uvcg_control_header_##cname##_show( \ } \ \ static ssize_t \ -uvcg_control_header_##cname##_store(struct uvcg_control_header *ch, \ +uvcg_control_header_##cname##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct uvcg_control_header *ch = to_uvcg_control_header(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ @@ -115,11 +111,7 @@ end: \ return ret; \ } \ \ -static struct uvcg_control_header_attribute \ - uvcg_control_header_##cname = \ - __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ - uvcg_control_header_##cname##_show, \ - uvcg_control_header_##cname##_store) +UVC_ATTR(uvcg_control_header_, cname, aname) UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16, 0xffff); @@ -130,13 +122,12 @@ UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32, #undef UVCG_CTRL_HDR_ATTR static struct configfs_attribute *uvcg_control_header_attrs[] = { - &uvcg_control_header_bcd_uvc.attr, - &uvcg_control_header_dw_clock_frequency.attr, + &uvcg_control_header_attr_bcd_uvc, + &uvcg_control_header_attr_dw_clock_frequency, NULL, }; static struct config_item_type uvcg_control_header_type = { - .ct_item_ops = &uvcg_control_header_item_ops, .ct_attrs = uvcg_control_header_attrs, .ct_owner = THIS_MODULE, }; @@ -196,17 +187,11 @@ static inline struct uvcg_default_processing struct uvcg_default_processing, group); } -CONFIGFS_ATTR_STRUCT(uvcg_default_processing); -CONFIGFS_ATTR_OPS_RO(uvcg_default_processing); - -static struct configfs_item_operations uvcg_default_processing_item_ops = { - .show_attribute = uvcg_default_processing_attr_show, -}; - #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv) \ static ssize_t uvcg_default_processing_##cname##_show( \ - struct uvcg_default_processing *dp, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_default_processing *dp = to_uvcg_default_processing(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; \ @@ -227,9 +212,7 @@ static ssize_t uvcg_default_processing_##cname##_show( \ return result; \ } \ \ -static struct uvcg_default_processing_attribute \ - uvcg_default_processing_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_default_processing_##cname##_show) +UVC_ATTR_RO(uvcg_default_processing_, cname, aname) #define identity_conv(x) (x) @@ -243,8 +226,9 @@ UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv); #undef UVCG_DEFAULT_PROCESSING_ATTR static ssize_t uvcg_default_processing_bm_controls_show( - struct uvcg_default_processing *dp, char *page) + struct config_item *item, char *page) { + struct uvcg_default_processing *dp = to_uvcg_default_processing(item); struct f_uvc_opts *opts; struct config_item *opts_item; struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex; @@ -270,22 +254,18 @@ static ssize_t uvcg_default_processing_bm_controls_show( return result; } -static struct uvcg_default_processing_attribute - uvcg_default_processing_bm_controls = - __CONFIGFS_ATTR_RO(bmControls, - uvcg_default_processing_bm_controls_show); +UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); static struct configfs_attribute *uvcg_default_processing_attrs[] = { - &uvcg_default_processing_b_unit_id.attr, - &uvcg_default_processing_b_source_id.attr, - &uvcg_default_processing_w_max_multiplier.attr, - &uvcg_default_processing_bm_controls.attr, - &uvcg_default_processing_i_processing.attr, + &uvcg_default_processing_attr_b_unit_id, + &uvcg_default_processing_attr_b_source_id, + &uvcg_default_processing_attr_w_max_multiplier, + &uvcg_default_processing_attr_bm_controls, + &uvcg_default_processing_attr_i_processing, NULL, }; static struct config_item_type uvcg_default_processing_type = { - .ct_item_ops = &uvcg_default_processing_item_ops, .ct_attrs = uvcg_default_processing_attrs, .ct_owner = THIS_MODULE, }; @@ -318,17 +298,11 @@ static inline struct uvcg_default_camera struct uvcg_default_camera, group); } -CONFIGFS_ATTR_STRUCT(uvcg_default_camera); -CONFIGFS_ATTR_OPS_RO(uvcg_default_camera); - -static struct configfs_item_operations uvcg_default_camera_item_ops = { - .show_attribute = uvcg_default_camera_attr_show, -}; - #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv) \ static ssize_t uvcg_default_camera_##cname##_show( \ - struct uvcg_default_camera *dc, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_default_camera *dc = to_uvcg_default_camera(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; \ @@ -351,9 +325,7 @@ static ssize_t uvcg_default_camera_##cname##_show( \ return result; \ } \ \ -static struct uvcg_default_camera_attribute \ - uvcg_default_camera_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_default_camera_##cname##_show) +UVC_ATTR_RO(uvcg_default_camera_, cname, aname) #define identity_conv(x) (x) @@ -373,8 +345,9 @@ UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength, #undef UVCG_DEFAULT_CAMERA_ATTR static ssize_t uvcg_default_camera_bm_controls_show( - struct uvcg_default_camera *dc, char *page) + struct config_item *item, char *page) { + struct uvcg_default_camera *dc = to_uvcg_default_camera(item); struct f_uvc_opts *opts; struct config_item *opts_item; struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; @@ -400,24 +373,21 @@ static ssize_t uvcg_default_camera_bm_controls_show( return result; } -static struct uvcg_default_camera_attribute - uvcg_default_camera_bm_controls = - __CONFIGFS_ATTR_RO(bmControls, uvcg_default_camera_bm_controls_show); +UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); static struct configfs_attribute *uvcg_default_camera_attrs[] = { - &uvcg_default_camera_b_terminal_id.attr, - &uvcg_default_camera_w_terminal_type.attr, - &uvcg_default_camera_b_assoc_terminal.attr, - &uvcg_default_camera_i_terminal.attr, - &uvcg_default_camera_w_objective_focal_length_min.attr, - &uvcg_default_camera_w_objective_focal_length_max.attr, - &uvcg_default_camera_w_ocular_focal_length.attr, - &uvcg_default_camera_bm_controls.attr, + &uvcg_default_camera_attr_b_terminal_id, + &uvcg_default_camera_attr_w_terminal_type, + &uvcg_default_camera_attr_b_assoc_terminal, + &uvcg_default_camera_attr_i_terminal, + &uvcg_default_camera_attr_w_objective_focal_length_min, + &uvcg_default_camera_attr_w_objective_focal_length_max, + &uvcg_default_camera_attr_w_ocular_focal_length, + &uvcg_default_camera_attr_bm_controls, NULL, }; static struct config_item_type uvcg_default_camera_type = { - .ct_item_ops = &uvcg_default_camera_item_ops, .ct_attrs = uvcg_default_camera_attrs, .ct_owner = THIS_MODULE, }; @@ -450,17 +420,11 @@ static inline struct uvcg_default_output struct uvcg_default_output, group); } -CONFIGFS_ATTR_STRUCT(uvcg_default_output); -CONFIGFS_ATTR_OPS_RO(uvcg_default_output); - -static struct configfs_item_operations uvcg_default_output_item_ops = { - .show_attribute = uvcg_default_output_attr_show, -}; - #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv) \ static ssize_t uvcg_default_output_##cname##_show( \ - struct uvcg_default_output *dout, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_default_output *dout = to_uvcg_default_output(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &dout->group.cg_subsys->su_mutex; \ @@ -483,9 +447,7 @@ static ssize_t uvcg_default_output_##cname##_show( \ return result; \ } \ \ -static struct uvcg_default_output_attribute \ - uvcg_default_output_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_default_output_##cname##_show) +UVC_ATTR_RO(uvcg_default_output_, cname, aname) #define identity_conv(x) (x) @@ -500,16 +462,15 @@ UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv); #undef UVCG_DEFAULT_OUTPUT_ATTR static struct configfs_attribute *uvcg_default_output_attrs[] = { - &uvcg_default_output_b_terminal_id.attr, - &uvcg_default_output_w_terminal_type.attr, - &uvcg_default_output_b_assoc_terminal.attr, - &uvcg_default_output_b_source_id.attr, - &uvcg_default_output_i_terminal.attr, + &uvcg_default_output_attr_b_terminal_id, + &uvcg_default_output_attr_w_terminal_type, + &uvcg_default_output_attr_b_assoc_terminal, + &uvcg_default_output_attr_b_source_id, + &uvcg_default_output_attr_i_terminal, NULL, }; static struct config_item_type uvcg_default_output_type = { - .ct_item_ops = &uvcg_default_output_item_ops, .ct_attrs = uvcg_default_output_attrs, .ct_owner = THIS_MODULE, }; @@ -800,9 +761,6 @@ static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item return container_of(item, struct uvcg_streaming_header, item); } -CONFIGFS_ATTR_STRUCT(uvcg_streaming_header); -CONFIGFS_ATTR_OPS(uvcg_streaming_header); - static int uvcg_streaming_header_allow_link(struct config_item *src, struct config_item *target) { @@ -893,16 +851,15 @@ out: } static struct configfs_item_operations uvcg_streaming_header_item_ops = { - .show_attribute = uvcg_streaming_header_attr_show, - .store_attribute = uvcg_streaming_header_attr_store, .allow_link = uvcg_streaming_header_allow_link, .drop_link = uvcg_streaming_header_drop_link, }; #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv) \ static ssize_t uvcg_streaming_header_##cname##_show( \ - struct uvcg_streaming_header *sh, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\ @@ -921,9 +878,7 @@ static ssize_t uvcg_streaming_header_##cname##_show( \ return result; \ } \ \ -static struct uvcg_streaming_header_attribute \ - uvcg_streaming_header_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_streaming_header_##cname##_show) +UVC_ATTR_RO(uvcg_streaming_header_, cname, aname) #define identity_conv(x) (x) @@ -939,11 +894,11 @@ UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv); #undef UVCG_STREAMING_HEADER_ATTR static struct configfs_attribute *uvcg_streaming_header_attrs[] = { - &uvcg_streaming_header_bm_info.attr, - &uvcg_streaming_header_b_terminal_link.attr, - &uvcg_streaming_header_b_still_capture_method.attr, - &uvcg_streaming_header_b_trigger_support.attr, - &uvcg_streaming_header_b_trigger_usage.attr, + &uvcg_streaming_header_attr_bm_info, + &uvcg_streaming_header_attr_b_terminal_link, + &uvcg_streaming_header_attr_b_still_capture_method, + &uvcg_streaming_header_attr_b_trigger_support, + &uvcg_streaming_header_attr_b_trigger_usage, NULL, }; @@ -1022,17 +977,10 @@ static struct uvcg_frame *to_uvcg_frame(struct config_item *item) return container_of(item, struct uvcg_frame, item); } -CONFIGFS_ATTR_STRUCT(uvcg_frame); -CONFIGFS_ATTR_OPS(uvcg_frame); - -static struct configfs_item_operations uvcg_frame_item_ops = { - .show_attribute = uvcg_frame_attr_show, - .store_attribute = uvcg_frame_attr_store, -}; - #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ -static ssize_t uvcg_frame_##cname##_show(struct uvcg_frame *f, char *page)\ +static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\ { \ + struct uvcg_frame *f = to_uvcg_frame(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ @@ -1051,9 +999,10 @@ static ssize_t uvcg_frame_##cname##_show(struct uvcg_frame *f, char *page)\ return result; \ } \ \ -static ssize_t uvcg_frame_##cname##_store(struct uvcg_frame *f, \ +static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \ const char *page, size_t len)\ { \ + struct uvcg_frame *f = to_uvcg_frame(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct uvcg_format *fmt; \ @@ -1085,11 +1034,7 @@ end: \ return ret; \ } \ \ -static struct uvcg_frame_attribute \ - uvcg_frame_##cname = \ - __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ - uvcg_frame_##cname##_show, \ - uvcg_frame_##cname##_store) +UVC_ATTR(uvcg_frame_, cname, aname); #define noop_conversion(x) (x) @@ -1108,9 +1053,10 @@ UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, #undef UVCG_FRAME_ATTR -static ssize_t uvcg_frame_dw_frame_interval_show(struct uvcg_frame *frm, +static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, char *page) { + struct uvcg_frame *frm = to_uvcg_frame(item); struct f_uvc_opts *opts; struct config_item *opts_item; struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; @@ -1185,9 +1131,10 @@ static int __uvcg_iter_frm_intrv(const char *page, size_t len, return 0; } -static ssize_t uvcg_frame_dw_frame_interval_store(struct uvcg_frame *ch, +static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item, const char *page, size_t len) { + struct uvcg_frame *ch = to_uvcg_frame(item); struct f_uvc_opts *opts; struct config_item *opts_item; struct uvcg_format *fmt; @@ -1234,26 +1181,21 @@ end: return ret; } -static struct uvcg_frame_attribute - uvcg_frame_dw_frame_interval = - __CONFIGFS_ATTR(dwFrameInterval, S_IRUGO | S_IWUSR, - uvcg_frame_dw_frame_interval_show, - uvcg_frame_dw_frame_interval_store); +UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); static struct configfs_attribute *uvcg_frame_attrs[] = { - &uvcg_frame_bm_capabilities.attr, - &uvcg_frame_w_width.attr, - &uvcg_frame_w_height.attr, - &uvcg_frame_dw_min_bit_rate.attr, - &uvcg_frame_dw_max_bit_rate.attr, - &uvcg_frame_dw_max_video_frame_buffer_size.attr, - &uvcg_frame_dw_default_frame_interval.attr, - &uvcg_frame_dw_frame_interval.attr, + &uvcg_frame_attr_bm_capabilities, + &uvcg_frame_attr_w_width, + &uvcg_frame_attr_w_height, + &uvcg_frame_attr_dw_min_bit_rate, + &uvcg_frame_attr_dw_max_bit_rate, + &uvcg_frame_attr_dw_max_video_frame_buffer_size, + &uvcg_frame_attr_dw_default_frame_interval, + &uvcg_frame_attr_dw_frame_interval, NULL, }; static struct config_item_type uvcg_frame_type = { - .ct_item_ops = &uvcg_frame_item_ops, .ct_attrs = uvcg_frame_attrs, .ct_owner = THIS_MODULE, }; @@ -1333,22 +1275,15 @@ static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) struct uvcg_uncompressed, fmt); } -CONFIGFS_ATTR_STRUCT(uvcg_uncompressed); -CONFIGFS_ATTR_OPS(uvcg_uncompressed); - -static struct configfs_item_operations uvcg_uncompressed_item_ops = { - .show_attribute = uvcg_uncompressed_attr_show, - .store_attribute = uvcg_uncompressed_attr_store, -}; - static struct configfs_group_operations uvcg_uncompressed_group_ops = { .make_item = uvcg_frame_make, .drop_item = uvcg_frame_drop, }; -static ssize_t uvcg_uncompressed_guid_format_show(struct uvcg_uncompressed *ch, +static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, char *page) { + struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); struct f_uvc_opts *opts; struct config_item *opts_item; struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; @@ -1367,9 +1302,10 @@ static ssize_t uvcg_uncompressed_guid_format_show(struct uvcg_uncompressed *ch, return sizeof(ch->desc.guidFormat); } -static ssize_t uvcg_uncompressed_guid_format_store(struct uvcg_uncompressed *ch, +static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, const char *page, size_t len) { + struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); struct f_uvc_opts *opts; struct config_item *opts_item; struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; @@ -1396,16 +1332,13 @@ end: return ret; } -static struct uvcg_uncompressed_attribute uvcg_uncompressed_guid_format = - __CONFIGFS_ATTR(guidFormat, S_IRUGO | S_IWUSR, - uvcg_uncompressed_guid_format_show, - uvcg_uncompressed_guid_format_store); - +UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv) \ static ssize_t uvcg_uncompressed_##cname##_show( \ - struct uvcg_uncompressed *u, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ @@ -1424,14 +1357,13 @@ static ssize_t uvcg_uncompressed_##cname##_show( \ return result; \ } \ \ -static struct uvcg_uncompressed_attribute \ - uvcg_uncompressed_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_uncompressed_##cname##_show) +UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv) \ static ssize_t uvcg_uncompressed_##cname##_show( \ - struct uvcg_uncompressed *u, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ @@ -1451,9 +1383,10 @@ static ssize_t uvcg_uncompressed_##cname##_show( \ } \ \ static ssize_t \ -uvcg_uncompressed_##cname##_store(struct uvcg_uncompressed *u, \ +uvcg_uncompressed_##cname##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ @@ -1487,11 +1420,7 @@ end: \ return ret; \ } \ \ -static struct uvcg_uncompressed_attribute \ - uvcg_uncompressed_##cname = \ - __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ - uvcg_uncompressed_##cname##_show, \ - uvcg_uncompressed_##cname##_store) +UVC_ATTR(uvcg_uncompressed_, cname, aname); #define identity_conv(x) (x) @@ -1508,36 +1437,34 @@ UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); #undef UVCG_UNCOMPRESSED_ATTR_RO static inline ssize_t -uvcg_uncompressed_bma_controls_show(struct uvcg_uncompressed *unc, char *page) +uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page) { + struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); return uvcg_format_bma_controls_show(&unc->fmt, page); } static inline ssize_t -uvcg_uncompressed_bma_controls_store(struct uvcg_uncompressed *ch, +uvcg_uncompressed_bma_controls_store(struct config_item *item, const char *page, size_t len) { - return uvcg_format_bma_controls_store(&ch->fmt, page, len); + struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); + return uvcg_format_bma_controls_store(&unc->fmt, page, len); } -static struct uvcg_uncompressed_attribute uvcg_uncompressed_bma_controls = - __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR, - uvcg_uncompressed_bma_controls_show, - uvcg_uncompressed_bma_controls_store); +UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls); static struct configfs_attribute *uvcg_uncompressed_attrs[] = { - &uvcg_uncompressed_guid_format.attr, - &uvcg_uncompressed_b_bits_per_pixel.attr, - &uvcg_uncompressed_b_default_frame_index.attr, - &uvcg_uncompressed_b_aspect_ratio_x.attr, - &uvcg_uncompressed_b_aspect_ratio_y.attr, - &uvcg_uncompressed_bm_interface_flags.attr, - &uvcg_uncompressed_bma_controls.attr, + &uvcg_uncompressed_attr_guid_format, + &uvcg_uncompressed_attr_b_bits_per_pixel, + &uvcg_uncompressed_attr_b_default_frame_index, + &uvcg_uncompressed_attr_b_aspect_ratio_x, + &uvcg_uncompressed_attr_b_aspect_ratio_y, + &uvcg_uncompressed_attr_bm_interface_flags, + &uvcg_uncompressed_attr_bma_controls, NULL, }; static struct config_item_type uvcg_uncompressed_type = { - .ct_item_ops = &uvcg_uncompressed_item_ops, .ct_group_ops = &uvcg_uncompressed_group_ops, .ct_attrs = uvcg_uncompressed_attrs, .ct_owner = THIS_MODULE, @@ -1605,22 +1532,15 @@ static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) struct uvcg_mjpeg, fmt); } -CONFIGFS_ATTR_STRUCT(uvcg_mjpeg); -CONFIGFS_ATTR_OPS(uvcg_mjpeg); - -static struct configfs_item_operations uvcg_mjpeg_item_ops = { - .show_attribute = uvcg_mjpeg_attr_show, - .store_attribute = uvcg_mjpeg_attr_store, -}; - static struct configfs_group_operations uvcg_mjpeg_group_ops = { .make_item = uvcg_frame_make, .drop_item = uvcg_frame_drop, }; #define UVCG_MJPEG_ATTR_RO(cname, aname, conv) \ -static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\ +static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ { \ + struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ @@ -1639,13 +1559,12 @@ static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\ return result; \ } \ \ -static struct uvcg_mjpeg_attribute \ - uvcg_mjpeg_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_mjpeg_##cname##_show) +UVC_ATTR_RO(uvcg_mjpeg_, cname, aname) #define UVCG_MJPEG_ATTR(cname, aname, conv) \ -static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\ +static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ { \ + struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ @@ -1665,9 +1584,10 @@ static ssize_t uvcg_mjpeg_##cname##_show(struct uvcg_mjpeg *u, char *page)\ } \ \ static ssize_t \ -uvcg_mjpeg_##cname##_store(struct uvcg_mjpeg *u, \ +uvcg_mjpeg_##cname##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ @@ -1701,11 +1621,7 @@ end: \ return ret; \ } \ \ -static struct uvcg_mjpeg_attribute \ - uvcg_mjpeg_##cname = \ - __CONFIGFS_ATTR(aname, S_IRUGO | S_IWUSR, \ - uvcg_mjpeg_##cname##_show, \ - uvcg_mjpeg_##cname##_store) +UVC_ATTR(uvcg_mjpeg_, cname, aname) #define identity_conv(x) (x) @@ -1722,35 +1638,33 @@ UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); #undef UVCG_MJPEG_ATTR_RO static inline ssize_t -uvcg_mjpeg_bma_controls_show(struct uvcg_mjpeg *unc, char *page) +uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page) { - return uvcg_format_bma_controls_show(&unc->fmt, page); + struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); + return uvcg_format_bma_controls_show(&u->fmt, page); } static inline ssize_t -uvcg_mjpeg_bma_controls_store(struct uvcg_mjpeg *ch, +uvcg_mjpeg_bma_controls_store(struct config_item *item, const char *page, size_t len) { - return uvcg_format_bma_controls_store(&ch->fmt, page, len); + struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); + return uvcg_format_bma_controls_store(&u->fmt, page, len); } -static struct uvcg_mjpeg_attribute uvcg_mjpeg_bma_controls = - __CONFIGFS_ATTR(bmaControls, S_IRUGO | S_IWUSR, - uvcg_mjpeg_bma_controls_show, - uvcg_mjpeg_bma_controls_store); +UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls); static struct configfs_attribute *uvcg_mjpeg_attrs[] = { - &uvcg_mjpeg_b_default_frame_index.attr, - &uvcg_mjpeg_bm_flags.attr, - &uvcg_mjpeg_b_aspect_ratio_x.attr, - &uvcg_mjpeg_b_aspect_ratio_y.attr, - &uvcg_mjpeg_bm_interface_flags.attr, - &uvcg_mjpeg_bma_controls.attr, + &uvcg_mjpeg_attr_b_default_frame_index, + &uvcg_mjpeg_attr_bm_flags, + &uvcg_mjpeg_attr_b_aspect_ratio_x, + &uvcg_mjpeg_attr_b_aspect_ratio_y, + &uvcg_mjpeg_attr_bm_interface_flags, + &uvcg_mjpeg_attr_bma_controls, NULL, }; static struct config_item_type uvcg_mjpeg_type = { - .ct_item_ops = &uvcg_mjpeg_item_ops, .ct_group_ops = &uvcg_mjpeg_group_ops, .ct_attrs = uvcg_mjpeg_attrs, .ct_owner = THIS_MODULE, @@ -1811,17 +1725,12 @@ static inline struct uvcg_default_color_matching struct uvcg_default_color_matching, group); } -CONFIGFS_ATTR_STRUCT(uvcg_default_color_matching); -CONFIGFS_ATTR_OPS_RO(uvcg_default_color_matching); - -static struct configfs_item_operations uvcg_default_color_matching_item_ops = { - .show_attribute = uvcg_default_color_matching_attr_show, -}; - #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv) \ static ssize_t uvcg_default_color_matching_##cname##_show( \ - struct uvcg_default_color_matching *dc, char *page) \ + struct config_item *item, char *page) \ { \ + struct uvcg_default_color_matching *dc = \ + to_uvcg_default_color_matching(item); \ struct f_uvc_opts *opts; \ struct config_item *opts_item; \ struct mutex *su_mutex = &dc->group.cg_subsys->su_mutex; \ @@ -1842,9 +1751,7 @@ static ssize_t uvcg_default_color_matching_##cname##_show( \ return result; \ } \ \ -static struct uvcg_default_color_matching_attribute \ - uvcg_default_color_matching_##cname = \ - __CONFIGFS_ATTR_RO(aname, uvcg_default_color_matching_##cname##_show) +UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname) #define identity_conv(x) (x) @@ -1860,14 +1767,13 @@ UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { - &uvcg_default_color_matching_b_color_primaries.attr, - &uvcg_default_color_matching_b_transfer_characteristics.attr, - &uvcg_default_color_matching_b_matrix_coefficients.attr, + &uvcg_default_color_matching_attr_b_color_primaries, + &uvcg_default_color_matching_attr_b_transfer_characteristics, + &uvcg_default_color_matching_attr_b_matrix_coefficients, NULL, }; static struct config_item_type uvcg_default_color_matching_type = { - .ct_item_ops = &uvcg_default_color_matching_item_ops, .ct_attrs = uvcg_default_color_matching_attrs, .ct_owner = THIS_MODULE, }; @@ -2285,9 +2191,6 @@ static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item) func_inst.group); } -CONFIGFS_ATTR_STRUCT(f_uvc_opts); -CONFIGFS_ATTR_OPS(f_uvc_opts); - static void uvc_attr_release(struct config_item *item) { struct f_uvc_opts *opts = to_f_uvc_opts(item); @@ -2297,14 +2200,13 @@ static void uvc_attr_release(struct config_item *item) static struct configfs_item_operations uvc_item_ops = { .release = uvc_attr_release, - .show_attribute = f_uvc_opts_attr_show, - .store_attribute = f_uvc_opts_attr_store, }; #define UVCG_OPTS_ATTR(cname, conv, str2u, uxx, vnoc, limit) \ static ssize_t f_uvc_opts_##cname##_show( \ - struct f_uvc_opts *opts, char *page) \ + struct config_item *item, char *page) \ { \ + struct f_uvc_opts *opts = to_f_uvc_opts(item); \ int result; \ \ mutex_lock(&opts->lock); \ @@ -2315,9 +2217,10 @@ static ssize_t f_uvc_opts_##cname##_show( \ } \ \ static ssize_t \ -f_uvc_opts_##cname##_store(struct f_uvc_opts *opts, \ +f_uvc_opts_##cname##_store(struct config_item *item, \ const char *page, size_t len) \ { \ + struct f_uvc_opts *opts = to_f_uvc_opts(item); \ int ret; \ uxx num; \ \ @@ -2342,11 +2245,7 @@ end: \ return ret; \ } \ \ -static struct f_uvc_opts_attribute \ - f_uvc_opts_attribute_##cname = \ - __CONFIGFS_ATTR(cname, S_IRUGO | S_IWUSR, \ - f_uvc_opts_##cname##_show, \ - f_uvc_opts_##cname##_store) +UVC_ATTR(f_uvc_opts_, cname, aname) #define identity_conv(x) (x) @@ -2362,9 +2261,9 @@ UVCG_OPTS_ATTR(streaming_maxburst, identity_conv, kstrtou8, u8, identity_conv, #undef UVCG_OPTS_ATTR static struct configfs_attribute *uvc_attrs[] = { - &f_uvc_opts_attribute_streaming_interval.attr, - &f_uvc_opts_attribute_streaming_maxpacket.attr, - &f_uvc_opts_attribute_streaming_maxburst.attr, + &f_uvc_opts_attr_streaming_interval, + &f_uvc_opts_attr_streaming_maxpacket, + &f_uvc_opts_attr_streaming_maxburst, NULL, }; diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index d617c39a0..51d4a1703 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -41,7 +41,7 @@ * videobuf2 queue operations */ -static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, +static int uvc_queue_setup(struct vb2_queue *vq, const void *parg, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]) { @@ -61,9 +61,10 @@ static int uvc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, static int uvc_buffer_prepare(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); - struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); - if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0)) { uvc_trace(UVC_TRACE_CAPTURE, "[E] Bytes used out of bounds.\n"); return -EINVAL; @@ -75,7 +76,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) buf->state = UVC_BUF_STATE_QUEUED; buf->mem = vb2_plane_vaddr(vb, 0); buf->length = vb2_plane_size(vb, 0); - if (vb->v4l2_buf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) buf->bytesused = 0; else buf->bytesused = vb2_get_plane_payload(vb, 0); @@ -86,7 +87,8 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) static void uvc_buffer_queue(struct vb2_buffer *vb) { struct uvc_video_queue *queue = vb2_get_drv_priv(vb->vb2_queue); - struct uvc_buffer *buf = container_of(vb, struct uvc_buffer, buf); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct uvc_buffer *buf = container_of(vbuf, struct uvc_buffer, buf); unsigned long flags; spin_lock_irqsave(&queue->irqlock, flags); @@ -98,7 +100,7 @@ static void uvc_buffer_queue(struct vb2_buffer *vb) * directly. The next QBUF call will fail with -ENODEV. */ buf->state = UVC_BUF_STATE_ERROR; - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); } spin_unlock_irqrestore(&queue->irqlock, flags); @@ -242,7 +244,7 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect) queue); list_del(&buf->queue); buf->state = UVC_BUF_STATE_ERROR; - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR); } /* This must be protected by the irqlock spinlock to avoid race * conditions between uvc_queue_buffer and the disconnection event that @@ -314,7 +316,7 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->length != buf->bytesused) { buf->state = UVC_BUF_STATE_QUEUED; - vb2_set_plane_payload(&buf->buf, 0, 0); + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, 0); return buf; } @@ -325,12 +327,12 @@ struct uvc_buffer *uvcg_queue_next_buffer(struct uvc_video_queue *queue, else nextbuf = NULL; - buf->buf.v4l2_buf.field = V4L2_FIELD_NONE; - buf->buf.v4l2_buf.sequence = queue->sequence++; - v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp); + buf->buf.field = V4L2_FIELD_NONE; + buf->buf.sequence = queue->sequence++; + v4l2_get_timestamp(&buf->buf.timestamp); - vb2_set_plane_payload(&buf->buf, 0, buf->bytesused); - vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE); + vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused); + vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE); return nextbuf; } diff --git a/drivers/usb/gadget/function/uvc_queue.h b/drivers/usb/gadget/function/uvc_queue.h index 01ca9eab3..ac461a9a1 100644 --- a/drivers/usb/gadget/function/uvc_queue.h +++ b/drivers/usb/gadget/function/uvc_queue.h @@ -6,7 +6,7 @@ #include <linux/kernel.h> #include <linux/poll.h> #include <linux/videodev2.h> -#include <media/videobuf2-core.h> +#include <media/videobuf2-v4l2.h> /* Maximum frame size in bytes, for sanity checking. */ #define UVC_MAX_FRAME_SIZE (16*1024*1024) @@ -26,7 +26,7 @@ enum uvc_buffer_state { }; struct uvc_buffer { - struct vb2_buffer buf; + struct vb2_v4l2_buffer buf; struct list_head queue; enum uvc_buffer_state state; diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 5231a32ae..99ca3dabc 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -79,10 +79,7 @@ static int dbgp_consume(char *buf, unsigned len) static void __disable_ep(struct usb_ep *ep) { - if (ep && ep->driver_data == dbgp.gadget) { - usb_ep_disable(ep); - ep->driver_data = NULL; - } + usb_ep_disable(ep); } static void dbgp_disable_ep(void) @@ -171,7 +168,6 @@ static int __enable_ep(struct usb_ep *ep, struct usb_endpoint_descriptor *desc) int err; ep->desc = desc; err = usb_ep_enable(ep); - ep->driver_data = dbgp.gadget; return err; } @@ -229,8 +225,6 @@ static void dbgp_unbind(struct usb_gadget *gadget) usb_ep_free_request(gadget->ep0, dbgp.req); dbgp.req = NULL; } - - gadget->ep0->driver_data = NULL; } #ifdef CONFIG_USB_G_DBGP_SERIAL @@ -249,18 +243,15 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget) goto fail_1; } - dbgp.i_ep->driver_data = gadget; i_desc.wMaxPacketSize = cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); dbgp.o_ep = usb_ep_autoconfig(gadget, &o_desc); if (!dbgp.o_ep) { - dbgp.i_ep->driver_data = NULL; stp = 2; - goto fail_2; + goto fail_1; } - dbgp.o_ep->driver_data = gadget; o_desc.wMaxPacketSize = cpu_to_le16(USB_DEBUG_MAX_PACKET_SIZE); @@ -277,8 +268,6 @@ static int dbgp_configure_endpoints(struct usb_gadget *gadget) return 0; -fail_2: - dbgp.i_ep->driver_data = NULL; fail_1: dev_dbg(&dbgp.gadget->dev, "ep config: failure (%d)\n", stp); return -ENODEV; @@ -306,7 +295,6 @@ static int dbgp_bind(struct usb_gadget *gadget, } dbgp.req->length = DBGP_REQ_EP0_LEN; - gadget->ep0->driver_data = gadget; #ifdef CONFIG_USB_G_DBGP_SERIAL dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); @@ -356,8 +344,6 @@ static int dbgp_setup(struct usb_gadget *gadget, void *data = NULL; u16 len = 0; - gadget->ep0->driver_data = gadget; - if (request == USB_REQ_GET_DESCRIPTOR) { switch (value>>8) { case USB_DT_DEVICE: diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index c3c48088f..22e56158d 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -19,8 +19,6 @@ #include <scsi/scsi_tcq.h> #include <target/target_core_base.h> #include <target/target_core_fabric.h> -#include <target/target_core_fabric_configfs.h> -#include <target/configfs_macros.h> #include <asm/unaligned.h> #include "tcm_usb_gadget.h" @@ -1467,23 +1465,21 @@ static void usbg_drop_tport(struct se_wwn *wwn) /* * If somebody feels like dropping the version property, go ahead. */ -static ssize_t usbg_wwn_show_attr_version( - struct target_fabric_configfs *tf, - char *page) +static ssize_t usbg_wwn_version_show(struct config_item *item, char *page) { return sprintf(page, "usb-gadget fabric module\n"); } -TF_WWN_ATTR_RO(usbg, version); + +CONFIGFS_ATTR_RO(usbg_wwn_, version); static struct configfs_attribute *usbg_wwn_attrs[] = { - &usbg_wwn_version.attr, + &usbg_wwn_attr_version, NULL, }; -static ssize_t tcm_usbg_tpg_show_enable( - struct se_portal_group *se_tpg, - char *page) +static ssize_t tcm_usbg_tpg_enable_show(struct config_item *item, char *page) { + struct se_portal_group *se_tpg = to_tpg(item); struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); return snprintf(page, PAGE_SIZE, "%u\n", tpg->gadget_connect); @@ -1492,11 +1488,10 @@ static ssize_t tcm_usbg_tpg_show_enable( static int usbg_attach(struct usbg_tpg *); static void usbg_detach(struct usbg_tpg *); -static ssize_t tcm_usbg_tpg_store_enable( - struct se_portal_group *se_tpg, - const char *page, - size_t count) +static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item, + const char *page, size_t count) { + struct se_portal_group *se_tpg = to_tpg(item); struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); unsigned long op; ssize_t ret; @@ -1523,12 +1518,10 @@ static ssize_t tcm_usbg_tpg_store_enable( out: return count; } -TF_TPG_BASE_ATTR(tcm_usbg, enable, S_IRUGO | S_IWUSR); -static ssize_t tcm_usbg_tpg_show_nexus( - struct se_portal_group *se_tpg, - char *page) +static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page) { + struct se_portal_group *se_tpg = to_tpg(item); struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); struct tcm_usbg_nexus *tv_nexus; ssize_t ret; @@ -1636,11 +1629,10 @@ out: return ret; } -static ssize_t tcm_usbg_tpg_store_nexus( - struct se_portal_group *se_tpg, - const char *page, - size_t count) +static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item, + const char *page, size_t count) { + struct se_portal_group *se_tpg = to_tpg(item); struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); unsigned char i_port[USBG_NAMELEN], *ptr; int ret; @@ -1670,11 +1662,13 @@ static ssize_t tcm_usbg_tpg_store_nexus( return ret; return count; } -TF_TPG_BASE_ATTR(tcm_usbg, nexus, S_IRUGO | S_IWUSR); + +CONFIGFS_ATTR(tcm_usbg_tpg_, enable); +CONFIGFS_ATTR(tcm_usbg_tpg_, nexus); static struct configfs_attribute *usbg_base_attrs[] = { - &tcm_usbg_tpg_enable.attr, - &tcm_usbg_tpg_nexus.attr, + &tcm_usbg_tpg_attr_enable, + &tcm_usbg_tpg_attr_nexus, NULL, }; @@ -2018,14 +2012,6 @@ static struct usb_configuration usbg_config_driver = { .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; -static void give_back_ep(struct usb_ep **pep) -{ - struct usb_ep *ep = *pep; - if (!ep) - return; - ep->driver_data = NULL; -} - static int usbg_bind(struct usb_configuration *c, struct usb_function *f) { struct f_uas *fu = to_f_uas(f); @@ -2045,29 +2031,24 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) &uasp_bi_ep_comp_desc); if (!ep) goto ep_fail; - - ep->driver_data = fu; fu->ep_in = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc, &uasp_bo_ep_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_out = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc, &uasp_status_in_ep_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_status = ep; ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc, &uasp_cmd_comp_desc); if (!ep) goto ep_fail; - ep->driver_data = fu; fu->ep_cmd = ep; /* Assume endpoint addresses are the same for both speeds */ @@ -2091,11 +2072,6 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f) return 0; ep_fail: pr_err("Can't claim all required eps\n"); - - give_back_ep(&fu->ep_in); - give_back_ep(&fu->ep_out); - give_back_ep(&fu->ep_status); - give_back_ep(&fu->ep_cmd); return -ENOTSUPP; } diff --git a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig index 9a3a6b003..cdbff54e0 100644 --- a/drivers/usb/gadget/udc/Kconfig +++ b/drivers/usb/gadget/udc/Kconfig @@ -55,7 +55,7 @@ config USB_LPC32XX config USB_ATMEL_USBA tristate "Atmel USBA" - depends on AVR32 || ARCH_AT91 + depends on ((AVR32 && !OF) || ARCH_AT91) help USBA is the integrated high-speed USB Device controller on the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel. diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index 175ca93fe..cd8764150 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -65,18 +65,10 @@ static void udc_tasklet_disconnect(unsigned long); static void empty_req_queue(struct udc_ep *); -static int udc_probe(struct udc *dev); -static void udc_basic_init(struct udc *dev); static void udc_setup_endpoints(struct udc *dev); static void udc_soft_reset(struct udc *dev); static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); -static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags); -static int udc_remote_wakeup(struct udc *dev); -static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); -static void udc_pci_remove(struct pci_dev *pdev); /* description */ static const char mod_desc[] = UDC_MOD_DESCRIPTION; @@ -615,6 +607,30 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) return &req->req; } +/* frees pci pool descriptors of a DMA chain */ +static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) +{ + int ret_val = 0; + struct udc_data_dma *td; + struct udc_data_dma *td_last = NULL; + unsigned int i; + + DBG(dev, "free chain req = %p\n", req); + + /* do not free first desc., will be done by free for request */ + td_last = req->td_data; + td = phys_to_virt(td_last->next); + + for (i = 1; i < req->chain_len; i++) { + pci_pool_free(dev->data_requests, td, + (dma_addr_t)td_last->next); + td_last = td; + td = phys_to_virt(td_last->next); + } + + return ret_val; +} + /* Frees request packet, called by gadget driver */ static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) @@ -789,6 +805,123 @@ udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) return finished; } +/* Creates or re-inits a DMA chain */ +static int udc_create_dma_chain( + struct udc_ep *ep, + struct udc_request *req, + unsigned long buf_len, gfp_t gfp_flags +) +{ + unsigned long bytes = req->req.length; + unsigned int i; + dma_addr_t dma_addr; + struct udc_data_dma *td = NULL; + struct udc_data_dma *last = NULL; + unsigned long txbytes; + unsigned create_new_chain = 0; + unsigned len; + + VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", + bytes, buf_len); + dma_addr = DMA_DONT_USE; + + /* unset L bit in first desc for OUT */ + if (!ep->in) + req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); + + /* alloc only new desc's if not already available */ + len = req->req.length / ep->ep.maxpacket; + if (req->req.length % ep->ep.maxpacket) + len++; + + if (len > req->chain_len) { + /* shorter chain already allocated before */ + if (req->chain_len > 1) + udc_free_dma_chain(ep->dev, req); + req->chain_len = len; + create_new_chain = 1; + } + + td = req->td_data; + /* gen. required number of descriptors and buffers */ + for (i = buf_len; i < bytes; i += buf_len) { + /* create or determine next desc. */ + if (create_new_chain) { + td = pci_pool_alloc(ep->dev->data_requests, + gfp_flags, &dma_addr); + if (!td) + return -ENOMEM; + + td->status = 0; + } else if (i == buf_len) { + /* first td */ + td = (struct udc_data_dma *)phys_to_virt( + req->td_data->next); + td->status = 0; + } else { + td = (struct udc_data_dma *)phys_to_virt(last->next); + td->status = 0; + } + + if (td) + td->bufptr = req->req.dma + i; /* assign buffer */ + else + break; + + /* short packet ? */ + if ((bytes - i) >= buf_len) { + txbytes = buf_len; + } else { + /* short packet */ + txbytes = bytes - i; + } + + /* link td and assign tx bytes */ + if (i == buf_len) { + if (create_new_chain) + req->td_data->next = dma_addr; + /* + * else + * req->td_data->next = virt_to_phys(td); + */ + /* write tx bytes */ + if (ep->in) { + /* first desc */ + req->td_data->status = + AMD_ADDBITS(req->td_data->status, + ep->ep.maxpacket, + UDC_DMA_IN_STS_TXBYTES); + /* second desc */ + td->status = AMD_ADDBITS(td->status, + txbytes, + UDC_DMA_IN_STS_TXBYTES); + } + } else { + if (create_new_chain) + last->next = dma_addr; + /* + * else + * last->next = virt_to_phys(td); + */ + if (ep->in) { + /* write tx bytes */ + td->status = AMD_ADDBITS(td->status, + txbytes, + UDC_DMA_IN_STS_TXBYTES); + } + } + last = td; + } + /* set last bit */ + if (td) { + td->status |= AMD_BIT(UDC_DMA_IN_STS_L); + /* last desc. points to itself */ + req->td_data_last = td; + } + + return 0; +} + /* create/re-init a DMA descriptor or a DMA descriptor chain */ static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) { @@ -913,32 +1046,6 @@ __acquires(ep->dev->lock) ep->halted = halted; } -/* frees pci pool descriptors of a DMA chain */ -static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) -{ - - int ret_val = 0; - struct udc_data_dma *td; - struct udc_data_dma *td_last = NULL; - unsigned int i; - - DBG(dev, "free chain req = %p\n", req); - - /* do not free first desc., will be done by free for request */ - td_last = req->td_data; - td = phys_to_virt(td_last->next); - - for (i = 1; i < req->chain_len; i++) { - - pci_pool_free(dev->data_requests, td, - (dma_addr_t) td_last->next); - td_last = td; - td = phys_to_virt(td_last->next); - } - - return ret_val; -} - /* Iterates to the end of a DMA chain and returns last descriptor */ static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) { @@ -975,125 +1082,6 @@ static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) } -/* Creates or re-inits a DMA chain */ -static int udc_create_dma_chain( - struct udc_ep *ep, - struct udc_request *req, - unsigned long buf_len, gfp_t gfp_flags -) -{ - unsigned long bytes = req->req.length; - unsigned int i; - dma_addr_t dma_addr; - struct udc_data_dma *td = NULL; - struct udc_data_dma *last = NULL; - unsigned long txbytes; - unsigned create_new_chain = 0; - unsigned len; - - VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", - bytes, buf_len); - dma_addr = DMA_DONT_USE; - - /* unset L bit in first desc for OUT */ - if (!ep->in) - req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); - - /* alloc only new desc's if not already available */ - len = req->req.length / ep->ep.maxpacket; - if (req->req.length % ep->ep.maxpacket) - len++; - - if (len > req->chain_len) { - /* shorter chain already allocated before */ - if (req->chain_len > 1) - udc_free_dma_chain(ep->dev, req); - req->chain_len = len; - create_new_chain = 1; - } - - td = req->td_data; - /* gen. required number of descriptors and buffers */ - for (i = buf_len; i < bytes; i += buf_len) { - /* create or determine next desc. */ - if (create_new_chain) { - - td = pci_pool_alloc(ep->dev->data_requests, - gfp_flags, &dma_addr); - if (!td) - return -ENOMEM; - - td->status = 0; - } else if (i == buf_len) { - /* first td */ - td = (struct udc_data_dma *) phys_to_virt( - req->td_data->next); - td->status = 0; - } else { - td = (struct udc_data_dma *) phys_to_virt(last->next); - td->status = 0; - } - - - if (td) - td->bufptr = req->req.dma + i; /* assign buffer */ - else - break; - - /* short packet ? */ - if ((bytes - i) >= buf_len) { - txbytes = buf_len; - } else { - /* short packet */ - txbytes = bytes - i; - } - - /* link td and assign tx bytes */ - if (i == buf_len) { - if (create_new_chain) - req->td_data->next = dma_addr; - /* - else - req->td_data->next = virt_to_phys(td); - */ - /* write tx bytes */ - if (ep->in) { - /* first desc */ - req->td_data->status = - AMD_ADDBITS(req->td_data->status, - ep->ep.maxpacket, - UDC_DMA_IN_STS_TXBYTES); - /* second desc */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } else { - if (create_new_chain) - last->next = dma_addr; - /* - else - last->next = virt_to_phys(td); - */ - if (ep->in) { - /* write tx bytes */ - td->status = AMD_ADDBITS(td->status, - txbytes, - UDC_DMA_IN_STS_TXBYTES); - } - } - last = td; - } - /* set last bit */ - if (td) { - td->status |= AMD_BIT(UDC_DMA_IN_STS_L); - /* last desc. points to itself */ - req->td_data_last = td; - } - - return 0; -} - /* Enabling RX DMA */ static void udc_set_rde(struct udc *dev) { @@ -1453,6 +1441,26 @@ static int udc_get_frame(struct usb_gadget *gadget) return -EOPNOTSUPP; } +/* Initiates a remote wakeup */ +static int udc_remote_wakeup(struct udc *dev) +{ + unsigned long flags; + u32 tmp; + + DBG(dev, "UDC initiates remote wakeup\n"); + + spin_lock_irqsave(&dev->lock, flags); + + tmp = readl(&dev->regs->ctl); + tmp |= AMD_BIT(UDC_DEVCTL_RES); + writel(tmp, &dev->regs->ctl); + tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); + writel(tmp, &dev->regs->ctl); + + spin_unlock_irqrestore(&dev->lock, flags); + return 0; +} + /* Remote wakeup gadget interface */ static int udc_wakeup(struct usb_gadget *gadget) { @@ -1498,33 +1506,6 @@ static void make_ep_lists(struct udc *dev) dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; } -/* init registers at driver load time */ -static int startup_registers(struct udc *dev) -{ - u32 tmp; - - /* init controller by soft reset */ - udc_soft_reset(dev); - - /* mask not needed interrupts */ - udc_mask_unused_interrupts(dev); - - /* put into initial config */ - udc_basic_init(dev); - /* link up all endpoints */ - udc_setup_endpoints(dev); - - /* program speed */ - tmp = readl(&dev->regs->cfg); - if (use_fullspeed) - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); - else - tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); - writel(tmp, &dev->regs->cfg); - - return 0; -} - /* Inits UDC context */ static void udc_basic_init(struct udc *dev) { @@ -1563,6 +1544,33 @@ static void udc_basic_init(struct udc *dev) dev->data_ep_queued = 0; } +/* init registers at driver load time */ +static int startup_registers(struct udc *dev) +{ + u32 tmp; + + /* init controller by soft reset */ + udc_soft_reset(dev); + + /* mask not needed interrupts */ + udc_mask_unused_interrupts(dev); + + /* put into initial config */ + udc_basic_init(dev); + /* link up all endpoints */ + udc_setup_endpoints(dev); + + /* program speed */ + tmp = readl(&dev->regs->cfg); + if (use_fullspeed) + tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); + else + tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); + writel(tmp, &dev->regs->cfg); + + return 0; +} + /* Sets initial endpoint parameters */ static void udc_setup_endpoints(struct udc *dev) { @@ -2177,7 +2185,7 @@ static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) } /* DMA */ - } else if (!ep->cancel_transfer && req != NULL) { + } else if (!ep->cancel_transfer && req) { ret_val = IRQ_HANDLED; /* check for DMA done */ @@ -3107,6 +3115,17 @@ static void udc_remove(struct udc *dev) udc = NULL; } +/* free all the dma pools */ +static void free_dma_pools(struct udc *dev) +{ + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td, + dev->ep[UDC_EP0OUT_IX].td_phys); + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp, + dev->ep[UDC_EP0OUT_IX].td_stp_dma); + dma_pool_destroy(dev->stp_requests); + dma_pool_destroy(dev->data_requests); +} + /* Reset all pci context */ static void udc_pci_remove(struct pci_dev *pdev) { @@ -3116,35 +3135,19 @@ static void udc_pci_remove(struct pci_dev *pdev) usb_del_gadget_udc(&udc->gadget); /* gadget driver must not be registered */ - BUG_ON(dev->driver != NULL); + if (WARN_ON(dev->driver)) + return; /* dma pool cleanup */ - if (dev->data_requests) - pci_pool_destroy(dev->data_requests); - - if (dev->stp_requests) { - /* cleanup DMA desc's for ep0in */ - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td_stp, - dev->ep[UDC_EP0OUT_IX].td_stp_dma); - pci_pool_free(dev->stp_requests, - dev->ep[UDC_EP0OUT_IX].td, - dev->ep[UDC_EP0OUT_IX].td_phys); - - pci_pool_destroy(dev->stp_requests); - } + free_dma_pools(dev); /* reset controller */ writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); - if (dev->irq_registered) - free_irq(pdev->irq, dev); - if (dev->virt_addr) - iounmap(dev->virt_addr); - if (dev->mem_region) - release_mem_region(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); - if (dev->active) - pci_disable_device(pdev); + free_irq(pdev->irq, dev); + iounmap(dev->virt_addr); + release_mem_region(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + pci_disable_device(pdev); udc_remove(dev); } @@ -3169,8 +3172,7 @@ static int init_dma_pools(struct udc *dev) sizeof(struct udc_data_dma), 0, 0); if (!dev->data_requests) { DBG(dev, "can't get request data pool\n"); - retval = -ENOMEM; - goto finished; + return -ENOMEM; } /* EP0 in dma regs = dev control regs */ @@ -3182,27 +3184,101 @@ static int init_dma_pools(struct udc *dev) if (!dev->stp_requests) { DBG(dev, "can't get stp request pool\n"); retval = -ENOMEM; - goto finished; + goto err_create_dma_pool; } /* setup */ td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_stp_dma); - if (td_stp == NULL) { + if (!td_stp) { retval = -ENOMEM; - goto finished; + goto err_alloc_dma; } dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; /* data: 0 packets !? */ td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, &dev->ep[UDC_EP0OUT_IX].td_phys); - if (td_data == NULL) { + if (!td_data) { retval = -ENOMEM; - goto finished; + goto err_alloc_phys; } dev->ep[UDC_EP0OUT_IX].td = td_data; return 0; +err_alloc_phys: + dma_pool_free(dev->stp_requests, dev->ep[UDC_EP0OUT_IX].td_stp, + dev->ep[UDC_EP0OUT_IX].td_stp_dma); +err_alloc_dma: + dma_pool_destroy(dev->stp_requests); + dev->stp_requests = NULL; +err_create_dma_pool: + dma_pool_destroy(dev->data_requests); + dev->data_requests = NULL; + return retval; +} + +/* general probe */ +static int udc_probe(struct udc *dev) +{ + char tmp[128]; + u32 reg; + int retval; + + /* mark timer as not initialized */ + udc_timer.data = 0; + udc_pollstall_timer.data = 0; + + /* device struct setup */ + dev->gadget.ops = &udc_ops; + + dev_set_name(&dev->gadget.dev, "gadget"); + dev->gadget.name = name; + dev->gadget.max_speed = USB_SPEED_HIGH; + + /* init registers, interrupts, ... */ + startup_registers(dev); + + dev_info(&dev->pdev->dev, "%s\n", mod_desc); + + snprintf(tmp, sizeof(tmp), "%d", dev->irq); + dev_info(&dev->pdev->dev, + "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", + tmp, dev->phys_addr, dev->chiprev, + (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); + strcpy(tmp, UDC_DRIVER_VERSION_STRING); + if (dev->chiprev == UDC_HSA0_REV) { + dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); + retval = -ENODEV; + goto finished; + } + dev_info(&dev->pdev->dev, + "driver version: %s(for Geode5536 B1)\n", tmp); + udc = dev; + + retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, + gadget_release); + if (retval) + goto finished; + + /* timer init */ + init_timer(&udc_timer); + udc_timer.function = udc_timer_function; + udc_timer.data = 1; + /* timer pollstall init */ + init_timer(&udc_pollstall_timer); + udc_pollstall_timer.function = udc_pollstall_timer_function; + udc_pollstall_timer.data = 1; + + /* set SD */ + reg = readl(&dev->regs->ctl); + reg |= AMD_BIT(UDC_DEVCTL_SD); + writel(reg, &dev->regs->ctl); + + /* print dev register info */ + print_regs(dev); + + return 0; + finished: return retval; } @@ -3234,7 +3310,6 @@ static int udc_pci_probe( retval = -ENODEV; goto err_pcidev; } - dev->active = 1; /* PCI resource allocation */ resource = pci_resource_start(pdev, 0); @@ -3245,10 +3320,9 @@ static int udc_pci_probe( retval = -EBUSY; goto err_memreg; } - dev->mem_region = 1; dev->virt_addr = ioremap_nocache(resource, len); - if (dev->virt_addr == NULL) { + if (!dev->virt_addr) { dev_dbg(&pdev->dev, "start address cannot be mapped\n"); retval = -EFAULT; goto err_ioremap; @@ -3276,7 +3350,6 @@ static int udc_pci_probe( retval = -EBUSY; goto err_irq; } - dev->irq_registered = 1; pci_set_drvdata(pdev, dev); @@ -3290,7 +3363,7 @@ static int udc_pci_probe( if (use_dma) { retval = init_dma_pools(dev); if (retval != 0) - goto finished; + goto err_dma; } dev->phys_addr = resource; @@ -3298,13 +3371,17 @@ static int udc_pci_probe( dev->pdev = pdev; /* general probing */ - if (udc_probe(dev) == 0) - return 0; - -finished: - udc_pci_remove(pdev); - return retval; + if (udc_probe(dev)) { + retval = -ENODEV; + goto err_probe; + } + return 0; +err_probe: + if (use_dma) + free_dma_pools(dev); +err_dma: + free_irq(pdev->irq, dev); err_irq: iounmap(dev->virt_addr); err_ioremap: @@ -3316,92 +3393,6 @@ err_pcidev: return retval; } -/* general probe */ -static int udc_probe(struct udc *dev) -{ - char tmp[128]; - u32 reg; - int retval; - - /* mark timer as not initialized */ - udc_timer.data = 0; - udc_pollstall_timer.data = 0; - - /* device struct setup */ - dev->gadget.ops = &udc_ops; - - dev_set_name(&dev->gadget.dev, "gadget"); - dev->gadget.name = name; - dev->gadget.max_speed = USB_SPEED_HIGH; - - /* init registers, interrupts, ... */ - startup_registers(dev); - - dev_info(&dev->pdev->dev, "%s\n", mod_desc); - - snprintf(tmp, sizeof tmp, "%d", dev->irq); - dev_info(&dev->pdev->dev, - "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", - tmp, dev->phys_addr, dev->chiprev, - (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); - strcpy(tmp, UDC_DRIVER_VERSION_STRING); - if (dev->chiprev == UDC_HSA0_REV) { - dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); - retval = -ENODEV; - goto finished; - } - dev_info(&dev->pdev->dev, - "driver version: %s(for Geode5536 B1)\n", tmp); - udc = dev; - - retval = usb_add_gadget_udc_release(&udc->pdev->dev, &dev->gadget, - gadget_release); - if (retval) - goto finished; - - /* timer init */ - init_timer(&udc_timer); - udc_timer.function = udc_timer_function; - udc_timer.data = 1; - /* timer pollstall init */ - init_timer(&udc_pollstall_timer); - udc_pollstall_timer.function = udc_pollstall_timer_function; - udc_pollstall_timer.data = 1; - - /* set SD */ - reg = readl(&dev->regs->ctl); - reg |= AMD_BIT(UDC_DEVCTL_SD); - writel(reg, &dev->regs->ctl); - - /* print dev register info */ - print_regs(dev); - - return 0; - -finished: - return retval; -} - -/* Initiates a remote wakeup */ -static int udc_remote_wakeup(struct udc *dev) -{ - unsigned long flags; - u32 tmp; - - DBG(dev, "UDC initiates remote wakeup\n"); - - spin_lock_irqsave(&dev->lock, flags); - - tmp = readl(&dev->regs->ctl); - tmp |= AMD_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); - writel(tmp, &dev->regs->ctl); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} - /* PCI device parameters */ static const struct pci_device_id pci_id[] = { { diff --git a/drivers/usb/gadget/udc/amd5536udc.h b/drivers/usb/gadget/udc/amd5536udc.h index 6744d3b83..4638d707f 100644 --- a/drivers/usb/gadget/udc/amd5536udc.h +++ b/drivers/usb/gadget/udc/amd5536udc.h @@ -526,14 +526,11 @@ struct udc { struct udc_ep ep[UDC_EP_NUM]; struct usb_gadget_driver *driver; /* operational flags */ - unsigned active : 1, - stall_ep0in : 1, + unsigned stall_ep0in : 1, waiting_zlp_ack_ep0in : 1, set_cfg_not_acked : 1, - irq_registered : 1, data_ep_enabled : 1, data_ep_queued : 1, - mem_region : 1, sys_suspended : 1, connected; diff --git a/drivers/usb/gadget/udc/at91_udc.h b/drivers/usb/gadget/udc/at91_udc.h index 2679c8b21..0a433e6b3 100644 --- a/drivers/usb/gadget/udc/at91_udc.h +++ b/drivers/usb/gadget/udc/at91_udc.h @@ -112,6 +112,14 @@ struct at91_udc_caps { void (*pullup)(struct at91_udc *udc, int is_on); }; +struct at91_udc_data { + int vbus_pin; /* high == host powering us */ + u8 vbus_active_low; /* vbus polarity */ + u8 vbus_polled; /* Use polling, not interrupt */ + int pullup_pin; /* active == D+ pulled up */ + u8 pullup_active_low; /* true == pullup_pin is active low */ +}; + /* * driver is non-SMP, and just blocks IRQs whenever it needs * access protection for chip registers or driver state diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 27af0f008..dde44450d 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -833,10 +833,10 @@ static const struct usb_ep_ops dummy_ep_ops = { /* there are both host and device side versions of this call ... */ static int dummy_g_get_frame(struct usb_gadget *_gadget) { - struct timeval tv; + struct timespec64 ts64; - do_gettimeofday(&tv); - return tv.tv_usec / 1000; + ktime_get_ts64(&ts64); + return ts64.tv_nsec / NSEC_PER_MSEC; } static int dummy_wakeup(struct usb_gadget *_gadget) diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index e5f4c5274..7a04157ff 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -330,7 +330,7 @@ struct pch_vbus_gpio_data { * @prot_stall: protcol stall requested * @irq_registered: irq registered with system * @mem_region: device memory mapped - * @registered: driver regsitered with system + * @registered: driver registered with system * @suspended: driver in suspended state * @connected: gadget driver associated * @vbus_session: required vbus_session state @@ -2747,18 +2747,18 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_US) { if (dev->driver && dev->driver->suspend) { - spin_lock(&dev->lock); - dev->driver->suspend(&dev->gadget); spin_unlock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_lock(&dev->lock); } vbus = pch_vbus_gpio_get_value(dev); if ((dev->vbus_session == 0) && (vbus != 1)) { if (dev->driver && dev->driver->disconnect) { - spin_lock(&dev->lock); - dev->driver->disconnect(&dev->gadget); spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); } pch_udc_reconnect(dev); } else if ((dev->vbus_session == 0) diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 670ac0b12..001a3b74a 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -2536,6 +2536,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) udc->pullup_resume = udc->pullup_on; dplus_pullup(udc, 0); + if (udc->driver) + udc->driver->disconnect(&udc->gadget); + return 0; } |