summaryrefslogtreecommitdiffstats
path: root/drivers/usb/chipidea
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/chipidea')
-rw-r--r--drivers/usb/chipidea/host.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index e86d13c04bdb..bdc3885c0d49 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -240,15 +240,18 @@ static int ci_ehci_hub_control(
)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ unsigned int ports = HCS_N_PORTS(ehci->hcs_params);
u32 __iomem *status_reg;
- u32 temp;
+ u32 temp, port_index;
unsigned long flags;
int retval = 0;
bool done = false;
struct device *dev = hcd->self.controller;
struct ci_hdrc *ci = dev_get_drvdata(dev);
- status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1];
+ port_index = wIndex & 0xff;
+ port_index -= (port_index > 0);
+ status_reg = &ehci->regs->port_status[port_index];
spin_lock_irqsave(&ehci->lock, flags);
@@ -260,6 +263,11 @@ static int ci_ehci_hub_control(
}
if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) {
+ if (!wIndex || wIndex > ports) {
+ retval = -EPIPE;
+ goto done;
+ }
+
temp = ehci_readl(ehci, status_reg);
if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) {
retval = -EPIPE;
@@ -288,7 +296,7 @@ static int ci_ehci_hub_control(
ehci_writel(ehci, temp, status_reg);
}
- set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports);
+ set_bit(port_index, &ehci->suspended_ports);
goto done;
}