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

xhci: replace real & fake port with pointer to root hub port

Variables real & fake port do not convey their purpose, thus they are
replaced with a pointer to the root hub port 'struct xhci_port *rhub_port'.
'rhub_port' contains real & fake ports in zero-based format, which happens
to be more widely used inside the xHCI driver:
- 'real_port' is ('rhub_port->hw_portnum' + 1)
- 'fake_port' is ('rhub_port->hcd_portnum' + 1)

One reason for real port being one-based, is to signal other functions in
case struct 'xhci_virt_device' initialization failed, in this case the
value will remain 0. This is no longer needed, instead we check whether
or not 'rhub_port' is 'NULL'.

Signed-off-by: Niklas Neronin <niklas.neronin@intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240229141438.619372-3-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Niklas Neronin and committed by
Greg Kroah-Hartman
06790c19 c9a63ec5

+35 -45
+3 -1
drivers/usb/host/xhci-hub.c
··· 464 464 int i; 465 465 enum usb_device_speed speed; 466 466 467 + /* 'hcd_portnum' is zero-based, thus convert one-based 'port' to zero-based */ 468 + port -= 1; 467 469 slot_id = 0; 468 470 for (i = 0; i < MAX_HC_SLOTS; i++) { 469 471 if (!xhci->devs[i] || !xhci->devs[i]->udev) 470 472 continue; 471 473 speed = xhci->devs[i]->udev->speed; 472 474 if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) 473 - && xhci->devs[i]->fake_port == port) { 475 + && xhci->devs[i]->rhub_port->hcd_portnum == port) { 474 476 slot_id = i; 475 477 break; 476 478 }
+15 -20
drivers/usb/host/xhci-mem.c
··· 789 789 bool slot_found = false; 790 790 791 791 /* If the device never made it past the Set Address stage, 792 - * it may not have the real_port set correctly. 792 + * it may not have the root hub port pointer set correctly. 793 793 */ 794 - if (virt_dev->real_port == 0 || 795 - virt_dev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) { 796 - xhci_dbg(xhci, "Bad real port.\n"); 794 + if (!virt_dev->rhub_port) { 795 + xhci_dbg(xhci, "Bad rhub port.\n"); 797 796 return; 798 797 } 799 798 800 - tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts); 799 + tt_list_head = &(xhci->rh_bw[virt_dev->rhub_port->hw_portnum].tts); 801 800 list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { 802 801 /* Multi-TT hubs will have more than one entry */ 803 802 if (tt_info->slot_id == slot_id) { ··· 833 834 goto free_tts; 834 835 INIT_LIST_HEAD(&tt_info->tt_list); 835 836 list_add(&tt_info->tt_list, 836 - &xhci->rh_bw[virt_dev->real_port - 1].tts); 837 + &xhci->rh_bw[virt_dev->rhub_port->hw_portnum].tts); 837 838 tt_info->slot_id = virt_dev->udev->slot_id; 838 839 if (tt->multi) 839 840 tt_info->ttport = i+1; ··· 928 929 if (!vdev) 929 930 return; 930 931 931 - if (vdev->real_port == 0 || 932 - vdev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) { 933 - xhci_dbg(xhci, "Bad vdev->real_port.\n"); 932 + if (!vdev->rhub_port) { 933 + xhci_dbg(xhci, "Bad rhub port.\n"); 934 934 goto out; 935 935 } 936 936 937 - tt_list_head = &(xhci->rh_bw[vdev->real_port - 1].tts); 937 + tt_list_head = &(xhci->rh_bw[vdev->rhub_port->hw_portnum].tts); 938 938 list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { 939 939 /* is this a hub device that added a tt_info to the tts list */ 940 940 if (tt_info->slot_id == slot_id) { ··· 1080 1082 struct xhci_virt_device *dev; 1081 1083 struct xhci_ep_ctx *ep0_ctx; 1082 1084 struct xhci_slot_ctx *slot_ctx; 1083 - struct xhci_port *rhub_port; 1084 1085 u32 max_packets; 1085 1086 1086 1087 dev = xhci->devs[udev->slot_id]; ··· 1121 1124 return -EINVAL; 1122 1125 } 1123 1126 /* Find the root hub port this device is under */ 1124 - rhub_port = xhci_find_rhub_port(xhci, udev); 1125 - if (!rhub_port) 1127 + dev->rhub_port = xhci_find_rhub_port(xhci, udev); 1128 + if (!dev->rhub_port) 1126 1129 return -EINVAL; 1127 - dev->real_port = rhub_port->hw_portnum + 1; 1128 - dev->fake_port = rhub_port->hcd_portnum + 1; 1129 - slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->real_port)); 1130 - xhci_dbg(xhci, "Set root hub portnum to %d\n", dev->real_port); 1131 - xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->fake_port); 1130 + slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->rhub_port->hw_portnum + 1)); 1131 + xhci_dbg(xhci, "Slot ID %d: HW portnum %d, hcd portnum %d\n", 1132 + udev->slot_id, dev->rhub_port->hw_portnum, dev->rhub_port->hcd_portnum); 1132 1133 1133 1134 /* Find the right bandwidth table that this device will be a part of. 1134 1135 * If this is a full speed device attached directly to a root port (or a ··· 1135 1140 * will never be created for the HS root hub. 1136 1141 */ 1137 1142 if (!udev->tt || !udev->tt->hub->parent) { 1138 - dev->bw_table = &xhci->rh_bw[dev->real_port - 1].bw_table; 1143 + dev->bw_table = &xhci->rh_bw[dev->rhub_port->hw_portnum].bw_table; 1139 1144 } else { 1140 1145 struct xhci_root_port_bw_info *rh_bw; 1141 1146 struct xhci_tt_bw_info *tt_bw; 1142 1147 1143 - rh_bw = &xhci->rh_bw[dev->real_port - 1]; 1148 + rh_bw = &xhci->rh_bw[dev->rhub_port->hw_portnum]; 1144 1149 /* Find the right TT. */ 1145 1150 list_for_each_entry(tt_bw, &rh_bw->tts, tt_list) { 1146 1151 if (tt_bw->slot_id != udev->tt->hub->slot_id)
+5 -9
drivers/usb/host/xhci-mtk-sch.c
··· 122 122 * each HS root port is treated as a single bandwidth domain, 123 123 * but each SS root port is treated as two bandwidth domains, one for IN eps, 124 124 * one for OUT eps. 125 - * @real_port value is defined as follow according to xHCI spec: 126 - * 1 for SSport0, ..., N+1 for SSportN, N+2 for HSport0, N+3 for HSport1, etc 127 - * so the bandwidth domain array is organized as follow for simplification: 128 - * SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY 129 125 */ 130 126 static struct mu3h_sch_bw_info * 131 127 get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev, ··· 132 136 int bw_index; 133 137 134 138 virt_dev = xhci->devs[udev->slot_id]; 135 - if (!virt_dev->real_port) { 136 - WARN_ONCE(1, "%s invalid real_port\n", dev_name(&udev->dev)); 139 + if (!virt_dev->rhub_port) { 140 + WARN_ONCE(1, "%s invalid rhub port\n", dev_name(&udev->dev)); 137 141 return NULL; 138 142 } 139 143 140 144 if (udev->speed >= USB_SPEED_SUPER) { 141 145 if (usb_endpoint_dir_out(&ep->desc)) 142 - bw_index = (virt_dev->real_port - 1) * 2; 146 + bw_index = (virt_dev->rhub_port->hw_portnum) * 2; 143 147 else 144 - bw_index = (virt_dev->real_port - 1) * 2 + 1; 148 + bw_index = (virt_dev->rhub_port->hw_portnum) * 2 + 1; 145 149 } else { 146 150 /* add one more for each SS port */ 147 - bw_index = virt_dev->real_port + xhci->usb3_rhub.num_ports - 1; 151 + bw_index = virt_dev->rhub_port->hw_portnum + xhci->usb3_rhub.num_ports; 148 152 } 149 153 150 154 return &mtk->sch_array[bw_index];
+6 -6
drivers/usb/host/xhci-trace.h
··· 172 172 __field(void *, vdev) 173 173 __field(unsigned long long, out_ctx) 174 174 __field(unsigned long long, in_ctx) 175 - __field(u8, fake_port) 176 - __field(u8, real_port) 175 + __field(int, hcd_portnum) 176 + __field(int, hw_portnum) 177 177 __field(u16, current_mel) 178 178 179 179 ), ··· 181 181 __entry->vdev = vdev; 182 182 __entry->in_ctx = (unsigned long long) vdev->in_ctx->dma; 183 183 __entry->out_ctx = (unsigned long long) vdev->out_ctx->dma; 184 - __entry->fake_port = (u8) vdev->fake_port; 185 - __entry->real_port = (u8) vdev->real_port; 184 + __entry->hcd_portnum = (int) vdev->rhub_port->hcd_portnum; 185 + __entry->hw_portnum = (int) vdev->rhub_port->hw_portnum; 186 186 __entry->current_mel = (u16) vdev->current_mel; 187 187 ), 188 - TP_printk("vdev %p ctx %llx | %llx fake_port %d real_port %d current_mel %d", 188 + TP_printk("vdev %p ctx %llx | %llx hcd_portnum %d hw_portnum %d current_mel %d", 189 189 __entry->vdev, __entry->in_ctx, __entry->out_ctx, 190 - __entry->fake_port, __entry->real_port, __entry->current_mel 190 + __entry->hcd_portnum, __entry->hw_portnum, __entry->current_mel 191 191 ) 192 192 ); 193 193
+5 -7
drivers/usb/host/xhci.c
··· 2273 2273 struct xhci_tt_bw_info *tt_info; 2274 2274 2275 2275 /* Find the bandwidth table for the root port this TT is attached to. */ 2276 - bw_table = &xhci->rh_bw[virt_dev->real_port - 1].bw_table; 2276 + bw_table = &xhci->rh_bw[virt_dev->rhub_port->hw_portnum].bw_table; 2277 2277 tt_info = virt_dev->tt_info; 2278 2278 /* If this TT already had active endpoints, the bandwidth for this TT 2279 2279 * has already been added. Removing all periodic endpoints (and thus ··· 2391 2391 if (virt_dev->tt_info) { 2392 2392 xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, 2393 2393 "Recalculating BW for rootport %u", 2394 - virt_dev->real_port); 2394 + virt_dev->rhub_port->hw_portnum + 1); 2395 2395 if (xhci_check_tt_bw_table(xhci, virt_dev, old_active_eps)) { 2396 2396 xhci_warn(xhci, "Not enough bandwidth on HS bus for " 2397 2397 "newly activated TT.\n"); ··· 2404 2404 } else { 2405 2405 xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, 2406 2406 "Recalculating BW for rootport %u", 2407 - virt_dev->real_port); 2407 + virt_dev->rhub_port->hw_portnum + 1); 2408 2408 } 2409 2409 2410 2410 /* Add in how much bandwidth will be used for interval zero, or the ··· 2501 2501 bw_used += overhead + packet_size; 2502 2502 2503 2503 if (!virt_dev->tt_info && virt_dev->udev->speed == USB_SPEED_HIGH) { 2504 - unsigned int port_index = virt_dev->real_port - 1; 2505 - 2506 2504 /* OK, we're manipulating a HS device attached to a 2507 2505 * root port bandwidth domain. Include the number of active TTs 2508 2506 * in the bandwidth used. 2509 2507 */ 2510 2508 bw_used += TT_HS_OVERHEAD * 2511 - xhci->rh_bw[port_index].num_active_tts; 2509 + xhci->rh_bw[virt_dev->rhub_port->hw_portnum].num_active_tts; 2512 2510 } 2513 2511 2514 2512 xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, ··· 2693 2695 if (!virt_dev->tt_info) 2694 2696 return; 2695 2697 2696 - rh_bw_info = &xhci->rh_bw[virt_dev->real_port - 1]; 2698 + rh_bw_info = &xhci->rh_bw[virt_dev->rhub_port->hw_portnum]; 2697 2699 if (old_active_eps == 0 && 2698 2700 virt_dev->tt_info->active_eps != 0) { 2699 2701 rh_bw_info->num_active_tts += 1;
+1 -2
drivers/usb/host/xhci.h
··· 739 739 /* Used for addressing devices and configuration changes */ 740 740 struct xhci_container_ctx *in_ctx; 741 741 struct xhci_virt_ep eps[EP_CTX_PER_DEV]; 742 - u8 fake_port; 743 - u8 real_port; 742 + struct xhci_port *rhub_port; 744 743 struct xhci_interval_bw_table *bw_table; 745 744 struct xhci_tt_bw_info *tt_info; 746 745 /*