diff options
Diffstat (limited to 'drivers/usb/gadget')
29 files changed, 7240 insertions, 129 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 11a3e0fa433..649c0c5f715 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -710,6 +710,43 @@ config USB_GADGETFS Say "y" to link the driver statically, or "m" to build a dynamically linked module called "gadgetfs". +config USB_FUNCTIONFS + tristate "Function Filesystem (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + The Function Filesystem (FunctioFS) lets one create USB + composite functions in user space in the same way as GadgetFS + lets one create USB gadgets in user space. This allows creation + of composite gadgets such that some of the functions are + implemented in kernel space (for instance Ethernet, serial or + mass storage) and other are implemented in user space. + + Say "y" to link the driver statically, or "m" to build + a dynamically linked module called "g_ffs". + +config USB_FUNCTIONFS_ETH + bool "Include CDC ECM (Ethernet) function" + depends on USB_FUNCTIONFS && NET + help + Include an CDC ECM (Ethernet) funcion in the CDC ECM (Funcion) + Filesystem. If you also say "y" to the RNDIS query below the + gadget will have two configurations. + +config USB_FUNCTIONFS_RNDIS + bool "Include RNDIS (Ethernet) function" + depends on USB_FUNCTIONFS && NET + help + Include an RNDIS (Ethernet) funcion in the Funcion Filesystem. + If you also say "y" to the CDC ECM query above the gadget will + have two configurations. + +config USB_FUNCTIONFS_GENERIC + bool "Include 'pure' configuration" + depends on USB_FUNCTIONFS && (USB_FUNCTIONFS_ETH || USB_FUNCTIONFS_RNDIS) + help + Include a configuration with FunctionFS and no Ethernet + configuration. + config USB_FILE_STORAGE tristate "File-backed Storage Gadget" depends on BLOCK @@ -863,11 +900,30 @@ config USB_G_MULTI_CDC If unsure, say "y". +config USB_G_HID + tristate "HID Gadget" + help + The HID gadget driver provides generic emulation of USB + Human Interface Devices (HID). + + For more information, see Documentation/usb/gadget_hid.txt which + includes sample code for accessing the device files. + + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "g_hid". # put drivers that need isochronous transfer support (for audio # or video class gadget drivers), or specific hardware, here. +config USB_G_WEBCAM + tristate "USB Webcam Gadget" + depends on VIDEO_DEV + help + The Webcam Gadget acts as a composite USB Audio and Video Class + device. It provides a userspace API to process UVC control requests + and stream video data to the host. -# - none yet + Say "y" to link the driver statically, or "m" to build a + dynamically linked module called "g_webcam". endchoice diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 43b51da8d72..9bcde110feb 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o fsl_usb2_udc-objs := fsl_udc_core.o ifeq ($(CONFIG_ARCH_MXC),y) -fsl_usb2_udc-objs += fsl_mx3_udc.o +fsl_usb2_udc-objs += fsl_mxc_udc.o endif obj-$(CONFIG_USB_M66592) += m66592-udc.o obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o @@ -43,18 +43,24 @@ g_mass_storage-objs := mass_storage.o g_printer-objs := printer.o g_cdc-objs := cdc2.o g_multi-objs := multi.o +g_hid-objs := hid.o g_nokia-objs := nokia.o +g_webcam-objs := webcam.o obj-$(CONFIG_USB_ZERO) += g_zero.o obj-$(CONFIG_USB_AUDIO) += g_audio.o obj-$(CONFIG_USB_ETH) += g_ether.o obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o +obj-$(CONFIG_USB_FUNCTIONFS) += g_ffs.o +obj-$(CONFIG_USB_ETH_FUNCTIONFS) += g_eth_ffs.o obj-$(CONFIG_USB_FILE_STORAGE) += g_file_storage.o obj-$(CONFIG_USB_MASS_STORAGE) += g_mass_storage.o obj-$(CONFIG_USB_G_SERIAL) += g_serial.o obj-$(CONFIG_USB_G_PRINTER) += g_printer.o obj-$(CONFIG_USB_MIDI_GADGET) += g_midi.o obj-$(CONFIG_USB_CDC_COMPOSITE) += g_cdc.o +obj-$(CONFIG_USB_G_HID) += g_hid.o obj-$(CONFIG_USB_G_MULTI) += g_multi.o obj-$(CONFIG_USB_G_NOKIA) += g_nokia.o +obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index df1bae9b048..eaa79c8a9b8 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -366,6 +366,13 @@ rescan: if (is_done) done(ep, req, 0); else if (ep->is_pingpong) { + /* + * One dummy read to delay the code because of a HW glitch: + * CSR returns bad RXCOUNT when read too soon after updating + * RX_DATA_BK flags. + */ + csr = __raw_readl(creg); + bufferspace -= count; buf += count; goto rescan; diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 75a256f3d45..d623c7bda1f 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c @@ -48,10 +48,9 @@ static int queue_dbg_open(struct inode *inode, struct file *file) spin_lock_irq(&ep->udc->lock); list_for_each_entry(req, &ep->queue, queue) { - req_copy = kmalloc(sizeof(*req_copy), GFP_ATOMIC); + req_copy = kmemdup(req, sizeof(*req_copy), GFP_ATOMIC); if (!req_copy) goto fail; - memcpy(req_copy, req, sizeof(*req_copy)); list_add_tail(&req_copy->queue, queue_data); } spin_unlock_irq(&ep->udc->lock); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 09289bb1e20..391d169f8d0 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -36,7 +36,7 @@ */ /* big enough to hold our biggest descriptor */ -#define USB_BUFSIZ 512 +#define USB_BUFSIZ 1024 static struct usb_composite_driver *composite; @@ -85,7 +85,7 @@ MODULE_PARM_DESC(iSerialNumber, "SerialNumber string"); * This function returns the value of the function's bind(), which is * zero for success else a negative errno value. */ -int __init usb_add_function(struct usb_configuration *config, +int usb_add_function(struct usb_configuration *config, struct usb_function *function) { int value = -EINVAL; @@ -215,7 +215,7 @@ int usb_function_activate(struct usb_function *function) * Returns the interface ID which was allocated; or -ENODEV if no * more interface IDs can be allocated. */ -int __init usb_interface_id(struct usb_configuration *config, +int usb_interface_id(struct usb_configuration *config, struct usb_function *function) { unsigned id = config->next_interface_id; @@ -480,7 +480,7 @@ done: * assigns global resources including string IDs, and per-configuration * resources such as interface IDs and endpoints. */ -int __init usb_add_config(struct usb_composite_dev *cdev, +int usb_add_config(struct usb_composite_dev *cdev, struct usb_configuration *config) { int status = -EINVAL; @@ -677,7 +677,7 @@ static int get_string(struct usb_composite_dev *cdev, * ensure that for example different functions don't wrongly assign * different meanings to the same identifier. */ -int __init usb_string_id(struct usb_composite_dev *cdev) +int usb_string_id(struct usb_composite_dev *cdev) { if (cdev->next_string_id < 254) { /* string id 0 is reserved */ @@ -898,7 +898,19 @@ static void composite_disconnect(struct usb_gadget *gadget) /*-------------------------------------------------------------------------*/ -static void /* __init_or_exit */ +static ssize_t composite_show_suspended(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct usb_gadget *gadget = dev_to_usb_gadget(dev); + struct usb_composite_dev *cdev = get_gadget_data(gadget); + + return sprintf(buf, "%d\n", cdev->suspended); +} + +static DEVICE_ATTR(suspended, 0444, composite_show_suspended, NULL); + +static void composite_unbind(struct usb_gadget *gadget) { struct usb_composite_dev *cdev = get_gadget_data(gadget); @@ -944,10 +956,11 @@ composite_unbind(struct usb_gadget *gadget) } kfree(cdev); set_gadget_data(gadget, NULL); + device_remove_file(&gadget->dev, &dev_attr_suspended); composite = NULL; } -static void __init +static void string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s) { struct usb_string *str = tab->strings; @@ -960,7 +973,7 @@ string_override_one(struct usb_gadget_strings *tab, u8 id, const char *s) } } -static void __init +static void string_override(struct usb_gadget_strings **tab, u8 id, const char *s) { while (*tab) { @@ -969,7 +982,7 @@ string_override(struct usb_gadget_strings **tab, u8 id, const char *s) } } -static int __init composite_bind(struct usb_gadget *gadget) +static int composite_bind(struct usb_gadget *gadget) { struct usb_composite_dev *cdev; int status = -ENOMEM; @@ -1004,6 +1017,14 @@ static int __init composite_bind(struct usb_gadget *gadget) */ usb_ep_autoconfig_reset(cdev->gadget); + /* standardized runtime overrides for device ID data */ + if (idVendor) + cdev->desc.idVendor = cpu_to_le16(idVendor); + if (idProduct) + cdev->desc.idProduct = cpu_to_le16(idProduct); + if (bcdDevice) + cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); + /* composite gadget needs to assign strings for whole device (like * serial number), register function drivers, potentially update * power state and consumption, etc @@ -1015,14 +1036,6 @@ static int __init composite_bind(struct usb_gadget *gadget) cdev->desc = *composite->dev; cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; - /* standardized runtime overrides for device ID data */ - if (idVendor) - cdev->desc.idVendor = cpu_to_le16(idVendor); - if (idProduct) - cdev->desc.idProduct = cpu_to_le16(idProduct); - if (bcdDevice) - cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); - /* strings can't be assigned before bind() allocates the * releavnt identifiers */ @@ -1036,6 +1049,10 @@ static int __init composite_bind(struct usb_gadget *gadget) string_override(composite->strings, cdev->desc.iSerialNumber, iSerialNumber); + status = device_create_file(&gadget->dev, &dev_attr_suspended); + if (status) + goto fail; + INFO(cdev, "%s ready\n", composite->name); return 0; @@ -1064,6 +1081,8 @@ composite_suspend(struct usb_gadget *gadget) } if (composite->suspend) composite->suspend(cdev); + + cdev->suspended = 1; } static void @@ -1084,6 +1103,8 @@ composite_resume(struct usb_gadget *gadget) f->resume(f); } } + + cdev->suspended = 0; } /*-------------------------------------------------------------------------*/ @@ -1092,7 +1113,6 @@ static struct usb_gadget_driver composite_driver = { .speed = USB_SPEED_HIGH, .bind = composite_bind, - /* .unbind = __exit_p(composite_unbind), */ .unbind = composite_unbind, .setup = composite_setup, @@ -1121,7 +1141,7 @@ static struct usb_gadget_driver composite_driver = { * while it was binding. That would usually be done in order to wait for * some userspace participation. */ -int __init usb_composite_register(struct usb_composite_driver *driver) +int usb_composite_register(struct usb_composite_driver *driver) { if (!driver || !driver->dev || !driver->bind || composite) return -EINVAL; @@ -1142,7 +1162,7 @@ int __init usb_composite_register(struct usb_composite_driver *driver) * This function is used to unregister drivers using the composite * driver framework. */ -void /* __exit */ usb_composite_unregister(struct usb_composite_driver *driver) +void usb_composite_unregister(struct usb_composite_driver *driver) { if (composite != driver) return; diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 47e8e722682..09084fd646a 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c @@ -128,7 +128,7 @@ int usb_gadget_config_buf( * with identifiers (for interfaces, strings, endpoints, and more) * as needed by a given function instance. */ -struct usb_descriptor_header **__init +struct usb_descriptor_header ** usb_copy_descriptors(struct usb_descriptor_header **src) { struct usb_descriptor_header **tmp; @@ -175,7 +175,7 @@ usb_copy_descriptors(struct usb_descriptor_header **src) * intended use is to help remembering the endpoint descriptor to use * when enabling a given endpoint. */ -struct usb_endpoint_descriptor *__init +struct usb_endpoint_descriptor * usb_find_endpoint( struct usb_descriptor_header **src, struct usb_descriptor_header **copy, diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 5e096648518..4f9e578cde9 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -47,6 +47,7 @@ #include <linux/platform_device.h> #include <linux/usb.h> #include <linux/usb/gadget.h> +#include <linux/usb/hcd.h> #include <asm/byteorder.h> #include <asm/io.h> @@ -55,9 +56,6 @@ #include <asm/unaligned.h> -#include "../core/hcd.h" - - #define DRIVER_DESC "USB Host+Gadget Emulator" #define DRIVER_VERSION "02 May 2005" diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 3568de210f7..8a832488ccd 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -34,12 +34,12 @@ /* we must assign addresses for configurable endpoints (like net2280) */ -static __initdata unsigned epnum; +static unsigned epnum; // #define MANY_ENDPOINTS #ifdef MANY_ENDPOINTS /* more than 15 configurable endpoints */ -static __initdata unsigned in_epnum; +static unsigned in_epnum; #endif @@ -59,7 +59,7 @@ static __initdata unsigned in_epnum; * NOTE: each endpoint is unidirectional, as specified by its USB * descriptor; and isn't specific to a configuration or altsetting. */ -static int __init +static int ep_matches ( struct usb_gadget *gadget, struct usb_ep *ep, @@ -187,7 +187,7 @@ ep_matches ( return 1; } -static struct usb_ep * __init +static struct usb_ep * find_ep (struct usb_gadget *gadget, const char *name) { struct usb_ep *ep; @@ -229,7 +229,7 @@ find_ep (struct usb_gadget *gadget, const char *name) * * On failure, this returns a null endpoint descriptor. */ -struct usb_ep * __init usb_ep_autoconfig ( +struct usb_ep *usb_ep_autoconfig ( struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc ) @@ -304,7 +304,7 @@ struct usb_ep * __init usb_ep_autoconfig ( * state such as ep->driver_data and the record of assigned endpoints * used by usb_ep_autoconfig(). */ -void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget) +void usb_ep_autoconfig_reset (struct usb_gadget *gadget) { struct usb_ep *ep; diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 400e1ebe697..d47a123f15a 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -116,7 +116,7 @@ acm_iad_descriptor = { }; -static struct usb_interface_descriptor acm_control_interface_desc __initdata = { +static struct usb_interface_descriptor acm_control_interface_desc = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, /* .bInterfaceNumber = DYNAMIC */ @@ -127,7 +127,7 @@ static struct usb_interface_descriptor acm_control_interface_desc __initdata = { /* .iInterface = DYNAMIC */ }; -static struct usb_interface_descriptor acm_data_interface_desc __initdata = { +static struct usb_interface_descriptor acm_data_interface_desc = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, /* .bInterfaceNumber = DYNAMIC */ @@ -138,7 +138,7 @@ static struct usb_interface_descriptor acm_data_interface_desc __initdata = { /* .iInterface = DYNAMIC */ }; -static struct usb_cdc_header_desc acm_header_desc __initdata = { +static struct usb_cdc_header_desc acm_header_desc = { .bLength = sizeof(acm_header_desc), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_HEADER_TYPE, @@ -146,7 +146,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = { }; static struct usb_cdc_call_mgmt_descriptor -acm_call_mgmt_descriptor __initdata = { +acm_call_mgmt_descriptor = { .bLength = sizeof(acm_call_mgmt_descriptor), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, @@ -154,14 +154,14 @@ acm_call_mgmt_descriptor __initdata = { /* .bDataInterface = DYNAMIC */ }; -static struct usb_cdc_acm_descriptor acm_descriptor __initdata = { +static struct usb_cdc_acm_descriptor acm_descriptor = { .bLength = sizeof(acm_descriptor), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_ACM_TYPE, .bmCapabilities = USB_CDC_CAP_LINE, }; -static struct usb_cdc_union_desc acm_union_desc __initdata = { +static struct usb_cdc_union_desc acm_union_desc = { .bLength = sizeof(acm_union_desc), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_UNION_TYPE, @@ -171,7 +171,7 @@ static struct usb_cdc_union_desc acm_union_desc __initdata = { /* full speed support: */ -static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = { +static struct usb_endpoint_descriptor acm_fs_notify_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -180,21 +180,21 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = { .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, }; -static struct usb_endpoint_descriptor acm_fs_in_desc __initdata = { +static struct usb_endpoint_descriptor acm_fs_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor acm_fs_out_desc __initdata = { +static struct usb_endpoint_descriptor acm_fs_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *acm_fs_function[] __initdata = { +static struct usb_descriptor_header *acm_fs_function[] = { (struct usb_descriptor_header *) &acm_iad_descriptor, (struct usb_descriptor_header *) &acm_control_interface_desc, (struct usb_descriptor_header *) &acm_header_desc, @@ -210,7 +210,7 @@ static struct usb_descriptor_header *acm_fs_function[] __initdata = { /* high speed support: */ -static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = { +static struct usb_endpoint_descriptor acm_hs_notify_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, @@ -219,21 +219,21 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = { .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, }; -static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = { +static struct usb_endpoint_descriptor acm_hs_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = { +static struct usb_endpoint_descriptor acm_hs_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK, .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *acm_hs_function[] __initdata = { +static struct usb_descriptor_header *acm_hs_function[] = { (struct usb_descriptor_header *) &acm_iad_descriptor, (struct usb_descriptor_header *) &acm_control_interface_desc, (struct usb_descriptor_header *) &acm_header_desc, @@ -571,7 +571,7 @@ static int acm_send_break(struct gserial *port, int duration) /*-------------------------------------------------------------------------*/ /* ACM function driver setup/binding */ -static int __init +static int acm_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; @@ -719,7 +719,7 @@ static inline bool can_support_cdc(struct usb_configuration *c) * handle all the ones it binds. Caller is also responsible * for calling @gserial_cleanup() before module unload. */ -int __init acm_bind_config(struct usb_configuration *c, u8 port_num) +int acm_bind_config(struct usb_configuration *c, u8 port_num) { struct f_acm *acm; int status; diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 4e595324c61..544257a89ed 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -113,7 +113,7 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g) /* interface descriptor: */ -static struct usb_interface_descriptor ecm_control_intf __initdata = { +static struct usb_interface_descriptor ecm_control_intf = { .bLength = sizeof ecm_control_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -126,7 +126,7 @@ static struct usb_interface_descriptor ecm_control_intf __initdata = { /* .iInterface = DYNAMIC */ }; -static struct usb_cdc_header_desc ecm_header_desc __initdata = { +static struct usb_cdc_header_desc ecm_header_desc = { .bLength = sizeof ecm_header_desc, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_HEADER_TYPE, @@ -134,7 +134,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = { .bcdCDC = cpu_to_le16(0x0110), }; -static struct usb_cdc_union_desc ecm_union_desc __initdata = { +static struct usb_cdc_union_desc ecm_union_desc = { .bLength = sizeof(ecm_union_desc), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_UNION_TYPE, @@ -142,7 +142,7 @@ static struct usb_cdc_union_desc ecm_union_desc __initdata = { /* .bSlaveInterface0 = DYNAMIC */ }; -static struct usb_cdc_ether_desc ecm_desc __initdata = { +static struct usb_cdc_ether_desc ecm_desc = { .bLength = sizeof ecm_desc, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = USB_CDC_ETHERNET_TYPE, @@ -157,7 +157,7 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = { /* the default data interface has no endpoints ... */ -static struct usb_interface_descriptor ecm_data_nop_intf __initdata = { +static struct usb_interface_descriptor ecm_data_nop_intf = { .bLength = sizeof ecm_data_nop_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -172,7 +172,7 @@ static struct usb_interface_descriptor ecm_data_nop_intf __initdata = { /* ... but the "real" data interface has two bulk endpoints */ -static struct usb_interface_descriptor ecm_data_intf __initdata = { +static struct usb_interface_descriptor ecm_data_intf = { .bLength = sizeof ecm_data_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -187,7 +187,7 @@ static struct usb_interface_descriptor ecm_data_intf __initdata = { /* full speed support: */ -static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = { +static struct usb_endpoint_descriptor fs_ecm_notify_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = { .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, }; -static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = { +static struct usb_endpoint_descriptor fs_ecm_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -205,7 +205,7 @@ static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = { +static struct usb_endpoint_descriptor fs_ecm_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -213,7 +213,7 @@ static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *ecm_fs_function[] __initdata = { +static struct usb_descriptor_header *ecm_fs_function[] = { /* CDC ECM control descriptors */ (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, @@ -231,7 +231,7 @@ static struct usb_descriptor_header *ecm_fs_function[] __initdata = { /* high speed support: */ -static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = { +static struct usb_endpoint_descriptor hs_ecm_notify_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -240,7 +240,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = { .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, }; -static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { +static struct usb_endpoint_descriptor hs_ecm_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -249,7 +249,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { +static struct usb_endpoint_descriptor hs_ecm_out_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -258,7 +258,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *ecm_hs_function[] __initdata = { +static struct usb_descriptor_header *ecm_hs_function[] = { /* CDC ECM control descriptors */ (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, @@ -597,7 +597,7 @@ static void ecm_close(struct gether *geth) /* ethernet function driver setup/binding */ -static int __init +static int ecm_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; @@ -763,7 +763,8 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f) * Caller must have called @gether_setup(). Caller is also responsible * for calling @gether_cleanup() before module unload. */ -int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) +int +ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) { struct f_ecm *ecm; int status; diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c new file mode 100644 index 00000000000..d69eccf5f19 --- /dev/null +++ b/drivers/usb/gadget/f_fs.c @@ -0,0 +1,2442 @@ +/* + * f_fs.c -- user mode filesystem api for usb composite funtcion controllers + * + * Copyright (C) 2010 Samsung Electronics + * Author: Michal Nazarewicz <m.nazarewicz@samsung.com> + * + * Based on inode.c (GadgetFS): + * Copyright (C) 2003-2004 David Brownell + * Copyright (C) 2003 Agilent Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +/* #define DEBUG */ +/* #define VERBOSE_DEBUG */ + +#include <linux/blkdev.h> +#include <linux/pagemap.h> +#include <asm/unaligned.h> +#include <linux/smp_lock.h> + +#include <linux/usb/composite.h> +#include <linux/usb/functionfs.h> + + +#define FUNCTIONFS_MAGIC 0xa647361 /* Chosen by a honest dice roll ;) */ + + +/* Debuging *****************************************************************/ + +#define ffs_printk(level, fmt, args...) printk(level "f_fs: " fmt "\n", ## args) + +#define FERR(...) ffs_printk(KERN_ERR, __VA_ARGS__) +#define FINFO(...) ffs_printk(KERN_INFO, __VA_ARGS__) + +#ifdef DEBUG +# define FDBG(...) ffs_printk(KERN_DEBUG, __VA_ARGS__) +#else +# define FDBG(...) do { } while (0) +#endif /* DEBUG */ + +#ifdef VERBOSE_DEBUG +# define FVDBG FDBG +#else +# define FVDBG(...) do { } while (0) +#endif /* VERBOSE_DEBUG */ + +#define ENTER() FVDBG("%s()", __func__) + +#ifdef VERBOSE_DEBUG +# define ffs_dump_mem(prefix, ptr, len) \ + print_hex_dump_bytes("f_fs" prefix ": ", DUMP_PREFIX_NONE, ptr, len) +#el |