Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

usb: xhci: stop treating 'wIndex' as a mutable port number

The USB request parameter 'wIndex' is a 16-bit field whose meaning depends
on the request type. For hub port operations, only bits 7:0 encode the port
number (1..MaxPorts). Despite this, the current code extracts the port
number into 'portnum1' while also modifying and using 'wIndex' directly as
a 0-based port index. This dual use is both confusing and error-prone,
since 'wIndex' is not always a pure port number.

Clean this up by deriving a single 0-based 'portnum' from 'wIndex' and
using it throughout the function. The original 'wIndex' value is no longer
modified or treated as a port number. This also matches existing xhci code.

Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260402131342.2628648-14-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Niklas Neronin and committed by
Greg Kroah-Hartman
1e6138c0 2a70e5dc

+30 -35
+30 -35
drivers/usb/host/xhci-hub.c
··· 1218 1218 struct xhci_hub *rhub; 1219 1219 struct xhci_port **ports; 1220 1220 struct xhci_port *port; 1221 - int portnum1; 1221 + int portnum; 1222 1222 1223 1223 rhub = xhci_get_rhub(hcd); 1224 1224 ports = rhub->ports; 1225 1225 max_ports = rhub->num_ports; 1226 1226 bus_state = &rhub->bus_state; 1227 - portnum1 = wIndex & 0xff; 1228 1227 1229 1228 spin_lock_irqsave(&xhci->lock, flags); 1230 1229 switch (typeReq) { ··· 1257 1258 spin_unlock_irqrestore(&xhci->lock, flags); 1258 1259 return retval; 1259 1260 case GetPortStatus: 1260 - if (!portnum1 || portnum1 > max_ports) 1261 + portnum = (wIndex & 0xff) - 1; 1262 + if (!in_range(portnum, 0, max_ports)) 1261 1263 goto error; 1262 1264 1263 - wIndex--; 1264 - port = ports[portnum1 - 1]; 1265 + port = ports[portnum]; 1265 1266 temp = xhci_portsc_readl(port); 1266 1267 if (temp == ~(u32)0) { 1267 1268 xhci_hc_died(xhci); ··· 1269 1270 break; 1270 1271 } 1271 1272 trace_xhci_get_port_status(port, temp); 1272 - status = xhci_get_port_status(hcd, bus_state, wIndex, temp, 1273 - &flags); 1273 + status = xhci_get_port_status(hcd, bus_state, portnum, temp, &flags); 1274 1274 if (status == 0xffffffff) 1275 1275 goto error; 1276 1276 1277 1277 xhci_dbg(xhci, "Get port status %d-%d read: 0x%x, return 0x%x", 1278 - hcd->self.busnum, portnum1, temp, status); 1278 + hcd->self.busnum, portnum + 1, temp, status); 1279 1279 1280 1280 put_unaligned(cpu_to_le32(status), (__le32 *) buf); 1281 1281 /* if USB 3.1 extended port status return additional 4 bytes */ ··· 1301 1303 /* The MSB of wIndex is the U1/U2 timeout */ 1302 1304 timeout = (wIndex & 0xff00) >> 8; 1303 1305 1304 - wIndex &= 0xff; 1305 - if (!portnum1 || portnum1 > max_ports) 1306 + portnum = (wIndex & 0xff) - 1; 1307 + if (!in_range(portnum, 0, max_ports)) 1306 1308 goto error; 1307 1309 1308 - port = ports[portnum1 - 1]; 1309 - wIndex--; 1310 + port = ports[portnum]; 1310 1311 temp = xhci_portsc_readl(port); 1311 1312 if (temp == ~(u32)0) { 1312 1313 xhci_hc_died(xhci); ··· 1332 1335 if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) 1333 1336 || (temp & PORT_PLS_MASK) >= XDEV_U3) { 1334 1337 xhci_warn(xhci, "USB core suspending port %d-%d not in U0/U1/U2\n", 1335 - hcd->self.busnum, portnum1); 1338 + hcd->self.busnum, portnum + 1); 1336 1339 goto error; 1337 1340 } 1338 1341 ··· 1352 1355 spin_lock_irqsave(&xhci->lock, flags); 1353 1356 1354 1357 temp = xhci_portsc_readl(port); 1355 - bus_state->suspended_ports |= 1 << wIndex; 1358 + bus_state->suspended_ports |= 1 << portnum; 1356 1359 break; 1357 1360 case USB_PORT_FEAT_LINK_STATE: 1358 1361 temp = xhci_portsc_readl(port); 1359 1362 /* Disable port */ 1360 1363 if (link_state == USB_SS_PORT_LS_SS_DISABLED) { 1361 1364 xhci_dbg(xhci, "Disable port %d-%d\n", 1362 - hcd->self.busnum, portnum1); 1365 + hcd->self.busnum, portnum + 1); 1363 1366 temp = xhci_port_state_to_neutral(temp); 1364 1367 /* 1365 1368 * Clear all change bits, so that we get a new ··· 1376 1379 /* Put link in RxDetect (enable port) */ 1377 1380 if (link_state == USB_SS_PORT_LS_RX_DETECT) { 1378 1381 xhci_dbg(xhci, "Enable port %d-%d\n", 1379 - hcd->self.busnum, portnum1); 1382 + hcd->self.busnum, portnum + 1); 1380 1383 xhci_set_link_state(xhci, port, link_state); 1381 1384 temp = xhci_portsc_readl(port); 1382 1385 break; ··· 1408 1411 } 1409 1412 1410 1413 xhci_dbg(xhci, "Enable compliance mode transition for port %d-%d\n", 1411 - hcd->self.busnum, portnum1); 1414 + hcd->self.busnum, portnum + 1); 1412 1415 xhci_set_link_state(xhci, port, link_state); 1413 1416 1414 1417 temp = xhci_portsc_readl(port); ··· 1422 1425 /* Can't set port link state above '3' (U3) */ 1423 1426 if (link_state > USB_SS_PORT_LS_U3) { 1424 1427 xhci_warn(xhci, "Cannot set port %d-%d link state %d\n", 1425 - hcd->self.busnum, portnum1, link_state); 1428 + hcd->self.busnum, portnum + 1, link_state); 1426 1429 goto error; 1427 1430 } 1428 1431 ··· 1457 1460 if (!wait_for_completion_timeout(&port->u3exit_done, 1458 1461 msecs_to_jiffies(500))) 1459 1462 xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n", 1460 - hcd->self.busnum, portnum1); 1463 + hcd->self.busnum, portnum + 1); 1461 1464 spin_lock_irqsave(&xhci->lock, flags); 1462 1465 temp = xhci_portsc_readl(port); 1463 1466 break; ··· 1483 1486 } 1484 1487 spin_lock_irqsave(&xhci->lock, flags); 1485 1488 temp = xhci_portsc_readl(port); 1486 - bus_state->suspended_ports |= 1 << wIndex; 1489 + bus_state->suspended_ports |= 1 << portnum; 1487 1490 } 1488 1491 break; 1489 1492 case USB_PORT_FEAT_POWER: ··· 1501 1504 1502 1505 temp = xhci_portsc_readl(port); 1503 1506 xhci_dbg(xhci, "set port reset, actual port %d-%d status = 0x%x\n", 1504 - hcd->self.busnum, portnum1, temp); 1507 + hcd->self.busnum, portnum + 1, temp); 1505 1508 break; 1506 1509 case USB_PORT_FEAT_REMOTE_WAKE_MASK: 1507 1510 xhci_set_remote_wake_mask(xhci, port, wake_mask); 1508 1511 temp = xhci_portsc_readl(port); 1509 1512 xhci_dbg(xhci, "set port remote wake mask, actual port %d-%d status = 0x%x\n", 1510 - hcd->self.busnum, portnum1, temp); 1513 + hcd->self.busnum, portnum + 1, temp); 1511 1514 break; 1512 1515 case USB_PORT_FEAT_BH_PORT_RESET: 1513 1516 temp |= PORT_WR; ··· 1537 1540 if (test_mode > USB_TEST_FORCE_ENABLE || 1538 1541 test_mode < USB_TEST_J) 1539 1542 goto error; 1540 - retval = xhci_enter_test_mode(xhci, test_mode, wIndex, 1541 - &flags); 1543 + retval = xhci_enter_test_mode(xhci, test_mode, portnum, &flags); 1542 1544 break; 1543 1545 default: 1544 1546 goto error; ··· 1546 1550 temp = xhci_portsc_readl(port); 1547 1551 break; 1548 1552 case ClearPortFeature: 1549 - if (!portnum1 || portnum1 > max_ports) 1553 + portnum = (wIndex & 0xff) - 1; 1554 + if (!in_range(portnum, 0, max_ports)) 1550 1555 goto error; 1551 1556 1552 - port = ports[portnum1 - 1]; 1553 - 1554 - wIndex--; 1557 + port = ports[portnum]; 1555 1558 temp = xhci_portsc_readl(port); 1556 1559 if (temp == ~(u32)0) { 1557 1560 xhci_hc_died(xhci); ··· 1570 1575 if ((temp & PORT_PE) == 0) 1571 1576 goto error; 1572 1577 1573 - set_bit(wIndex, &bus_state->resuming_ports); 1574 - usb_hcd_start_port_resume(&hcd->self, wIndex); 1578 + set_bit(portnum, &bus_state->resuming_ports); 1579 + usb_hcd_start_port_resume(&hcd->self, portnum); 1575 1580 xhci_set_link_state(xhci, port, XDEV_RESUME); 1576 1581 spin_unlock_irqrestore(&xhci->lock, flags); 1577 1582 msleep(USB_RESUME_TIMEOUT); 1578 1583 spin_lock_irqsave(&xhci->lock, flags); 1579 1584 xhci_set_link_state(xhci, port, XDEV_U0); 1580 - clear_bit(wIndex, &bus_state->resuming_ports); 1581 - usb_hcd_end_port_resume(&hcd->self, wIndex); 1585 + clear_bit(portnum, &bus_state->resuming_ports); 1586 + usb_hcd_end_port_resume(&hcd->self, portnum); 1582 1587 } 1583 - bus_state->port_c_suspend |= 1 << wIndex; 1588 + bus_state->port_c_suspend |= 1 << portnum; 1584 1589 1585 1590 if (!port->slot_id) { 1586 1591 xhci_dbg(xhci, "slot_id is zero\n"); ··· 1589 1594 xhci_ring_device(xhci, port->slot_id); 1590 1595 break; 1591 1596 case USB_PORT_FEAT_C_SUSPEND: 1592 - bus_state->port_c_suspend &= ~(1 << wIndex); 1597 + bus_state->port_c_suspend &= ~(1 << portnum); 1593 1598 fallthrough; 1594 1599 case USB_PORT_FEAT_C_RESET: 1595 1600 case USB_PORT_FEAT_C_BH_PORT_RESET: ··· 1598 1603 case USB_PORT_FEAT_C_ENABLE: 1599 1604 case USB_PORT_FEAT_C_PORT_LINK_STATE: 1600 1605 case USB_PORT_FEAT_C_PORT_CONFIG_ERROR: 1601 - xhci_clear_port_change_bit(xhci, wValue, wIndex, port, temp); 1606 + xhci_clear_port_change_bit(xhci, wValue, portnum, port, temp); 1602 1607 break; 1603 1608 case USB_PORT_FEAT_ENABLE: 1604 1609 xhci_disable_port(xhci, port);