diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-05-15 10:26:50 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2013-05-15 10:26:50 -0400 |
commit | 12e04ffcd93b25dfd726d46338c2ee7d23de556e (patch) | |
tree | f91479a62805619168994fd3ee55e3ffa23fc24e /include/linux/usb/gadget_configfs.h | |
parent | 9eff37a8713939f218ab8bf0dc93f1d67af7b8b4 (diff) | |
parent | f722406faae2d073cc1d01063d1123c35425939e (diff) |
Merge tag 'v3.10-rc1' into stable/for-linus-3.10
Linux 3.10-rc1
* tag 'v3.10-rc1': (12273 commits)
Linux 3.10-rc1
[SCSI] qla2xxx: Update firmware link in Kconfig file.
[SCSI] iscsi class, qla4xxx: fix sess/conn refcounting when find fns are used
[SCSI] sas: unify the pointlessly separated enums sas_dev_type and sas_device_type
[SCSI] pm80xx: thermal, sas controller config and error handling update
[SCSI] pm80xx: NCQ error handling changes
[SCSI] pm80xx: WWN Modification for PM8081/88/89 controllers
[SCSI] pm80xx: Changed module name and debug messages update
[SCSI] pm80xx: Firmware flash memory free fix, with addition of new memory region for it
[SCSI] pm80xx: SPC new firmware changes for device id 0x8081 alone
[SCSI] pm80xx: Added SPCv/ve specific hardware functionalities and relevant changes in common files
[SCSI] pm80xx: MSI-X implementation for using 64 interrupts
[SCSI] pm80xx: Updated common functions common for SPC and SPCv/ve
[SCSI] pm80xx: Multiple inbound/outbound queue configuration
[SCSI] pm80xx: Added SPCv/ve specific ids, variables and modify for SPC
[SCSI] lpfc: fix up Kconfig dependencies
[SCSI] Handle MLQUEUE busy response in scsi_send_eh_cmnd
dm cache: set config value
dm cache: move config fns
dm thin: generate event when metadata threshold passed
...
Diffstat (limited to 'include/linux/usb/gadget_configfs.h')
-rw-r--r-- | include/linux/usb/gadget_configfs.h | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/include/linux/usb/gadget_configfs.h b/include/linux/usb/gadget_configfs.h new file mode 100644 index 00000000000..d74c0ae989d --- /dev/null +++ b/include/linux/usb/gadget_configfs.h @@ -0,0 +1,110 @@ +#ifndef __GADGET_CONFIGFS__ +#define __GADGET_CONFIGFS__ + +#include <linux/configfs.h> + +int check_user_usb_string(const char *name, + struct usb_gadget_strings *stringtab_dev); + +#define GS_STRINGS_W(__struct, __name) \ + static ssize_t __struct##_##__name##_store(struct __struct *gs, \ + const char *page, size_t len) \ +{ \ + int ret; \ + \ + ret = usb_string_copy(page, &gs->__name); \ + if (ret) \ + return ret; \ + return len; \ +} + +#define GS_STRINGS_R(__struct, __name) \ + static ssize_t __struct##_##__name##_show(struct __struct *gs, \ + char *page) \ +{ \ + return sprintf(page, "%s\n", gs->__name ?: ""); \ +} + +#define GS_STRING_ITEM_ATTR(struct_name, name) \ + static struct struct_name##_attribute struct_name##_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ + struct_name##_##name##_show, \ + struct_name##_##name##_store) + +#define GS_STRINGS_RW(struct_name, _name) \ + GS_STRINGS_R(struct_name, _name) \ + GS_STRINGS_W(struct_name, _name) \ + GS_STRING_ITEM_ATTR(struct_name, _name) + +#define USB_CONFIG_STRING_RW_OPS(struct_in) \ + CONFIGFS_ATTR_OPS(struct_in); \ + \ +static struct configfs_item_operations struct_in##_langid_item_ops = { \ + .release = struct_in##_attr_release, \ + .show_attribute = struct_in##_attr_show, \ + .store_attribute = struct_in##_attr_store, \ +}; \ + \ +static struct config_item_type struct_in##_langid_type = { \ + .ct_item_ops = &struct_in##_langid_item_ops, \ + .ct_attrs = struct_in##_langid_attrs, \ + .ct_owner = THIS_MODULE, \ +} + +#define USB_CONFIG_STRINGS_LANG(struct_in, struct_member) \ + static struct config_group *struct_in##_strings_make( \ + struct config_group *group, \ + const char *name) \ + { \ + struct struct_member *gi; \ + struct struct_in *gs; \ + struct struct_in *new; \ + int langs = 0; \ + int ret; \ + \ + new = kzalloc(sizeof(*new), GFP_KERNEL); \ + if (!new) \ + return ERR_PTR(-ENOMEM); \ + \ + ret = check_user_usb_string(name, &new->stringtab_dev); \ + if (ret) \ + goto err; \ + config_group_init_type_name(&new->group, name, \ + &struct_in##_langid_type); \ + \ + gi = container_of(group, struct struct_member, strings_group); \ + ret = -EEXIST; \ + list_for_each_entry(gs, &gi->string_list, list) { \ + if (gs->stringtab_dev.language == new->stringtab_dev.language) \ + goto err; \ + langs++; \ + } \ + ret = -EOVERFLOW; \ + if (langs >= MAX_USB_STRING_LANGS) \ + goto err; \ + \ + list_add_tail(&new->list, &gi->string_list); \ + return &new->group; \ +err: \ + kfree(new); \ + return ERR_PTR(ret); \ +} \ + \ +static void struct_in##_strings_drop( \ + struct config_group *group, \ + struct config_item *item) \ +{ \ + config_item_put(item); \ +} \ + \ +static struct configfs_group_operations struct_in##_strings_ops = { \ + .make_group = &struct_in##_strings_make, \ + .drop_item = &struct_in##_strings_drop, \ +}; \ + \ +static struct config_item_type struct_in##_strings_type = { \ + .ct_group_ops = &struct_in##_strings_ops, \ + .ct_owner = THIS_MODULE, \ +} + +#endif |