USB/host: Bugfix: Return length of copied buffer in uhci_hub_control()
authorDeng-Cheng Zhu <dengcheng.zhu@imgtec.com>
Sun, 6 Oct 2013 06:08:17 +0000 (23:08 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Oct 2013 07:07:17 +0000 (00:07 -0700)
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>
drivers/usb/host/uhci-hub.c

index 9189bc9..93e17b1 100644 (file)
@@ -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;