diff options
Diffstat (limited to 'drivers/usb/gadget/legacy')
-rw-r--r-- | drivers/usb/gadget/legacy/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/dbgp.c | 26 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/gmidi.c | 43 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/hid.c | 80 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/inode.c | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/printer.c | 65 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/tcm_usb_gadget.c | 12 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/zero.c | 2 |
8 files changed, 177 insertions, 55 deletions
diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 24392d269709..fd48ef3af4eb 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -287,6 +287,7 @@ config USB_MIDI_GADGET depends on SND select USB_LIBCOMPOSITE select SND_RAWMIDI + select USB_F_MIDI help The MIDI Gadget acts as a USB Audio device, with one MIDI input and one MIDI output. These MIDI jacks appear as @@ -419,6 +420,7 @@ endif # TTY config USB_G_HID tristate "HID Gadget" select USB_LIBCOMPOSITE + select USB_F_HID help The HID gadget driver provides generic emulation of USB Human Interface Devices (HID). diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 1b075132f8f1..633683a72a11 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -237,7 +237,7 @@ static void dbgp_unbind(struct usb_gadget *gadget) static unsigned char tty_line; #endif -static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) +static int dbgp_configure_endpoints(struct usb_gadget *gadget) { int stp; @@ -273,19 +273,10 @@ static int __init dbgp_configure_endpoints(struct usb_gadget *gadget) dbgp.serial->in->desc = &i_desc; dbgp.serial->out->desc = &o_desc; - - if (gserial_alloc_line(&tty_line)) { - stp = 3; - goto fail_3; - } +#endif return 0; -fail_3: - dbgp.o_ep->driver_data = NULL; -#else - return 0; -#endif fail_2: dbgp.i_ep->driver_data = NULL; fail_1: @@ -324,10 +315,17 @@ static int __init dbgp_bind(struct usb_gadget *gadget, err = -ENOMEM; goto fail; } + + if (gserial_alloc_line(&tty_line)) { + stp = 4; + err = -ENODEV; + goto fail; + } #endif + err = dbgp_configure_endpoints(gadget); if (err < 0) { - stp = 4; + stp = 5; goto fail; } @@ -383,6 +381,10 @@ static int dbgp_setup(struct usb_gadget *gadget, #ifdef CONFIG_USB_G_DBGP_PRINTK err = dbgp_enable_ep(); #else + err = dbgp_configure_endpoints(gadget); + if (err < 0) { + goto fail; + } err = gserial_connect(dbgp.serial, tty_line); #endif if (err < 0) diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c index 3d696b86ff76..e02a095294ac 100644 --- a/drivers/usb/gadget/legacy/gmidi.c +++ b/drivers/usb/gadget/legacy/gmidi.c @@ -37,7 +37,7 @@ #include "gadget_chips.h" -#include "f_midi.c" +#include "u_midi.h" /*-------------------------------------------------------------------------*/ @@ -115,8 +115,13 @@ static struct usb_gadget_strings *dev_strings[] = { NULL, }; +static struct usb_function_instance *fi_midi; +static struct usb_function *f_midi; + static int __exit midi_unbind(struct usb_composite_dev *dev) { + usb_put_function(f_midi); + usb_put_function_instance(fi_midi); return 0; } @@ -130,28 +135,54 @@ static struct usb_configuration midi_config = { static int __init midi_bind_config(struct usb_configuration *c) { - return f_midi_bind_config(c, index, id, - in_ports, out_ports, - buflen, qlen); + int status; + + f_midi = usb_get_function(fi_midi); + if (IS_ERR(f_midi)) + return PTR_ERR(f_midi); + + status = usb_add_function(c, f_midi); + if (status < 0) { + usb_put_function(f_midi); + return status; + } + + return 0; } static int __init midi_bind(struct usb_composite_dev *cdev) { + struct f_midi_opts *midi_opts; int status; + fi_midi = usb_get_function_instance("midi"); + if (IS_ERR(fi_midi)) + return PTR_ERR(fi_midi); + + midi_opts = container_of(fi_midi, struct f_midi_opts, func_inst); + midi_opts->index = index; + midi_opts->id = id; + midi_opts->in_ports = in_ports; + midi_opts->out_ports = out_ports; + midi_opts->buflen = buflen; + midi_opts->qlen = qlen; + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) - return status; + goto put; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; midi_config.iConfiguration = strings_dev[STRING_DESCRIPTION_IDX].id; status = usb_add_config(cdev, &midi_config, midi_bind_config); if (status < 0) - return status; + goto put; usb_composite_overwrite_options(cdev, &coverwrite); pr_info("%s\n", longname); return 0; +put: + usb_put_function_instance(fi_midi); + return status; } static __refdata struct usb_composite_driver midi_driver = { diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 778613eb37af..614b06d80b41 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -17,11 +17,14 @@ #include <linux/list.h> #include <linux/module.h> #include <linux/usb/composite.h> +#include <linux/usb/g_hid.h> #include "gadget_chips.h" #define DRIVER_DESC "HID Gadget" #define DRIVER_VERSION "2010/03/16" +#include "u_hid.h" + /*-------------------------------------------------------------------------*/ #define HIDG_VENDOR_NUM 0x0525 /* XXX NetChip */ @@ -29,17 +32,9 @@ /*-------------------------------------------------------------------------*/ -/* - * kbuild is not very cooperative with respect to linking separately - * compiled library objects into one module. So for now we won't use - * separate compilation ... ensuring init/exit sections work to shrink - * the runtime footprint, and giving us at least some parts of what - * a "gcc --combine ... part1.c part2.c part3.c ... " build would. - */ -#include "f_hid.c" - - struct hidg_func_node { + struct usb_function_instance *fi; + struct usb_function *f; struct list_head node; struct hidg_func_descriptor *func; }; @@ -113,8 +108,8 @@ static struct usb_gadget_strings *dev_strings[] = { static int __init do_config(struct usb_configuration *c) { - struct hidg_func_node *e; - int func = 0, status = 0; + struct hidg_func_node *e, *n; + int status = 0; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; @@ -122,11 +117,24 @@ static int __init do_config(struct usb_configuration *c) } list_for_each_entry(e, &hidg_func_list, node) { - status = hidg_bind_config(c, e->func, func++); - if (status) - break; + e->f = usb_get_function(e->fi); + if (IS_ERR(e->f)) + goto put; + status = usb_add_function(c, e->f); + if (status < 0) { + usb_put_function(e->f); + goto put; + } } + return 0; +put: + list_for_each_entry(n, &hidg_func_list, node) { + if (n == e) + break; + usb_remove_function(c, n->f); + usb_put_function(n->f); + } return status; } @@ -143,6 +151,8 @@ static int __init hid_bind(struct usb_composite_dev *cdev) { struct usb_gadget *gadget = cdev->gadget; struct list_head *tmp; + struct hidg_func_node *n, *m; + struct f_hid_opts *hid_opts; int status, funcs = 0; list_for_each(tmp, &hidg_func_list) @@ -151,10 +161,20 @@ static int __init hid_bind(struct usb_composite_dev *cdev) if (!funcs) return -ENODEV; - /* set up HID */ - status = ghid_setup(cdev->gadget, funcs); - if (status < 0) - return status; + list_for_each_entry(n, &hidg_func_list, node) { + n->fi = usb_get_function_instance("hid"); + if (IS_ERR(n->fi)) { + status = PTR_ERR(n->fi); + goto put; + } + hid_opts = container_of(n->fi, struct f_hid_opts, func_inst); + hid_opts->subclass = n->func->subclass; + hid_opts->protocol = n->func->protocol; + hid_opts->report_length = n->func->report_length; + hid_opts->report_desc_length = n->func->report_desc_length; + hid_opts->report_desc = n->func->report_desc; + } + /* Allocate string descriptor numbers ... note that string * contents can be overridden by the composite_dev glue. @@ -162,24 +182,37 @@ static int __init hid_bind(struct usb_composite_dev *cdev) status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) - return status; + goto put; device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id; device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id; /* register our configuration */ status = usb_add_config(cdev, &config_driver, do_config); if (status < 0) - return status; + goto put; usb_composite_overwrite_options(cdev, &coverwrite); dev_info(&gadget->dev, DRIVER_DESC ", version: " DRIVER_VERSION "\n"); return 0; + +put: + list_for_each_entry(m, &hidg_func_list, node) { + if (m == n) + break; + usb_put_function_instance(m->fi); + } + return status; } static int __exit hid_unbind(struct usb_composite_dev *cdev) { - ghid_cleanup(); + struct hidg_func_node *n; + + list_for_each_entry(n, &hidg_func_list, node) { + usb_put_function(n->f); + usb_put_function_instance(n->fi); + } return 0; } @@ -231,7 +264,6 @@ static __refdata struct usb_composite_driver hidg_driver = { static struct platform_driver hidg_plat_driver = { .remove = hidg_plat_driver_remove, .driver = { - .owner = THIS_MODULE, .name = "hidg", }, }; @@ -260,7 +292,7 @@ module_init(hidg_init); static void __exit hidg_cleanup(void) { - platform_driver_unregister(&hidg_plat_driver); usb_composite_unregister(&hidg_driver); + platform_driver_unregister(&hidg_plat_driver); } module_exit(hidg_cleanup); diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index c744e4975d74..db49ec4c748e 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -441,6 +441,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) kbuf = memdup_user(buf, len); if (IS_ERR(kbuf)) { value = PTR_ERR(kbuf); + kbuf = NULL; goto free1; } @@ -449,6 +450,7 @@ ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) data->name, len, (int) value); free1: mutex_unlock(&data->lock); + kfree (kbuf); return value; } diff --git a/drivers/usb/gadget/legacy/printer.c b/drivers/usb/gadget/legacy/printer.c index 6474081dcbaf..90545980542f 100644 --- a/drivers/usb/gadget/legacy/printer.c +++ b/drivers/usb/gadget/legacy/printer.c @@ -208,6 +208,43 @@ static struct usb_descriptor_header *hs_printer_function[] = { NULL }; +/* + * Added endpoint descriptors for 3.0 devices + */ + +static struct usb_endpoint_descriptor ss_ep_in_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = { + .bLength = sizeof(ss_ep_in_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_endpoint_descriptor ss_ep_out_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = cpu_to_le16(1024), +}; + +static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { + .bLength = sizeof(ss_ep_out_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, +}; + +static struct usb_descriptor_header *ss_printer_function[] = { + (struct usb_descriptor_header *) &intf_desc, + (struct usb_descriptor_header *) &ss_ep_in_desc, + (struct usb_descriptor_header *) &ss_ep_in_comp_desc, + (struct usb_descriptor_header *) &ss_ep_out_desc, + (struct usb_descriptor_header *) &ss_ep_out_comp_desc, + NULL +}; + static struct usb_otg_descriptor otg_descriptor = { .bLength = sizeof otg_descriptor, .bDescriptorType = USB_DT_OTG, @@ -220,7 +257,20 @@ static const struct usb_descriptor_header *otg_desc[] = { }; /* maxpacket and other transfer characteristics vary by speed. */ -#define ep_desc(g, hs, fs) (((g)->speed == USB_SPEED_HIGH)?(hs):(fs)) +static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, + struct usb_endpoint_descriptor *fs, + struct usb_endpoint_descriptor *hs, + struct usb_endpoint_descriptor *ss) +{ + switch (gadget->speed) { + case USB_SPEED_SUPER: + return ss; + case USB_SPEED_HIGH: + return hs; + default: + return fs; + } +} /*-------------------------------------------------------------------------*/ @@ -793,11 +843,12 @@ set_printer_interface(struct printer_dev *dev) { int result = 0; - dev->in_ep->desc = ep_desc(dev->gadget, &hs_ep_in_desc, &fs_ep_in_desc); + dev->in_ep->desc = ep_desc(dev->gadget, &fs_ep_in_desc, &hs_ep_in_desc, + &ss_ep_in_desc); dev->in_ep->driver_data = dev; - dev->out_ep->desc = ep_desc(dev->gadget, &hs_ep_out_desc, - &fs_ep_out_desc); + dev->out_ep->desc = ep_desc(dev->gadget, &fs_ep_out_desc, + &hs_ep_out_desc, &ss_ep_out_desc); dev->out_ep->driver_data = dev; result = usb_ep_enable(dev->in_ep); @@ -1016,9 +1067,11 @@ autoconf_fail: /* assumes that all endpoints are dual-speed */ hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; + ss_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress; + ss_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress; ret = usb_assign_descriptors(f, fs_printer_function, - hs_printer_function, NULL); + hs_printer_function, ss_printer_function); if (ret) return ret; @@ -1253,7 +1306,7 @@ static __refdata struct usb_composite_driver printer_driver = { .name = shortname, .dev = &device_desc, .strings = dev_strings, - .max_speed = USB_SPEED_HIGH, + .max_speed = USB_SPEED_SUPER, .bind = printer_bind, .unbind = printer_unbind, }; diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 6cdb7a534f23..3a494168661e 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -912,7 +912,7 @@ static int get_cmd_dir(const unsigned char *cdb) case INQUIRY: case MODE_SENSE: case MODE_SENSE_10: - case SERVICE_ACTION_IN: + case SERVICE_ACTION_IN_16: case MAINTENANCE_IN: case PERSISTENT_RESERVE_IN: case SECURITY_PROTOCOL_IN: @@ -1131,19 +1131,19 @@ static int usbg_submit_command(struct f_uas *fu, switch (cmd_iu->prio_attr & 0x7) { case UAS_HEAD_TAG: - cmd->prio_attr = MSG_HEAD_TAG; + cmd->prio_attr = TCM_HEAD_TAG; break; case UAS_ORDERED_TAG: - cmd->prio_attr = MSG_ORDERED_TAG; + cmd->prio_attr = TCM_ORDERED_TAG; break; case UAS_ACA: - cmd->prio_attr = MSG_ACA_TAG; + cmd->prio_attr = TCM_ACA_TAG; break; default: pr_debug_once("Unsupported prio_attr: %02x.\n", cmd_iu->prio_attr); case UAS_SIMPLE_TAG: - cmd->prio_attr = MSG_SIMPLE_TAG; + cmd->prio_attr = TCM_SIMPLE_TAG; break; } @@ -1240,7 +1240,7 @@ static int bot_submit_command(struct f_uas *fu, goto err; } - cmd->prio_attr = MSG_SIMPLE_TAG; + cmd->prio_attr = TCM_SIMPLE_TAG; se_cmd = &cmd->se_cmd; cmd->unpacked_lun = cbw->Lun; cmd->is_read = cbw->Flags & US_BULK_FLAG_IN ? 1 : 0; diff --git a/drivers/usb/gadget/legacy/zero.c b/drivers/usb/gadget/legacy/zero.c index ebf09f439f3a..ff97ac93ac03 100644 --- a/drivers/usb/gadget/legacy/zero.c +++ b/drivers/usb/gadget/legacy/zero.c @@ -28,7 +28,7 @@ * * Why is *this* driver using two configurations, rather than setting up * two interfaces with different functions? To help verify that multiple - * configuration infrastucture is working correctly; also, so that it can + * configuration infrastructure is working correctly; also, so that it can * work with low capability USB controllers without four bulk endpoints. */ |