Re: [PATCH] USB: ehci_hub_control() (Kernel 2.6.21.4)
"Craig W. Nadler" <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
Alan Stern wrote: > On Sun, 10 Jun 2007, Craig W. Nadler wrote: > > >> From: Craig W. Nadler <[email protected]> >> >> EHCI_HUB_CTRL: Fixes a bug with a pointer to a port_status register. >> >> The ehci_hub_control() function in driver/usb/host/ehci-hub.c takes a >> u16 parameter called wIndex. The least significant byte of this >> parameter holds the port number relevant to the function call. The other >> byte in wIndex is sometimes used to hold another value. A pointer to the >> port_status register for the relevant port was being set using wIndex as >> a subscript to an array without masking off the other byte. This patch >> adds a local u8 variable called port_num which is set to wIndex&0xFF. >> The pointer for the port_status register is then set using port_num as >> the subscript. >> >> >> Signed-off-by: Craig W. Nadler <[email protected]> >> >> --- >> >> diff -uprN a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c >> --- a/drivers/usb/host/ehci-hub.c 2007-06-07 17:27:31.000000000 -0400 >> +++ b/drivers/usb/host/ehci-hub.c 2007-06-10 13:45:14.000000000 -0400 >> @@ -444,7 +444,8 @@ static int ehci_hub_control ( >> ) { >> struct ehci_hcd *ehci = hcd_to_ehci (hcd); >> int ports = HCS_N_PORTS (ehci->hcs_params); >> - u32 __iomem *status_reg = &ehci->regs->port_status[wIndex - 1]; >> + u8 port_num = wIndex&0xFF; >> + u32 __iomem *status_reg = &ehci->regs->port_status[port_num - 1]; >> u32 temp, status; >> unsigned long flags; >> int retval = 0; >> > > > I have some comments on the contents of this patch -- others may > comment on its formatting (or lack thereof!). > Ok, I'm not sure I know what you're referring to as far as formatting. If there is something I'm doing wrong please let me know. > First, there's no reason to make port_num u8. Compilers and CPUs work > better with word-sized types; make it unsigned. > Thanks, I've changed the patch to use an unsigned for port_num. > Second, you didn't fix enough. Although the indexing is now correct, > the code in the ClearPortFeature and related cases still checks the > value of wIndex, not the value of port_num. > Thanks, I've changed the patch to use port_num instead of wIndex in cases where wIndex contains the port number. > Third, exactly the same bug is present in all of the HCDs. Why change > only ehci-hcd? Please fix all of them. And don't forget > drivers/usb/gadget/dummy-hcd.c! > I was trying to limited the amount of code that I touched. The new patch covers all the HCDs. > Alan Stern > Please note that the new patch is untested. I'm posting it to get comments. Best Regards, Craig Nadler ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
ehci_wIndex_all.patch
(text/x-patch, 17.8 KB)
diff -uprN a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
--- a/drivers/usb/gadget/dummy_hcd.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/gadget/dummy_hcd.c 2007-06-10 20:14:04.000000000 -0400
@@ -1632,6 +1632,7 @@ static int dummy_hub_control (
struct dummy *dum;
int retval = 0;
unsigned long flags;
+ unsigned port_num = wIndex&0xFF;
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
return -ETIMEDOUT;
@@ -1667,7 +1668,7 @@ static int dummy_hub_control (
*(__le32 *) buf = __constant_cpu_to_le32 (0);
break;
case GetPortStatus:
- if (wIndex != 1)
+ if (port_num != 1)
retval = -EPIPE;
/* whoever resets or resumes must GetPortStatus to
diff -uprN a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
--- a/drivers/usb/host/ehci-hub.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/ehci-hub.c 2007-06-10 19:06:45.000000000 -0400
@@ -444,11 +444,12 @@ static int ehci_hub_control (
) {
struct ehci_hcd *ehci = hcd_to_ehci (hcd);
int ports = HCS_N_PORTS (ehci->hcs_params);
- u32 __iomem *status_reg = &ehci->regs->port_status[wIndex - 1];
+ unsigned port_num = wIndex&0xFF;
+ unsigned selector = (wIndex << 8)&0xFF;
+ u32 __iomem *status_reg = &ehci->regs->port_status[port_num - 1];
u32 temp, status;
unsigned long flags;
int retval = 0;
- unsigned selector;
/*
* FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR.
@@ -470,9 +471,9 @@ static int ehci_hub_control (
}
break;
case ClearPortFeature:
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
temp = ehci_readl(ehci, status_reg);
/*
@@ -502,7 +503,7 @@ static int ehci_hub_control (
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
ehci_writel(ehci, temp | PORT_RESUME,
status_reg);
- ehci->reset_done [wIndex] = jiffies
+ ehci->reset_done [port_num] = jiffies
+ msecs_to_jiffies (20);
}
break;
@@ -541,9 +542,9 @@ static int ehci_hub_control (
//cpu_to_le32s ((u32 *) buf);
break;
case GetPortStatus:
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
status = 0;
temp = ehci_readl(ehci, status_reg);
@@ -559,20 +560,20 @@ static int ehci_hub_control (
if (temp & PORT_RESUME) {
/* Remote Wakeup received? */
- if (!ehci->reset_done[wIndex]) {
+ if (!ehci->reset_done[port_num]) {
/* resume signaling for 20 msec */
- ehci->reset_done[wIndex] = jiffies
+ ehci->reset_done[port_num] = jiffies
+ msecs_to_jiffies(20);
/* check the port again */
mod_timer(&ehci_to_hcd(ehci)->rh_timer,
- ehci->reset_done[wIndex]);
+ ehci->reset_done[port_num]);
}
/* resume completed? */
else if (time_after_eq(jiffies,
- ehci->reset_done[wIndex])) {
+ ehci->reset_done[port_num])) {
status |= 1 << USB_PORT_FEAT_C_SUSPEND;
- ehci->reset_done[wIndex] = 0;
+ ehci->reset_done[port_num] = 0;
/* stop resume signaling */
temp = ehci_readl(ehci, status_reg);
@@ -584,7 +585,7 @@ static int ehci_hub_control (
if (retval != 0) {
ehci_err(ehci,
"port %d resume error %d\n",
- wIndex + 1, retval);
+ port_num + 1, retval);
goto error;
}
temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
@@ -594,9 +595,9 @@ static int ehci_hub_control (
/* whoever resets must GetPortStatus to complete it!! */
if ((temp & PORT_RESET)
&& time_after_eq(jiffies,
- ehci->reset_done[wIndex])) {
+ ehci->reset_done[port_num])) {
status |= 1 << USB_PORT_FEAT_C_RESET;
- ehci->reset_done [wIndex] = 0;
+ ehci->reset_done [port_num] = 0;
/* force reset to complete */
ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
@@ -608,22 +609,22 @@ static int ehci_hub_control (
PORT_RESET, 0, 750);
if (retval != 0) {
ehci_err (ehci, "port %d reset error %d\n",
- wIndex + 1, retval);
+ port_num + 1, retval);
goto error;
}
/* see what we found out */
- temp = check_reset_complete (ehci, wIndex, status_reg,
+ temp = check_reset_complete (ehci, port_num, status_reg,
ehci_readl(ehci, status_reg));
}
/* transfer dedicated ports to the companion hc */
if ((temp & PORT_CONNECT) &&
- test_bit(wIndex, &ehci->companion_ports)) {
+ test_bit(port_num, &ehci->companion_ports)) {
temp &= ~PORT_RWC_BITS;
temp |= PORT_OWNER;
ehci_writel(ehci, temp, status_reg);
- ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1);
+ ehci_dbg(ehci, "port %d --> companion\n", port_num + 1);
temp = ehci_readl(ehci, status_reg);
}
@@ -652,7 +653,7 @@ static int ehci_hub_control (
#ifndef EHCI_VERBOSE_DEBUG
if (status & ~0xffff) /* only if wPortChange is interesting */
#endif
- dbg_port (ehci, "GetStatus", wIndex + 1, temp);
+ dbg_port (ehci, "GetStatus", port_num + 1, temp);
put_unaligned(cpu_to_le32 (status), (__le32 *) buf);
break;
case SetHubFeature:
@@ -666,11 +667,9 @@ static int ehci_hub_control (
}
break;
case SetPortFeature:
- selector = wIndex >> 8;
- wIndex &= 0xff;
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
temp = ehci_readl(ehci, status_reg);
if (temp & PORT_OWNER)
break;
@@ -704,10 +703,11 @@ static int ehci_hub_control (
&& PORT_USB11 (temp)) {
ehci_dbg (ehci,
"port %d low speed --> companion\n",
- wIndex + 1);
+ port_num + 1);
temp |= PORT_OWNER;
} else {
- ehci_vdbg (ehci, "port %d reset\n", wIndex + 1);
+ ehci_vdbg (ehci, "port %d reset\n",
+ port_num + 1);
temp |= PORT_RESET;
temp &= ~PORT_PE;
@@ -715,7 +715,7 @@ static int ehci_hub_control (
* caller must wait, then call GetPortStatus
* usb 2.0 spec says 50 ms resets on root
*/
- ehci->reset_done [wIndex] = jiffies
+ ehci->reset_done [port_num] = jiffies
+ msecs_to_jiffies (50);
}
ehci_writel(ehci, temp, status_reg);
diff -uprN a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
--- a/drivers/usb/host/isp116x-hcd.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/isp116x-hcd.c 2007-06-10 19:21:57.000000000 -0400
@@ -1012,6 +1012,7 @@ static int isp116x_hub_control(struct us
int ret = 0;
unsigned long flags;
int ports = isp116x->rhdesca & RH_A_NDP;
+ unsigned port_num = wIndex&0xFF;
u32 tmp = 0;
switch (typeReq) {
@@ -1052,17 +1053,17 @@ static int isp116x_hub_control(struct us
break;
case GetPortStatus:
DBG("GetPortStatus\n");
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- tmp = isp116x->rhport[--wIndex];
+ tmp = isp116x->rhport[--port_num];
*(__le32 *) buf = cpu_to_le32(tmp);
- DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp);
+ DBG("GetPortStatus: port[%d] %08x\n", port_num + 1, tmp);
break;
case ClearPortFeature:
DBG("ClearPortFeature: ");
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
@@ -1101,40 +1102,44 @@ static int isp116x_hub_control(struct us
goto error;
}
spin_lock_irqsave(&isp116x->lock, flags);
- isp116x_write_reg32(isp116x, wIndex
- ? HCRHPORT2 : HCRHPORT1, tmp);
- isp116x->rhport[wIndex] =
- isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
+ isp116x_write_reg32(isp116x,
+ port_num ? HCRHPORT2 : HCRHPORT1, tmp);
+ isp116x->rhport[port_num] =
+ isp116x_read_reg32(isp116x,
+ port_num ? HCRHPORT2 : HCRHPORT1);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;
case SetPortFeature:
DBG("SetPortFeature: ");
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
DBG("USB_PORT_FEAT_SUSPEND\n");
spin_lock_irqsave(&isp116x->lock, flags);
- isp116x_write_reg32(isp116x, wIndex
- ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS);
+ isp116x_write_reg32(isp116x,
+ port_num ? HCRHPORT2 : HCRHPORT1,
+ RH_PS_PSS);
break;
case USB_PORT_FEAT_POWER:
DBG("USB_PORT_FEAT_POWER\n");
spin_lock_irqsave(&isp116x->lock, flags);
- isp116x_write_reg32(isp116x, wIndex
- ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS);
+ isp116x_write_reg32(isp116x,
+ port_num ? HCRHPORT2 : HCRHPORT1,
+ RH_PS_PPS);
break;
case USB_PORT_FEAT_RESET:
DBG("USB_PORT_FEAT_RESET\n");
- root_port_reset(isp116x, wIndex);
+ root_port_reset(isp116x, port_num);
spin_lock_irqsave(&isp116x->lock, flags);
break;
default:
goto error;
}
- isp116x->rhport[wIndex] =
- isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1);
+ isp116x->rhport[port_num] =
+ isp116x_read_reg32(isp116x,
+ port_num ? HCRHPORT2 : HCRHPORT1);
spin_unlock_irqrestore(&isp116x->lock, flags);
break;
diff -uprN a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
--- a/drivers/usb/host/ohci-hub.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/ohci-hub.c 2007-06-10 18:57:28.000000000 -0400
@@ -603,6 +603,7 @@ static int ohci_hub_control (
) {
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int ports = hcd_to_bus (hcd)->root_hub->maxchild;
+ unsigned port_num = wIndex&0xFF;
u32 temp;
int retval = 0;
@@ -622,9 +623,9 @@ static int ohci_hub_control (
}
break;
case ClearPortFeature:
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
switch (wValue) {
case USB_PORT_FEAT_ENABLE:
@@ -655,8 +656,9 @@ static int ohci_hub_control (
goto error;
}
ohci_writel (ohci, temp,
- &ohci->regs->roothub.portstatus [wIndex]);
- // ohci_readl (ohci, &ohci->regs->roothub.portstatus [wIndex]);
+ &ohci->regs->roothub.portstatus [port_num]);
+ // ohci_readl (ohci,
+ // &ohci->regs->roothub.portstatus [port_num]);
break;
case GetHubDescriptor:
ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
@@ -666,16 +668,16 @@ static int ohci_hub_control (
put_unaligned(cpu_to_le32 (temp), (__le32 *) buf);
break;
case GetPortStatus:
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
- temp = roothub_portstatus (ohci, wIndex);
+ port_num--;
+ temp = roothub_portstatus (ohci, port_num);
put_unaligned(cpu_to_le32 (temp), (__le32 *) buf);
#ifndef OHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */
#endif
- dbg_port (ohci, "GetStatus", wIndex, temp);
+ dbg_port (ohci, "GetStatus", port_num, temp);
break;
case SetHubFeature:
switch (wValue) {
@@ -688,26 +690,26 @@ static int ohci_hub_control (
}
break;
case SetPortFeature:
- if (!wIndex || wIndex > ports)
+ if (!port_num || port_num > ports)
goto error;
- wIndex--;
+ port_num--;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
#ifdef CONFIG_USB_OTG
- if (hcd->self.otg_port == (wIndex + 1)
+ if (hcd->self.otg_port == (port_num + 1)
&& hcd->self.b_hnp_enable)
start_hnp(ohci);
else
#endif
ohci_writel (ohci, RH_PS_PSS,
- &ohci->regs->roothub.portstatus [wIndex]);
+ &ohci->regs->roothub.portstatus [port_num]);
break;
case USB_PORT_FEAT_POWER:
ohci_writel (ohci, RH_PS_PPS,
- &ohci->regs->roothub.portstatus [wIndex]);
+ &ohci->regs->roothub.portstatus [port_num]);
break;
case USB_PORT_FEAT_RESET:
- retval = root_port_reset (ohci, wIndex);
+ retval = root_port_reset (ohci, port_num);
break;
default:
goto error;
diff -uprN a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
--- a/drivers/usb/host/ohci-s3c2410.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/ohci-s3c2410.c 2007-06-10 19:13:50.000000000 -0400
@@ -157,6 +157,7 @@ static int ohci_s3c2410_hub_control (
{
struct s3c2410_hcd_info *info = to_s3c2410_info(hcd);
struct usb_hub_descriptor *desc;
+ unsigned port_num = wIndex&0xFF;
int ret = -EINVAL;
u32 *data = (u32 *)buf;
@@ -179,7 +180,7 @@ static int ohci_s3c2410_hub_control (
case SetPortFeature:
if (wValue == USB_PORT_FEAT_POWER) {
dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
- s3c2410_usb_set_power(info, wIndex, 1);
+ s3c2410_usb_set_power(info, port_num, 1);
goto out;
}
break;
@@ -190,9 +191,9 @@ static int ohci_s3c2410_hub_control (
dev_dbg(hcd->self.controller,
"ClearPortFeature: C_OVER_CURRENT\n");
- if (valid_port(wIndex)) {
- info->port[wIndex-1].oc_changed = 0;
- info->port[wIndex-1].oc_status = 0;
+ if (valid_port(port_num)) {
+ info->port[port_num-1].oc_changed = 0;
+ info->port[port_num-1].oc_status = 0;
}
goto out;
@@ -201,8 +202,8 @@ static int ohci_s3c2410_hub_control (
dev_dbg(hcd->self.controller,
"ClearPortFeature: OVER_CURRENT\n");
- if (valid_port(wIndex)) {
- info->port[wIndex-1].oc_status = 0;
+ if (valid_port(port_num)) {
+ info->port[port_num-1].oc_status = 0;
}
goto out;
@@ -211,15 +212,15 @@ static int ohci_s3c2410_hub_control (
dev_dbg(hcd->self.controller,
"ClearPortFeature: POWER\n");
- if (valid_port(wIndex)) {
- s3c2410_usb_set_power(info, wIndex, 0);
+ if (valid_port(port_num)) {
+ s3c2410_usb_set_power(info, port_num, 0);
return 0;
}
}
break;
}
- ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
+ ret = ohci_hub_control(hcd, typeReq, wValue, port_num, buf, wLength);
if (ret)
goto out;
@@ -256,14 +257,14 @@ static int ohci_s3c2410_hub_control (
case GetPortStatus:
/* check port status */
- dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
+ dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", port_num);
- if (valid_port(wIndex)) {
- if (info->port[wIndex-1].oc_changed) {
+ if (valid_port(port_num)) {
+ if (info->port[port_num-1].oc_changed) {
*data |= cpu_to_le32(RH_PS_OCIC);
}
- if (info->port[wIndex-1].oc_status) {
+ if (info->port[port_num-1].oc_status) {
*data |= cpu_to_le32(RH_PS_POCI);
}
}
diff -uprN a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
--- a/drivers/usb/host/sl811-hcd.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/sl811-hcd.c 2007-06-10 20:20:22.000000000 -0400
@@ -1230,6 +1230,7 @@ sl811h_hub_control(
struct sl811 *sl811 = hcd_to_sl811(hcd);
int retval = 0;
unsigned long flags;
+ unsigned port_num = wIndex&0xFF;
spin_lock_irqsave(&sl811->lock, flags);
@@ -1245,7 +1246,7 @@ sl811h_hub_control(
}
break;
case ClearPortFeature:
- if (wIndex != 1 || wLength != 0)
+ if (port_num != 1 || wLength != 0)
goto error;
switch (wValue) {
@@ -1293,7 +1294,7 @@ sl811h_hub_control(
*(__le32 *) buf = cpu_to_le32(0);
break;
case GetPortStatus:
- if (wIndex != 1)
+ if (port_num != 1)
goto error;
*(__le32 *) buf = cpu_to_le32(sl811->port1);
@@ -1303,7 +1304,7 @@ sl811h_hub_control(
DBG("GetPortStatus %08x\n", sl811->port1);
break;
case SetPortFeature:
- if (wIndex != 1 || wLength != 0)
+ if (port_num != 1 || wLength != 0)
goto error;
switch (wValue) {
case USB_PORT_FEAT_SUSPEND:
diff -uprN a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
--- a/drivers/usb/host/u132-hcd.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/u132-hcd.c 2007-06-10 20:41:01.000000000 -0400
@@ -2577,10 +2577,12 @@ static int u132_roothub_status(struct u1
static int u132_roothub_portstatus(struct u132 *u132, __le32 *desc, u16 wIndex)
{
- if (wIndex == 0 || wIndex > u132->num_ports) {
+ unsigned port_num = wIndex&0xFF;
+
+ if (port_num == 0 || port_num > u132->num_ports) {
return -EINVAL;
} else {
- int port = wIndex - 1;
+ int port = port_num - 1;
u32 rh_portstatus = -1;
int ret_portstatus = u132_read_pcimem(u132,
roothub.portstatus[port], &rh_portstatus);
@@ -2651,11 +2653,13 @@ static int u132_roothub_portreset(struct
static int u132_roothub_setportfeature(struct u132 *u132, u16 wValue,
u16 wIndex)
{
- if (wIndex == 0 || wIndex > u132->num_ports) {
+ unsigned port_num = wIndex&0xFF;
+
+ if (port_num == 0 || port_num > u132->num_ports) {
return -EINVAL;
} else {
int retval;
- int port_index = wIndex - 1;
+ int port_index = port_num - 1;
struct u132_port *port = &u132->port[port_index];
port->Status &= ~(1 << wValue);
switch (wValue) {
@@ -2685,10 +2689,12 @@ static int u132_roothub_setportfeature(s
static int u132_roothub_clearportfeature(struct u132 *u132, u16 wValue,
u16 wIndex)
{
- if (wIndex == 0 || wIndex > u132->num_ports) {
+ unsigned port_num = wIndex&0xFF;
+
+ if (port_num == 0 || port_num > u132->num_ports) {
return -EINVAL;
} else {
- int port_index = wIndex - 1;
+ int port_index = port_num - 1;
u32 temp;
int retval;
struct u132_port *port = &u132->port[port_index];
diff -uprN a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
--- a/drivers/usb/host/uhci-hub.c 2007-06-07 17:27:31.000000000 -0400
+++ b/drivers/usb/host/uhci-hub.c 2007-06-10 21:33:47.000000000 -0400
@@ -241,7 +241,7 @@ static int uhci_hub_control(struct usb_h
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
int status, lstatus, retval = 0, len = 0;
- unsigned int port = wIndex - 1;
+ unsigned int port = (wIndex&0xFF) - 1;
unsigned long port_addr = uhci->io_addr + USBPORTSC1 + 2 * port;
u16 wPortChange, wPortStatus;
unsigned long flags;
@@ -304,7 +304,7 @@ static int uhci_hub_control(struct usb_h
if (wPortChange)
dev_dbg(uhci_dev(uhci), "port %d portsc %04x,%02x\n",
- wIndex, status, lstatus);
+ port, status, lstatus);
*(__le16 *)buf = cpu_to_le16(wPortStatus);
*(__le16 *)(buf + 2) = cpu_to_le16(wPortChange);