diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 12:23:15 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-25 12:23:15 +0200 |
commit | 1be025d3cb40cd295123af2c394f7229ef9b30ca (patch) | |
tree | 5dc14e1ea412cc7fdc3e563ad23187059fe8bfb5 /drivers/usb/core/hcd.c | |
parent | 2d03423b2319cc854adeb28a03f65de5b5e0ab63 (diff) | |
parent | a2c76b83fdd763c826f38a55127ccf25708099ce (diff) | |
download | linux-1be025d3cb40cd295123af2c394f7229ef9b30ca.tar.bz2 |
Merge branch 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
* 'usb-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (260 commits)
usb: renesas_usbhs: fixup inconsistent return from usbhs_pkt_push()
usb/isp1760: Allow to optionally trigger low-level chip reset via GPIOLIB.
USB: gadget: midi: memory leak in f_midi_bind_config()
USB: gadget: midi: fix range check in f_midi_out_open()
QE/FHCI: fixed the CONTROL bug
usb: renesas_usbhs: tidyup for smatch warnings
USB: Fix USB Kconfig dependency problem on 85xx/QoirQ platforms
EHCI: workaround for MosChip controller bug
usb: gadget: file_storage: fix race on unloading
USB: ftdi_sio.c: Use ftdi async_icount structure for TIOCMIWAIT, as in other drivers
USB: ftdi_sio.c:Fill MSR fields of the ftdi async_icount structure
USB: ftdi_sio.c: Fill LSR fields of the ftdi async_icount structure
USB: ftdi_sio.c:Fill TX field of the ftdi async_icount structure
USB: ftdi_sio.c: Fill the RX field of the ftdi async_icount structure
USB: ftdi_sio.c: Basic icount infrastructure for ftdi_sio
usb/isp1760: Let OF bindings depend on general CONFIG_OF instead of PPC_OF .
USB: ftdi_sio: Support TI/Luminary Micro Stellaris BD-ICDI Board
USB: Fix runtime wakeup on OHCI
xHCI/USB: Make xHCI driver have a BOS descriptor.
usb: gadget: add new usb gadget for ACM and mass storage
...
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 73cbbd85219f..b3b7d062906d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -442,7 +442,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) struct usb_ctrlrequest *cmd; u16 typeReq, wValue, wIndex, wLength; u8 *ubuf = urb->transfer_buffer; - u8 tbuf [sizeof (struct usb_hub_descriptor)] + /* + * tbuf should be as big as the BOS descriptor and + * the USB hub descriptor. + */ + u8 tbuf[USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE] __attribute__((aligned(4))); const u8 *bufp = tbuf; unsigned len = 0; @@ -562,6 +566,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) else /* unsupported IDs --> "protocol stall" */ goto error; break; + case USB_DT_BOS << 8: + goto nongeneric; default: goto error; } @@ -596,6 +602,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) /* CLASS REQUESTS (and errors) */ default: +nongeneric: /* non-generic request */ switch (typeReq) { case GetHubStatus: @@ -605,6 +612,9 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) case GetHubDescriptor: len = sizeof (struct usb_hub_descriptor); break; + case DeviceRequest | USB_REQ_GET_DESCRIPTOR: + /* len is returned by hub_control */ + break; } status = hcd->driver->hub_control (hcd, typeReq, wValue, wIndex, @@ -615,7 +625,7 @@ error: status = -EPIPE; } - if (status) { + if (status < 0) { len = 0; if (status != -EPIPE) { dev_dbg (hcd->self.controller, @@ -624,6 +634,10 @@ error: typeReq, wValue, wIndex, wLength, status); } + } else if (status > 0) { + /* hub_control may return the length of data copied. */ + len = status; + status = 0; } if (len) { if (urb->transfer_buffer_length < len) @@ -2429,7 +2443,7 @@ int usb_add_hcd(struct usb_hcd *hcd, * but drivers can override it in reset() if needed, along with * recording the overall controller's system wakeup capability. */ - device_init_wakeup(&rhdev->dev, 1); + device_set_wakeup_capable(&rhdev->dev, 1); /* HCD_FLAG_RH_RUNNING doesn't matter until the root hub is * registered. But since the controller can die at any time, @@ -2478,6 +2492,13 @@ int usb_add_hcd(struct usb_hcd *hcd, } if (hcd->uses_new_polling && HCD_POLL_RH(hcd)) usb_hcd_poll_rh_status(hcd); + + /* + * Host controllers don't generate their own wakeup requests; + * they only forward requests from the root hub. Therefore + * controllers should always be enabled for remote wakeup. + */ + device_wakeup_enable(hcd->self.controller); return retval; error_create_attr_group: |