diff options
author | Deng-Cheng Zhu <dengcheng.zhu@imgtec.com> | 2013-10-06 10:08:17 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-07 11:07:17 +0400 |
commit | 5a3e2055c56c7c32b51d47bde78c7f7508ffea98 (patch) | |
tree | 5bf3a633e6d37f2aa694277276442b6dc604201e /drivers/usb/host/uhci-hub.c | |
parent | cae9160d9b074a75c5ae4b08a8552155b1607b9b (diff) | |
download | linux-5a3e2055c56c7c32b51d47bde78c7f7508ffea98.tar.xz |
USB/host: Bugfix: Return length of copied buffer in uhci_hub_control()
In addition to the error statuses -ETIMEDOUT and -EPIPE, uhci_hub_control()
needs to return the length of copied buffer when appropriate, so that the
returned status of ->hub_control() in rh_call_control() in the USB core
HCD can be properly handled.
This patch also removes the OK() macro to make the code more readable.
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Deng-Cheng Zhu <dengcheng.zhu@imgtec.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/uhci-hub.c')
-rw-r--r-- | drivers/usb/host/uhci-hub.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 9189bc984c98..93e17b12fb33 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -75,8 +75,6 @@ static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) return !!*buf; } -#define OK(x) len = (x); break - #define CLR_RH_PORTSTAT(x) \ status = uhci_readw(uhci, port_addr); \ status &= ~(RWC_BITS|WZ_BITS); \ @@ -244,7 +242,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); - int status, lstatus, retval = 0, len = 0; + int status, lstatus, retval = 0; unsigned int port = wIndex - 1; unsigned long port_addr = USBPORTSC1 + 2 * port; u16 wPortChange, wPortStatus; @@ -258,7 +256,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, case GetHubStatus: *(__le32 *)buf = cpu_to_le32(0); - OK(4); /* hub power */ + retval = 4; /* hub power */ + break; case GetPortStatus: if (port >= uhci->rh_numports) goto err; @@ -311,13 +310,14 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, *(__le16 *)buf = cpu_to_le16(wPortStatus); *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange); - OK(4); + retval = 4; + break; case SetHubFeature: /* We don't implement these */ case ClearHubFeature: switch (wValue) { case C_HUB_OVER_CURRENT: case C_HUB_LOCAL_POWER: - OK(0); + break; default: goto err; } @@ -329,7 +329,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, switch (wValue) { case USB_PORT_FEAT_SUSPEND: SET_RH_PORTSTAT(USBPORTSC_SUSP); - OK(0); + break; case USB_PORT_FEAT_RESET: SET_RH_PORTSTAT(USBPORTSC_PR); @@ -338,10 +338,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, /* USB v2.0 7.1.7.5 */ uhci->ports_timeout = jiffies + msecs_to_jiffies(50); - OK(0); + break; case USB_PORT_FEAT_POWER: /* UHCI has no power switching */ - OK(0); + break; default: goto err; } @@ -356,10 +356,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, /* Disable terminates Resume signalling */ uhci_finish_suspend(uhci, port, port_addr); - OK(0); + break; case USB_PORT_FEAT_C_ENABLE: CLR_RH_PORTSTAT(USBPORTSC_PEC); - OK(0); + break; case USB_PORT_FEAT_SUSPEND: if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) { @@ -382,32 +382,32 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, uhci->ports_timeout = jiffies + msecs_to_jiffies(20); } - OK(0); + break; case USB_PORT_FEAT_C_SUSPEND: clear_bit(port, &uhci->port_c_suspend); - OK(0); + break; case USB_PORT_FEAT_POWER: /* UHCI has no power switching */ goto err; case USB_PORT_FEAT_C_CONNECTION: CLR_RH_PORTSTAT(USBPORTSC_CSC); - OK(0); + break; case USB_PORT_FEAT_C_OVER_CURRENT: CLR_RH_PORTSTAT(USBPORTSC_OCC); - OK(0); + break; case USB_PORT_FEAT_C_RESET: /* this driver won't report these */ - OK(0); + break; default: goto err; } break; case GetHubDescriptor: - len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); - memcpy(buf, root_hub_hub_des, len); - if (len > 2) + retval = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); + memcpy(buf, root_hub_hub_des, retval); + if (retval > 2) buf[2] = uhci->rh_numports; - OK(len); + break; default: err: retval = -EPIPE; |