aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorDeng-Cheng Zhu <dengcheng.zhu@imgtec.com>2013-10-06 02:08:17 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-07 03:07:17 -0400
commit5a3e2055c56c7c32b51d47bde78c7f7508ffea98 (patch)
tree5bf3a633e6d37f2aa694277276442b6dc604201e /drivers/usb/host
parentcae9160d9b074a75c5ae4b08a8552155b1607b9b (diff)
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')
-rw-r--r--drivers/usb/host/uhci-hub.c40
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)
75 return !!*buf; 75 return !!*buf;
76} 76}
77 77
78#define OK(x) len = (x); break
79
80#define CLR_RH_PORTSTAT(x) \ 78#define CLR_RH_PORTSTAT(x) \
81 status = uhci_readw(uhci, port_addr); \ 79 status = uhci_readw(uhci, port_addr); \
82 status &= ~(RWC_BITS|WZ_BITS); \ 80 status &= ~(RWC_BITS|WZ_BITS); \
@@ -244,7 +242,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
244 u16 wIndex, char *buf, u16 wLength) 242 u16 wIndex, char *buf, u16 wLength)
245{ 243{
246 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 244 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
247 int status, lstatus, retval = 0, len = 0; 245 int status, lstatus, retval = 0;
248 unsigned int port = wIndex - 1; 246 unsigned int port = wIndex - 1;
249 unsigned long port_addr = USBPORTSC1 + 2 * port; 247 unsigned long port_addr = USBPORTSC1 + 2 * port;
250 u16 wPortChange, wPortStatus; 248 u16 wPortChange, wPortStatus;
@@ -258,7 +256,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
258 256
259 case GetHubStatus: 257 case GetHubStatus:
260 *(__le32 *)buf = cpu_to_le32(0); 258 *(__le32 *)buf = cpu_to_le32(0);
261 OK(4); /* hub power */ 259 retval = 4; /* hub power */
260 break;
262 case GetPortStatus: 261 case GetPortStatus:
263 if (port >= uhci->rh_numports) 262 if (port >= uhci->rh_numports)
264 goto err; 263 goto err;
@@ -311,13 +310,14 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
311 310
312 *(__le16 *)buf = cpu_to_le16(wPortStatus); 311 *(__le16 *)buf = cpu_to_le16(wPortStatus);
313 *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange); 312 *(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);
314 OK(4); 313 retval = 4;
314 break;
315 case SetHubFeature: /* We don't implement these */ 315 case SetHubFeature: /* We don't implement these */
316 case ClearHubFeature: 316 case ClearHubFeature:
317 switch (wValue) { 317 switch (wValue) {
318 case C_HUB_OVER_CURRENT: 318 case C_HUB_OVER_CURRENT:
319 case C_HUB_LOCAL_POWER: 319 case C_HUB_LOCAL_POWER:
320 OK(0); 320 break;
321 default: 321 default:
322 goto err; 322 goto err;
323 } 323 }
@@ -329,7 +329,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
329 switch (wValue) { 329 switch (wValue) {
330 case USB_PORT_FEAT_SUSPEND: 330 case USB_PORT_FEAT_SUSPEND:
331 SET_RH_PORTSTAT(USBPORTSC_SUSP); 331 SET_RH_PORTSTAT(USBPORTSC_SUSP);
332 OK(0); 332 break;
333 case USB_PORT_FEAT_RESET: 333 case USB_PORT_FEAT_RESET:
334 SET_RH_PORTSTAT(USBPORTSC_PR); 334 SET_RH_PORTSTAT(USBPORTSC_PR);
335 335
@@ -338,10 +338,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
338 338
339 /* USB v2.0 7.1.7.5 */ 339 /* USB v2.0 7.1.7.5 */
340 uhci->ports_timeout = jiffies + msecs_to_jiffies(50); 340 uhci->ports_timeout = jiffies + msecs_to_jiffies(50);
341 OK(0); 341 break;
342 case USB_PORT_FEAT_POWER: 342 case USB_PORT_FEAT_POWER:
343 /* UHCI has no power switching */ 343 /* UHCI has no power switching */
344 OK(0); 344 break;
345 default: 345 default:
346 goto err; 346 goto err;
347 } 347 }
@@ -356,10 +356,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
356 356
357 /* Disable terminates Resume signalling */ 357 /* Disable terminates Resume signalling */
358 uhci_finish_suspend(uhci, port, port_addr); 358 uhci_finish_suspend(uhci, port, port_addr);
359 OK(0); 359 break;
360 case USB_PORT_FEAT_C_ENABLE: 360 case USB_PORT_FEAT_C_ENABLE:
361 CLR_RH_PORTSTAT(USBPORTSC_PEC); 361 CLR_RH_PORTSTAT(USBPORTSC_PEC);
362 OK(0); 362 break;
363 case USB_PORT_FEAT_SUSPEND: 363 case USB_PORT_FEAT_SUSPEND:
364 if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) { 364 if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) {
365 365
@@ -382,32 +382,32 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
382 uhci->ports_timeout = jiffies + 382 uhci->ports_timeout = jiffies +
383 msecs_to_jiffies(20); 383 msecs_to_jiffies(20);
384 } 384 }
385 OK(0); 385 break;
386 case USB_PORT_FEAT_C_SUSPEND: 386 case USB_PORT_FEAT_C_SUSPEND:
387 clear_bit(port, &uhci->port_c_suspend); 387 clear_bit(port, &uhci->port_c_suspend);
388 OK(0); 388 break;
389 case USB_PORT_FEAT_POWER: 389 case USB_PORT_FEAT_POWER:
390 /* UHCI has no power switching */ 390 /* UHCI has no power switching */
391 goto err; 391 goto err;
392 case USB_PORT_FEAT_C_CONNECTION: 392 case USB_PORT_FEAT_C_CONNECTION:
393 CLR_RH_PORTSTAT(USBPORTSC_CSC); 393 CLR_RH_PORTSTAT(USBPORTSC_CSC);
394 OK(0); 394 break;
395 case USB_PORT_FEAT_C_OVER_CURRENT: 395 case USB_PORT_FEAT_C_OVER_CURRENT:
396 CLR_RH_PORTSTAT(USBPORTSC_OCC); 396 CLR_RH_PORTSTAT(USBPORTSC_OCC);
397 OK(0); 397 break;
398 case USB_PORT_FEAT_C_RESET: 398 case USB_PORT_FEAT_C_RESET:
399 /* this driver won't report these */ 399 /* this driver won't report these */
400 OK(0); 400 break;
401 default: 401 default:
402 goto err; 402 goto err;
403 } 403 }
404 break; 404 break;
405 case GetHubDescriptor: 405 case GetHubDescriptor:
406 len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); 406 retval = min_t(unsigned int, sizeof(root_hub_hub_des), wLength);
407 memcpy(buf, root_hub_hub_des, len); 407 memcpy(buf, root_hub_hub_des, retval);
408 if (len > 2) 408 if (retval > 2)
409 buf[2] = uhci->rh_numports; 409 buf[2] = uhci->rh_numports;
410 OK(len); 410 break;
411 default: 411 default:
412err: 412err:
413 retval = -EPIPE; 413 retval = -EPIPE;