Commit 06790c19 authored by Niklas Neronin's avatar Niklas Neronin Committed by Greg Kroah-Hartman

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: default avatarNiklas Neronin <niklas.neronin@intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20240229141438.619372-3-mathias.nyman@linux.intel.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c9a63ec5
...@@ -464,13 +464,15 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, ...@@ -464,13 +464,15 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
int i; int i;
enum usb_device_speed speed; enum usb_device_speed speed;
/* 'hcd_portnum' is zero-based, thus convert one-based 'port' to zero-based */
port -= 1;
slot_id = 0; slot_id = 0;
for (i = 0; i < MAX_HC_SLOTS; i++) { for (i = 0; i < MAX_HC_SLOTS; i++) {
if (!xhci->devs[i] || !xhci->devs[i]->udev) if (!xhci->devs[i] || !xhci->devs[i]->udev)
continue; continue;
speed = xhci->devs[i]->udev->speed; speed = xhci->devs[i]->udev->speed;
if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3))
&& xhci->devs[i]->fake_port == port) { && xhci->devs[i]->rhub_port->hcd_portnum == port) {
slot_id = i; slot_id = i;
break; break;
} }
......
...@@ -789,15 +789,14 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci, ...@@ -789,15 +789,14 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci,
bool slot_found = false; bool slot_found = false;
/* If the device never made it past the Set Address stage, /* If the device never made it past the Set Address stage,
* it may not have the real_port set correctly. * it may not have the root hub port pointer set correctly.
*/ */
if (virt_dev->real_port == 0 || if (!virt_dev->rhub_port) {
virt_dev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) { xhci_dbg(xhci, "Bad rhub port.\n");
xhci_dbg(xhci, "Bad real port.\n");
return; return;
} }
tt_list_head = &(xhci->rh_bw[virt_dev->real_port - 1].tts); tt_list_head = &(xhci->rh_bw[virt_dev->rhub_port->hw_portnum].tts);
list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
/* Multi-TT hubs will have more than one entry */ /* Multi-TT hubs will have more than one entry */
if (tt_info->slot_id == slot_id) { if (tt_info->slot_id == slot_id) {
...@@ -834,7 +833,7 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci, ...@@ -834,7 +833,7 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci,
goto free_tts; goto free_tts;
INIT_LIST_HEAD(&tt_info->tt_list); INIT_LIST_HEAD(&tt_info->tt_list);
list_add(&tt_info->tt_list, list_add(&tt_info->tt_list,
&xhci->rh_bw[virt_dev->real_port - 1].tts); &xhci->rh_bw[virt_dev->rhub_port->hw_portnum].tts);
tt_info->slot_id = virt_dev->udev->slot_id; tt_info->slot_id = virt_dev->udev->slot_id;
if (tt->multi) if (tt->multi)
tt_info->ttport = i+1; tt_info->ttport = i+1;
...@@ -929,13 +928,12 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i ...@@ -929,13 +928,12 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i
if (!vdev) if (!vdev)
return; return;
if (vdev->real_port == 0 || if (!vdev->rhub_port) {
vdev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) { xhci_dbg(xhci, "Bad rhub port.\n");
xhci_dbg(xhci, "Bad vdev->real_port.\n");
goto out; goto out;
} }
tt_list_head = &(xhci->rh_bw[vdev->real_port - 1].tts); tt_list_head = &(xhci->rh_bw[vdev->rhub_port->hw_portnum].tts);
list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) { list_for_each_entry_safe(tt_info, next, tt_list_head, tt_list) {
/* is this a hub device that added a tt_info to the tts list */ /* is this a hub device that added a tt_info to the tts list */
if (tt_info->slot_id == slot_id) { if (tt_info->slot_id == slot_id) {
...@@ -1082,7 +1080,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud ...@@ -1082,7 +1080,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
struct xhci_virt_device *dev; struct xhci_virt_device *dev;
struct xhci_ep_ctx *ep0_ctx; struct xhci_ep_ctx *ep0_ctx;
struct xhci_slot_ctx *slot_ctx; struct xhci_slot_ctx *slot_ctx;
struct xhci_port *rhub_port;
u32 max_packets; u32 max_packets;
dev = xhci->devs[udev->slot_id]; dev = xhci->devs[udev->slot_id];
...@@ -1124,14 +1121,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud ...@@ -1124,14 +1121,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
return -EINVAL; return -EINVAL;
} }
/* Find the root hub port this device is under */ /* Find the root hub port this device is under */
rhub_port = xhci_find_rhub_port(xhci, udev); dev->rhub_port = xhci_find_rhub_port(xhci, udev);
if (!rhub_port) if (!dev->rhub_port)
return -EINVAL; return -EINVAL;
dev->real_port = rhub_port->hw_portnum + 1; slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->rhub_port->hw_portnum + 1));
dev->fake_port = rhub_port->hcd_portnum + 1; xhci_dbg(xhci, "Slot ID %d: HW portnum %d, hcd portnum %d\n",
slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->real_port)); udev->slot_id, dev->rhub_port->hw_portnum, dev->rhub_port->hcd_portnum);
xhci_dbg(xhci, "Set root hub portnum to %d\n", dev->real_port);
xhci_dbg(xhci, "Set fake root hub portnum to %d\n", dev->fake_port);
/* Find the right bandwidth table that this device will be a part of. /* Find the right bandwidth table that this device will be a part of.
* If this is a full speed device attached directly to a root port (or a * If this is a full speed device attached directly to a root port (or a
...@@ -1140,12 +1135,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud ...@@ -1140,12 +1135,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
* will never be created for the HS root hub. * will never be created for the HS root hub.
*/ */
if (!udev->tt || !udev->tt->hub->parent) { if (!udev->tt || !udev->tt->hub->parent) {
dev->bw_table = &xhci->rh_bw[dev->real_port - 1].bw_table; dev->bw_table = &xhci->rh_bw[dev->rhub_port->hw_portnum].bw_table;
} else { } else {
struct xhci_root_port_bw_info *rh_bw; struct xhci_root_port_bw_info *rh_bw;
struct xhci_tt_bw_info *tt_bw; struct xhci_tt_bw_info *tt_bw;
rh_bw = &xhci->rh_bw[dev->real_port - 1]; rh_bw = &xhci->rh_bw[dev->rhub_port->hw_portnum];
/* Find the right TT. */ /* Find the right TT. */
list_for_each_entry(tt_bw, &rh_bw->tts, tt_list) { list_for_each_entry(tt_bw, &rh_bw->tts, tt_list) {
if (tt_bw->slot_id != udev->tt->hub->slot_id) if (tt_bw->slot_id != udev->tt->hub->slot_id)
......
...@@ -122,10 +122,6 @@ static u32 get_bw_boundary(enum usb_device_speed speed) ...@@ -122,10 +122,6 @@ static u32 get_bw_boundary(enum usb_device_speed speed)
* each HS root port is treated as a single bandwidth domain, * each HS root port is treated as a single bandwidth domain,
* but each SS root port is treated as two bandwidth domains, one for IN eps, * but each SS root port is treated as two bandwidth domains, one for IN eps,
* one for OUT eps. * one for OUT eps.
* @real_port value is defined as follow according to xHCI spec:
* 1 for SSport0, ..., N+1 for SSportN, N+2 for HSport0, N+3 for HSport1, etc
* so the bandwidth domain array is organized as follow for simplification:
* SSport0-OUT, SSport0-IN, ..., SSportX-OUT, SSportX-IN, HSport0, ..., HSportY
*/ */
static struct mu3h_sch_bw_info * static struct mu3h_sch_bw_info *
get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev, get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
...@@ -136,19 +132,19 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev, ...@@ -136,19 +132,19 @@ get_bw_info(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
int bw_index; int bw_index;
virt_dev = xhci->devs[udev->slot_id]; virt_dev = xhci->devs[udev->slot_id];
if (!virt_dev->real_port) { if (!virt_dev->rhub_port) {
WARN_ONCE(1, "%s invalid real_port\n", dev_name(&udev->dev)); WARN_ONCE(1, "%s invalid rhub port\n", dev_name(&udev->dev));
return NULL; return NULL;
} }
if (udev->speed >= USB_SPEED_SUPER) { if (udev->speed >= USB_SPEED_SUPER) {
if (usb_endpoint_dir_out(&ep->desc)) if (usb_endpoint_dir_out(&ep->desc))
bw_index = (virt_dev->real_port - 1) * 2; bw_index = (virt_dev->rhub_port->hw_portnum) * 2;
else else
bw_index = (virt_dev->real_port - 1) * 2 + 1; bw_index = (virt_dev->rhub_port->hw_portnum) * 2 + 1;
} else { } else {
/* add one more for each SS port */ /* add one more for each SS port */
bw_index = virt_dev->real_port + xhci->usb3_rhub.num_ports - 1; bw_index = virt_dev->rhub_port->hw_portnum + xhci->usb3_rhub.num_ports;
} }
return &mtk->sch_array[bw_index]; return &mtk->sch_array[bw_index];
......
...@@ -172,8 +172,8 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev, ...@@ -172,8 +172,8 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
__field(void *, vdev) __field(void *, vdev)
__field(unsigned long long, out_ctx) __field(unsigned long long, out_ctx)
__field(unsigned long long, in_ctx) __field(unsigned long long, in_ctx)
__field(u8, fake_port) __field(int, hcd_portnum)
__field(u8, real_port) __field(int, hw_portnum)
__field(u16, current_mel) __field(u16, current_mel)
), ),
...@@ -181,13 +181,13 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev, ...@@ -181,13 +181,13 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
__entry->vdev = vdev; __entry->vdev = vdev;
__entry->in_ctx = (unsigned long long) vdev->in_ctx->dma; __entry->in_ctx = (unsigned long long) vdev->in_ctx->dma;
__entry->out_ctx = (unsigned long long) vdev->out_ctx->dma; __entry->out_ctx = (unsigned long long) vdev->out_ctx->dma;
__entry->fake_port = (u8) vdev->fake_port; __entry->hcd_portnum = (int) vdev->rhub_port->hcd_portnum;
__entry->real_port = (u8) vdev->real_port; __entry->hw_portnum = (int) vdev->rhub_port->hw_portnum;
__entry->current_mel = (u16) vdev->current_mel; __entry->current_mel = (u16) vdev->current_mel;
), ),
TP_printk("vdev %p ctx %llx | %llx fake_port %d real_port %d current_mel %d", TP_printk("vdev %p ctx %llx | %llx hcd_portnum %d hw_portnum %d current_mel %d",
__entry->vdev, __entry->in_ctx, __entry->out_ctx, __entry->vdev, __entry->in_ctx, __entry->out_ctx,
__entry->fake_port, __entry->real_port, __entry->current_mel __entry->hcd_portnum, __entry->hw_portnum, __entry->current_mel
) )
); );
......
...@@ -2273,7 +2273,7 @@ static int xhci_check_tt_bw_table(struct xhci_hcd *xhci, ...@@ -2273,7 +2273,7 @@ static int xhci_check_tt_bw_table(struct xhci_hcd *xhci,
struct xhci_tt_bw_info *tt_info; struct xhci_tt_bw_info *tt_info;
/* Find the bandwidth table for the root port this TT is attached to. */ /* Find the bandwidth table for the root port this TT is attached to. */
bw_table = &xhci->rh_bw[virt_dev->real_port - 1].bw_table; bw_table = &xhci->rh_bw[virt_dev->rhub_port->hw_portnum].bw_table;
tt_info = virt_dev->tt_info; tt_info = virt_dev->tt_info;
/* If this TT already had active endpoints, the bandwidth for this TT /* If this TT already had active endpoints, the bandwidth for this TT
* has already been added. Removing all periodic endpoints (and thus * has already been added. Removing all periodic endpoints (and thus
...@@ -2391,7 +2391,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci, ...@@ -2391,7 +2391,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
if (virt_dev->tt_info) { if (virt_dev->tt_info) {
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Recalculating BW for rootport %u", "Recalculating BW for rootport %u",
virt_dev->real_port); virt_dev->rhub_port->hw_portnum + 1);
if (xhci_check_tt_bw_table(xhci, virt_dev, old_active_eps)) { if (xhci_check_tt_bw_table(xhci, virt_dev, old_active_eps)) {
xhci_warn(xhci, "Not enough bandwidth on HS bus for " xhci_warn(xhci, "Not enough bandwidth on HS bus for "
"newly activated TT.\n"); "newly activated TT.\n");
...@@ -2404,7 +2404,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci, ...@@ -2404,7 +2404,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
} else { } else {
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Recalculating BW for rootport %u", "Recalculating BW for rootport %u",
virt_dev->real_port); virt_dev->rhub_port->hw_portnum + 1);
} }
/* Add in how much bandwidth will be used for interval zero, or the /* Add in how much bandwidth will be used for interval zero, or the
...@@ -2501,14 +2501,12 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci, ...@@ -2501,14 +2501,12 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
bw_used += overhead + packet_size; bw_used += overhead + packet_size;
if (!virt_dev->tt_info && virt_dev->udev->speed == USB_SPEED_HIGH) { if (!virt_dev->tt_info && virt_dev->udev->speed == USB_SPEED_HIGH) {
unsigned int port_index = virt_dev->real_port - 1;
/* OK, we're manipulating a HS device attached to a /* OK, we're manipulating a HS device attached to a
* root port bandwidth domain. Include the number of active TTs * root port bandwidth domain. Include the number of active TTs
* in the bandwidth used. * in the bandwidth used.
*/ */
bw_used += TT_HS_OVERHEAD * bw_used += TT_HS_OVERHEAD *
xhci->rh_bw[port_index].num_active_tts; xhci->rh_bw[virt_dev->rhub_port->hw_portnum].num_active_tts;
} }
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
...@@ -2695,7 +2693,7 @@ void xhci_update_tt_active_eps(struct xhci_hcd *xhci, ...@@ -2695,7 +2693,7 @@ void xhci_update_tt_active_eps(struct xhci_hcd *xhci,
if (!virt_dev->tt_info) if (!virt_dev->tt_info)
return; return;
rh_bw_info = &xhci->rh_bw[virt_dev->real_port - 1]; rh_bw_info = &xhci->rh_bw[virt_dev->rhub_port->hw_portnum];
if (old_active_eps == 0 && if (old_active_eps == 0 &&
virt_dev->tt_info->active_eps != 0) { virt_dev->tt_info->active_eps != 0) {
rh_bw_info->num_active_tts += 1; rh_bw_info->num_active_tts += 1;
......
...@@ -739,8 +739,7 @@ struct xhci_virt_device { ...@@ -739,8 +739,7 @@ struct xhci_virt_device {
/* Used for addressing devices and configuration changes */ /* Used for addressing devices and configuration changes */
struct xhci_container_ctx *in_ctx; struct xhci_container_ctx *in_ctx;
struct xhci_virt_ep eps[EP_CTX_PER_DEV]; struct xhci_virt_ep eps[EP_CTX_PER_DEV];
u8 fake_port; struct xhci_port *rhub_port;
u8 real_port;
struct xhci_interval_bw_table *bw_table; struct xhci_interval_bw_table *bw_table;
struct xhci_tt_bw_info *tt_info; struct xhci_tt_bw_info *tt_info;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment