diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/usb/core/hcd.c | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 122 |
1 files changed, 65 insertions, 57 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 6bffb8c..d6a8d23 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -6,7 +6,7 @@ * (C) Copyright Deti Fliegl 1999 * (C) Copyright Randy Dunlap 2000 * (C) Copyright David Brownell 2000-2002 - * + * * 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 @@ -40,7 +40,6 @@ #include <linux/platform_device.h> #include <linux/workqueue.h> #include <linux/pm_runtime.h> -#include <linux/types.h> #include <linux/usb.h> #include <linux/usb/hcd.h> @@ -93,7 +92,10 @@ EXPORT_SYMBOL_GPL (usb_bus_list); /* used when allocating bus numbers */ #define USB_MAXBUS 64 -static DECLARE_BITMAP(busmap, USB_MAXBUS); +struct usb_busmap { + unsigned long busmap [USB_MAXBUS / (8*sizeof (unsigned long))]; +}; +static struct usb_busmap busmap; /* used when updating list of hcds */ DEFINE_MUTEX(usb_bus_list_lock); /* exported only for usbfs */ @@ -169,7 +171,7 @@ static const u8 usb25_rh_dev_descriptor[18] = { }; /* usb 2.0 root hub device descriptor */ -static const u8 usb2_rh_dev_descriptor[18] = { +static const u8 usb2_rh_dev_descriptor [18] = { 0x12, /* __u8 bLength; */ 0x01, /* __u8 bDescriptorType; Device */ 0x00, 0x02, /* __le16 bcdUSB; v2.0 */ @@ -192,7 +194,7 @@ static const u8 usb2_rh_dev_descriptor[18] = { /* no usb 2.0 root hub "device qualifier" descriptor: one speed only */ /* usb 1.1 root hub device descriptor */ -static const u8 usb11_rh_dev_descriptor[18] = { +static const u8 usb11_rh_dev_descriptor [18] = { 0x12, /* __u8 bLength; */ 0x01, /* __u8 bDescriptorType; Device */ 0x10, 0x01, /* __le16 bcdUSB; v1.1 */ @@ -217,7 +219,7 @@ static const u8 usb11_rh_dev_descriptor[18] = { /* Configuration descriptors for our root hubs */ -static const u8 fs_rh_config_descriptor[] = { +static const u8 fs_rh_config_descriptor [] = { /* one configuration */ 0x09, /* __u8 bLength; */ @@ -226,13 +228,13 @@ static const u8 fs_rh_config_descriptor[] = { 0x01, /* __u8 bNumInterfaces; (1) */ 0x01, /* __u8 bConfigurationValue; */ 0x00, /* __u8 iConfiguration; */ - 0xc0, /* __u8 bmAttributes; + 0xc0, /* __u8 bmAttributes; Bit 7: must be set, 6: Self-powered, 5: Remote wakeup, 4..0: resvd */ 0x00, /* __u8 MaxPower; */ - + /* USB 1.1: * USB 2.0, single TT organization (mandatory): * one interface, protocol 0 @@ -254,17 +256,17 @@ static const u8 fs_rh_config_descriptor[] = { 0x00, /* __u8 if_bInterfaceSubClass; */ 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ 0x00, /* __u8 if_iInterface; */ - + /* one endpoint (status change endpoint) */ 0x07, /* __u8 ep_bLength; */ 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ - 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x02, 0x00, /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ 0xff /* __u8 ep_bInterval; (255ms -- usb 2.0 spec) */ }; -static const u8 hs_rh_config_descriptor[] = { +static const u8 hs_rh_config_descriptor [] = { /* one configuration */ 0x09, /* __u8 bLength; */ @@ -273,13 +275,13 @@ static const u8 hs_rh_config_descriptor[] = { 0x01, /* __u8 bNumInterfaces; (1) */ 0x01, /* __u8 bConfigurationValue; */ 0x00, /* __u8 iConfiguration; */ - 0xc0, /* __u8 bmAttributes; + 0xc0, /* __u8 bmAttributes; Bit 7: must be set, 6: Self-powered, 5: Remote wakeup, 4..0: resvd */ 0x00, /* __u8 MaxPower; */ - + /* USB 1.1: * USB 2.0, single TT organization (mandatory): * one interface, protocol 0 @@ -301,12 +303,12 @@ static const u8 hs_rh_config_descriptor[] = { 0x00, /* __u8 if_bInterfaceSubClass; */ 0x00, /* __u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ 0x00, /* __u8 if_iInterface; */ - + /* one endpoint (status change endpoint) */ 0x07, /* __u8 ep_bLength; */ 0x05, /* __u8 ep_bDescriptorType; Endpoint */ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ /* __le16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) * see hub.c:hub_configure() for details. */ (USB_MAXCHILDREN + 1 + 7) / 8, 0x00, @@ -426,7 +428,7 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len) char const *s; static char const langids[4] = {4, USB_DT_STRING, 0x09, 0x04}; - /* language ids */ + // language ids switch (id) { case 0: /* Array of LANGID codes (0x0409 is MSFT-speak for "en-us") */ @@ -462,7 +464,7 @@ rh_string(int id, struct usb_hcd const *hcd, u8 *data, unsigned len) static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) { struct usb_ctrlrequest *cmd; - u16 typeReq, wValue, wIndex, wLength; + u16 typeReq, wValue, wIndex, wLength; u8 *ubuf = urb->transfer_buffer; unsigned len = 0; int status; @@ -524,10 +526,10 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) */ case DeviceRequest | USB_REQ_GET_STATUS: - tbuf[0] = (device_may_wakeup(&hcd->self.root_hub->dev) + tbuf [0] = (device_may_wakeup(&hcd->self.root_hub->dev) << USB_DEVICE_REMOTE_WAKEUP) | (1 << USB_DEVICE_SELF_POWERED); - tbuf[1] = 0; + tbuf [1] = 0; len = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: @@ -544,7 +546,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) goto error; break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: - tbuf[0] = 1; + tbuf [0] = 1; len = 1; /* FALLTHROUGH */ case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: @@ -607,13 +609,13 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) } break; case DeviceRequest | USB_REQ_GET_INTERFACE: - tbuf[0] = 0; + tbuf [0] = 0; len = 1; /* FALLTHROUGH */ case DeviceOutRequest | USB_REQ_SET_INTERFACE: break; case DeviceOutRequest | USB_REQ_SET_ADDRESS: - /* wValue == urb->dev->devaddr */ + // wValue == urb->dev->devaddr dev_dbg (hcd->self.controller, "root hub device address %d\n", wValue); break; @@ -623,9 +625,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) /* ENDPOINT REQUESTS */ case EndpointRequest | USB_REQ_GET_STATUS: - /* ENDPOINT_HALT flag */ - tbuf[0] = 0; - tbuf[1] = 0; + // ENDPOINT_HALT flag + tbuf [0] = 0; + tbuf [1] = 0; len = 2; /* FALLTHROUGH */ case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: @@ -681,7 +683,7 @@ error: if (urb->transfer_buffer_length < len) len = urb->transfer_buffer_length; urb->actual_length = len; - /* always USB_DIR_IN, toward host */ + // always USB_DIR_IN, toward host memcpy (ubuf, bufp, len); /* report whether RH hardware supports remote wakeup */ @@ -875,11 +877,11 @@ static ssize_t authorized_default_store(struct device *dev, usb_hcd = bus_to_hcd(usb_bus); result = sscanf(buf, "%u\n", &val); if (result == 1) { - usb_hcd->authorized_default = val ? 1 : 0; + usb_hcd->authorized_default = val? 1 : 0; result = size; - } else { - result = -EINVAL; } + else + result = -EINVAL; return result; } static DEVICE_ATTR_RW(authorized_default); @@ -939,12 +941,12 @@ static int usb_register_bus(struct usb_bus *bus) int busnum; mutex_lock(&usb_bus_list_lock); - busnum = find_next_zero_bit(busmap, USB_MAXBUS, 1); + busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); if (busnum >= USB_MAXBUS) { printk (KERN_ERR "%s: too many buses\n", usbcore_name); goto error_find_busnum; } - set_bit(busnum, busmap); + set_bit (busnum, busmap.busmap); bus->busnum = busnum; /* Add it to the local list of buses */ @@ -985,7 +987,7 @@ static void usb_deregister_bus (struct usb_bus *bus) usb_notify_remove_bus(bus); - clear_bit(bus->busnum, busmap); + clear_bit (bus->busnum, busmap.busmap); } /** @@ -1031,7 +1033,6 @@ static int register_root_hub(struct usb_hcd *hcd) dev_name(&usb_dev->dev), retval); return retval; } - usb_dev->lpm_capable = usb_device_supports_lpm(usb_dev); } retval = usb_new_device (usb_dev); @@ -1119,21 +1120,21 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) case USB_SPEED_LOW: /* INTR only */ if (is_input) { tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L; - return 64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp; + return (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); } else { tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L; - return 64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp; + return (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp); } case USB_SPEED_FULL: /* ISOC or INTR */ if (isoc) { tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; - return ((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp; + return (((is_input) ? 7268L : 6265L) + BW_HOST_DELAY + tmp); } else { tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L; - return 9107L + BW_HOST_DELAY + tmp; + return (9107L + BW_HOST_DELAY + tmp); } case USB_SPEED_HIGH: /* ISOC or INTR */ - /* FIXME adjust for input vs output */ + // FIXME adjust for input vs output if (isoc) tmp = HS_NSECS_ISO (bytecount); else @@ -1650,7 +1651,6 @@ int usb_hcd_unlink_urb (struct urb *urb, int status) static void __usb_hcd_giveback_urb(struct urb *urb) { struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); - struct usb_anchor *anchor = urb->anchor; int status = urb->unlinked; unsigned long flags; @@ -1662,7 +1662,6 @@ static void __usb_hcd_giveback_urb(struct urb *urb) unmap_urb_for_dma(hcd, urb); usbmon_urb_complete(&hcd->self, urb, status); - usb_anchor_suspend_wakeups(anchor); usb_unanchor_urb(urb); /* pass ownership to the completion handler */ @@ -1682,7 +1681,6 @@ static void __usb_hcd_giveback_urb(struct urb *urb) urb->complete(urb); local_irq_restore(flags); - usb_anchor_resume_wakeups(anchor); atomic_dec(&urb->use_count); if (unlikely(atomic_read(&urb->reject))) wake_up(&usb_kill_urb_queue); @@ -1705,9 +1703,7 @@ static void usb_giveback_urb_bh(unsigned long param) urb = list_entry(local_list.next, struct urb, urb_list); list_del_init(&urb->urb_list); - bh->completing_ep = urb->ep; __usb_hcd_giveback_urb(urb); - bh->completing_ep = NULL; } /* check if there are new URBs to giveback */ @@ -1816,7 +1812,7 @@ rescan: case USB_ENDPOINT_XFER_INT: s = "-intr"; break; default: - s = "-iso"; break; + s = "-iso"; break; }; s; })); @@ -2077,11 +2073,8 @@ EXPORT_SYMBOL_GPL(usb_alloc_streams); * * Reverts a group of bulk endpoints back to not using stream IDs. * Can fail if we are given bad arguments, or HCD is broken. - * - * Return: On success, the number of allocated streams. On failure, a negative - * error code. */ -int usb_free_streams(struct usb_interface *interface, +void usb_free_streams(struct usb_interface *interface, struct usb_host_endpoint **eps, unsigned int num_eps, gfp_t mem_flags) { @@ -2092,14 +2085,14 @@ int usb_free_streams(struct usb_interface *interface, dev = interface_to_usbdev(interface); hcd = bus_to_hcd(dev->bus); if (dev->speed != USB_SPEED_SUPER) - return -EINVAL; + return; /* Streams only apply to bulk endpoints. */ for (i = 0; i < num_eps; i++) if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc)) - return -EINVAL; + return; - return hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); + hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); } EXPORT_SYMBOL_GPL(usb_free_streams); @@ -2252,7 +2245,7 @@ static void hcd_resume_work(struct work_struct *work) } /** - * usb_hcd_resume_root_hub - called by HCD to resume its root hub + * usb_hcd_resume_root_hub - called by HCD to resume its root hub * @hcd: host controller for this root hub * * The USB host controller calls this function when its root hub is @@ -2331,8 +2324,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum); irqreturn_t usb_hcd_irq (int irq, void *__hcd) { struct usb_hcd *hcd = __hcd; + unsigned long flags; irqreturn_t rc; + /* IRQF_DISABLED doesn't work correctly with shared IRQs + * when the first handler doesn't use it. So let's just + * assume it's never used. + */ + local_irq_save(flags); + if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) rc = IRQ_NONE; else if (hcd->driver->irq(hcd) == IRQ_NONE) @@ -2340,6 +2340,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd) else rc = IRQ_HANDLED; + local_irq_restore(flags); return rc; } EXPORT_SYMBOL_GPL(usb_hcd_irq); @@ -2546,6 +2547,13 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd, if (hcd->driver->irq) { + /* IRQF_DISABLED doesn't work as advertised when used together + * with IRQF_SHARED. As usb_hcd_irq() will always disable + * interrupts we can remove it here. + */ + if (irqflags & IRQF_SHARED) + irqflags &= ~IRQF_DISABLED; + snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); retval = request_irq(irqnum, &usb_hcd_irq, irqflags, @@ -2592,7 +2600,7 @@ int usb_add_hcd(struct usb_hcd *hcd, /* Keep old behaviour if authorized_default is not in [0, 1]. */ if (authorized_default < 0 || authorized_default > 1) - hcd->authorized_default = hcd->wireless ? 0 : 1; + hcd->authorized_default = hcd->wireless? 0 : 1; else hcd->authorized_default = authorized_default; set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); @@ -2735,7 +2743,7 @@ err_allocate_root_hub: err_register_bus: hcd_buffer_destroy(hcd); return retval; -} +} EXPORT_SYMBOL_GPL(usb_add_hcd); /** @@ -2810,7 +2818,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) EXPORT_SYMBOL_GPL(usb_remove_hcd); void -usb_hcd_platform_shutdown(struct platform_device *dev) +usb_hcd_platform_shutdown(struct platform_device* dev) { struct usb_hcd *hcd = platform_get_drvdata(dev); @@ -2832,7 +2840,7 @@ struct usb_mon_operations *mon_ops; * Notice that the code is minimally error-proof. Because usbmon needs * symbols from usbcore, usbcore gets referenced and cannot be unloaded first. */ - + int usb_mon_register (struct usb_mon_operations *ops) { |