diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 20:30:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-22 20:30:48 -0700 |
commit | 5cc103506289de7ee0a0b526ae0381541990cad4 (patch) | |
tree | ae8a4958e70c6d1295030b40e333dcc007b3c074 /drivers/usb/core | |
parent | 73ecf3a6e3f0206bf56a0fefe3b3eda042fb7034 (diff) | |
parent | 92ca0dc5ee022e4c0e488177e1d8865a0778c6c2 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (141 commits)
USB: mct_u232: fix broken close
USB: gadget: amd5536udc.c: fix error path
USB: imx21-hcd - fix off by one resource size calculation
usb: gadget: fix Kconfig warning
usb: r8a66597-udc: Add processing when USB was removed.
mxc_udc: add workaround for ENGcm09152 for i.MX35
USB: ftdi_sio: add device ids for ScienceScope
USB: musb: AM35x: Workaround for fifo read issue
USB: musb: add musb support for AM35x
USB: AM35x: Add musb support
usb: Fix linker errors with CONFIG_PM=n
USB: ohci-sh - use resource_size instead of defining its own resource_len macro
USB: isp1362-hcd - use resource_size instead of defining its own resource_len macro
USB: isp116x-hcd - use resource_size instead of defining its own resource_len macro
USB: xhci: Fix compile error when CONFIG_PM=n
USB: accept some invalid ep0-maxpacket values
USB: xHCI: PCI power management implementation
USB: xHCI: bus power management implementation
USB: xHCI: port remote wakeup implementation
USB: xHCI: port power management implementation
...
Manually fix up (non-data) conflict: the SCSI merge gad renamed the
'hw_sector_size' member to 'physical_block_size', and the USB tree
brought a new use of it.
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/Makefile | 21 | ||||
-rw-r--r-- | drivers/usb/core/devices.c | 11 | ||||
-rw-r--r-- | drivers/usb/core/driver.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/endpoint.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/hcd.c | 19 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 41 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 14 | ||||
-rw-r--r-- | drivers/usb/core/urb.c | 5 |
9 files changed, 67 insertions, 52 deletions
diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile index ec16e602990..507a4e1b636 100644 --- a/drivers/usb/core/Makefile +++ b/drivers/usb/core/Makefile @@ -2,20 +2,13 @@ # Makefile for USB Core files and filesystem # -usbcore-objs := usb.o hub.o hcd.o urb.o message.o driver.o \ - config.o file.o buffer.o sysfs.o endpoint.o \ - devio.o notify.o generic.o quirks.o devices.o +ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG -ifeq ($(CONFIG_PCI),y) - usbcore-objs += hcd-pci.o -endif +usbcore-y := usb.o hub.o hcd.o urb.o message.o driver.o +usbcore-y += config.o file.o buffer.o sysfs.o endpoint.o +usbcore-y += devio.o notify.o generic.o quirks.o devices.o -ifeq ($(CONFIG_USB_DEVICEFS),y) - usbcore-objs += inode.o -endif +usbcore-$(CONFIG_PCI) += hcd-pci.o +usbcore-$(CONFIG_USB_DEVICEFS) += inode.o -obj-$(CONFIG_USB) += usbcore.o - -ifeq ($(CONFIG_USB_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif +obj-$(CONFIG_USB) += usbcore.o diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 3449742c00e..ddb4dc98092 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -66,8 +66,8 @@ #define ALLOW_SERIAL_NUMBER static const char *format_topo = -/* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */ -"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n"; +/* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */ +"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n"; static const char *format_string_manufacturer = /* S: Manufacturer=xxxx */ @@ -520,11 +520,14 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, speed = "1.5"; break; case USB_SPEED_UNKNOWN: /* usb 1.1 root hub code */ case USB_SPEED_FULL: - speed = "12 "; break; + speed = "12"; break; + case USB_SPEED_WIRELESS: /* Wireless has no real fixed speed */ case USB_SPEED_HIGH: speed = "480"; break; + case USB_SPEED_SUPER: + speed = "5000"; break; default: - speed = "?? "; + speed = "??"; } data_end = pages_start + sprintf(pages_start, format_topo, bus->busnum, level, parent_devnum, diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d7a4401ef01..c0e60fbcb04 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1337,7 +1337,7 @@ int usb_resume(struct device *dev, pm_message_t msg) /* Avoid PM error messages for devices disconnected while suspended * as we'll display regular disconnect messages just a bit later. */ - if (status == -ENODEV) + if (status == -ENODEV || status == -ESHUTDOWN) status = 0; return status; } diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index 3788e738e26..9da25056302 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -202,7 +202,7 @@ int usb_create_ep_devs(struct device *parent, return retval; error_register: - kfree(ep_dev); + put_device(&ep_dev->dev); exit: return retval; } diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index c3f98543caa..3799573bd38 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -329,8 +329,10 @@ void usb_hcd_pci_shutdown(struct pci_dev *dev) return; if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && - hcd->driver->shutdown) + hcd->driver->shutdown) { hcd->driver->shutdown(hcd); + pci_disable_device(dev); + } } EXPORT_SYMBOL_GPL(usb_hcd_pci_shutdown); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 5cca00a6d09..61800f77dac 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1263,10 +1263,8 @@ static void hcd_free_coherent(struct usb_bus *bus, dma_addr_t *dma_handle, *dma_handle = 0; } -static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +void unmap_urb_setup_for_dma(struct usb_hcd *hcd, struct urb *urb) { - enum dma_data_direction dir; - if (urb->transfer_flags & URB_SETUP_MAP_SINGLE) dma_unmap_single(hcd->self.controller, urb->setup_dma, @@ -1279,6 +1277,17 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) sizeof(struct usb_ctrlrequest), DMA_TO_DEVICE); + /* Make it safe to call this routine more than once */ + urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL); +} +EXPORT_SYMBOL_GPL(unmap_urb_setup_for_dma); + +void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ + enum dma_data_direction dir; + + unmap_urb_setup_for_dma(hcd, urb); + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; if (urb->transfer_flags & URB_DMA_MAP_SG) dma_unmap_sg(hcd->self.controller, @@ -1303,10 +1312,10 @@ static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) dir); /* Make it safe to call this routine more than once */ - urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL | - URB_DMA_MAP_SG | URB_DMA_MAP_PAGE | + urb->transfer_flags &= ~(URB_DMA_MAP_SG | URB_DMA_MAP_PAGE | URB_DMA_MAP_SINGLE | URB_MAP_LOCAL); } +EXPORT_SYMBOL_GPL(unmap_urb_for_dma); static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 84c1897188d..27115b45edc 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -758,6 +758,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); portstatus &= ~USB_PORT_STAT_ENABLE; + } else { + /* Pretend that power was lost for USB3 devs */ + portstatus &= ~USB_PORT_STAT_ENABLE; } } @@ -2594,16 +2597,14 @@ static int hub_set_address(struct usb_device *udev, int devnum) return 0; if (udev->state != USB_STATE_DEFAULT) return -EINVAL; - if (hcd->driver->address_device) { + if (hcd->driver->address_device) retval = hcd->driver->address_device(hcd, udev); - } else { + else retval = usb_control_msg(udev, usb_sndaddr0pipe(), USB_REQ_SET_ADDRESS, 0, devnum, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (retval == 0) - update_address(udev, devnum); - } if (retval == 0) { + update_address(udev, devnum); /* Device now using proper address. */ usb_set_device_state(udev, USB_STATE_ADDRESS); usb_ep0_reinit(udev); @@ -2860,13 +2861,16 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, else i = udev->descriptor.bMaxPacketSize0; if (le16_to_cpu(udev->ep0.desc.wMaxPacketSize) != i) { - if (udev->speed != USB_SPEED_FULL || + if (udev->speed == USB_SPEED_LOW || !(i == 8 || i == 16 || i == 32 || i == 64)) { - dev_err(&udev->dev, "ep0 maxpacket = %d\n", i); + dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i); retval = -EMSGSIZE; goto fail; } - dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); + if (udev->speed == USB_SPEED_FULL) + dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i); + else + dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i); udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i); usb_ep0_reinit(udev); } @@ -3097,16 +3101,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, udev->speed = USB_SPEED_UNKNOWN; /* - * xHCI needs to issue an address device command later - * in the hub_port_init sequence for SS/HS/FS/LS devices. + * Set the address. + * Note xHCI needs to issue an address device command later + * in the hub_port_init sequence for SS/HS/FS/LS devices, + * and xHC will assign an address to the device. But use + * kernel assigned address here, to avoid any address conflict + * issue. */ - if (!(hcd->driver->flags & HCD_USB3)) { - /* set the address */ - choose_address(udev); - if (udev->devnum <= 0) { - status = -ENOTCONN; /* Don't retry */ - goto loop; - } + choose_address(udev); + if (udev->devnum <= 0) { + status = -ENOTCONN; /* Don't retry */ + goto loop; } /* reset (non-USB 3.0 devices) and get descriptor */ @@ -3629,7 +3634,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev) } if (!parent_hdev) { - /* this requires hcd-specific logic; see OHCI hc_restart() */ + /* this requires hcd-specific logic; see ohci_restart() */ dev_dbg(&udev->dev, "%s for root hub!\n", __func__); return -EISDIR; } diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 9f0ce7de0e3..d6e3e410477 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1140,13 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; - dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, - skip_ep0 ? "non-ep0" : "all"); - for (i = skip_ep0; i < 16; ++i) { - usb_disable_endpoint(dev, i, true); - usb_disable_endpoint(dev, i + USB_DIR_IN, true); - } - /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) */ @@ -1176,6 +1169,13 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) if (dev->state == USB_STATE_CONFIGURED) usb_set_device_state(dev, USB_STATE_ADDRESS); } + + dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, + skip_ep0 ? "non-ep0" : "all"); + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, true); + usb_disable_endpoint(dev, i + USB_DIR_IN, true); + } } /** diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 419e6b34e2f..c14fc082864 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -401,8 +401,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) }; /* Check that the pipe's type matches the endpoint's type */ - if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) + if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) { + dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", + usb_pipetype(urb->pipe), pipetypes[xfertype]); return -EPIPE; /* The most suitable error code :-) */ + } /* enforce simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK | |