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>
This commit is contained in:
parent
c9a63ec5d2
commit
06790c1908
@ -464,13 +464,15 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
|
||||
int i;
|
||||
enum usb_device_speed speed;
|
||||
|
||||
/* 'hcd_portnum' is zero-based, thus convert one-based 'port' to zero-based */
|
||||
port -= 1;
|
||||
slot_id = 0;
|
||||
for (i = 0; i < MAX_HC_SLOTS; i++) {
|
||||
if (!xhci->devs[i] || !xhci->devs[i]->udev)
|
||||
continue;
|
||||
speed = xhci->devs[i]->udev->speed;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -789,15 +789,14 @@ static void xhci_free_tt_info(struct xhci_hcd *xhci,
|
||||
bool slot_found = false;
|
||||
|
||||
/* 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 ||
|
||||
virt_dev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) {
|
||||
xhci_dbg(xhci, "Bad real port.\n");
|
||||
if (!virt_dev->rhub_port) {
|
||||
xhci_dbg(xhci, "Bad rhub port.\n");
|
||||
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) {
|
||||
/* Multi-TT hubs will have more than one entry */
|
||||
if (tt_info->slot_id == slot_id) {
|
||||
@ -834,7 +833,7 @@ int xhci_alloc_tt_info(struct xhci_hcd *xhci,
|
||||
goto free_tts;
|
||||
INIT_LIST_HEAD(&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;
|
||||
if (tt->multi)
|
||||
tt_info->ttport = i+1;
|
||||
@ -929,13 +928,12 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i
|
||||
if (!vdev)
|
||||
return;
|
||||
|
||||
if (vdev->real_port == 0 ||
|
||||
vdev->real_port > HCS_MAX_PORTS(xhci->hcs_params1)) {
|
||||
xhci_dbg(xhci, "Bad vdev->real_port.\n");
|
||||
if (!vdev->rhub_port) {
|
||||
xhci_dbg(xhci, "Bad rhub port.\n");
|
||||
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) {
|
||||
/* is this a hub device that added a tt_info to the tts list */
|
||||
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
|
||||
struct xhci_virt_device *dev;
|
||||
struct xhci_ep_ctx *ep0_ctx;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
struct xhci_port *rhub_port;
|
||||
u32 max_packets;
|
||||
|
||||
dev = xhci->devs[udev->slot_id];
|
||||
@ -1124,14 +1121,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Find the root hub port this device is under */
|
||||
rhub_port = xhci_find_rhub_port(xhci, udev);
|
||||
if (!rhub_port)
|
||||
dev->rhub_port = xhci_find_rhub_port(xhci, udev);
|
||||
if (!dev->rhub_port)
|
||||
return -EINVAL;
|
||||
dev->real_port = rhub_port->hw_portnum + 1;
|
||||
dev->fake_port = rhub_port->hcd_portnum + 1;
|
||||
slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->real_port));
|
||||
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);
|
||||
slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->rhub_port->hw_portnum + 1));
|
||||
xhci_dbg(xhci, "Slot ID %d: HW portnum %d, hcd portnum %d\n",
|
||||
udev->slot_id, dev->rhub_port->hw_portnum, dev->rhub_port->hcd_portnum);
|
||||
|
||||
/* 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
|
||||
@ -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.
|
||||
*/
|
||||
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 {
|
||||
struct xhci_root_port_bw_info *rh_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. */
|
||||
list_for_each_entry(tt_bw, &rh_bw->tts, tt_list) {
|
||||
if (tt_bw->slot_id != udev->tt->hub->slot_id)
|
||||
|
@ -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,
|
||||
* but each SS root port is treated as two bandwidth domains, one for IN 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 *
|
||||
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;
|
||||
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
if (!virt_dev->real_port) {
|
||||
WARN_ONCE(1, "%s invalid real_port\n", dev_name(&udev->dev));
|
||||
if (!virt_dev->rhub_port) {
|
||||
WARN_ONCE(1, "%s invalid rhub port\n", dev_name(&udev->dev));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (udev->speed >= USB_SPEED_SUPER) {
|
||||
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
|
||||
bw_index = (virt_dev->real_port - 1) * 2 + 1;
|
||||
bw_index = (virt_dev->rhub_port->hw_portnum) * 2 + 1;
|
||||
} else {
|
||||
/* 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];
|
||||
|
@ -172,8 +172,8 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
|
||||
__field(void *, vdev)
|
||||
__field(unsigned long long, out_ctx)
|
||||
__field(unsigned long long, in_ctx)
|
||||
__field(u8, fake_port)
|
||||
__field(u8, real_port)
|
||||
__field(int, hcd_portnum)
|
||||
__field(int, hw_portnum)
|
||||
__field(u16, current_mel)
|
||||
|
||||
),
|
||||
@ -181,13 +181,13 @@ DECLARE_EVENT_CLASS(xhci_log_free_virt_dev,
|
||||
__entry->vdev = vdev;
|
||||
__entry->in_ctx = (unsigned long long) vdev->in_ctx->dma;
|
||||
__entry->out_ctx = (unsigned long long) vdev->out_ctx->dma;
|
||||
__entry->fake_port = (u8) vdev->fake_port;
|
||||
__entry->real_port = (u8) vdev->real_port;
|
||||
__entry->hcd_portnum = (int) vdev->rhub_port->hcd_portnum;
|
||||
__entry->hw_portnum = (int) vdev->rhub_port->hw_portnum;
|
||||
__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->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,
|
||||
struct xhci_tt_bw_info *tt_info;
|
||||
|
||||
/* 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;
|
||||
/* If this TT already had active endpoints, the bandwidth for this TT
|
||||
* has already been added. Removing all periodic endpoints (and thus
|
||||
@ -2391,7 +2391,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
|
||||
if (virt_dev->tt_info) {
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
|
||||
"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)) {
|
||||
xhci_warn(xhci, "Not enough bandwidth on HS bus for "
|
||||
"newly activated TT.\n");
|
||||
@ -2404,7 +2404,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
|
||||
} else {
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
|
||||
"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
|
||||
@ -2501,14 +2501,12 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci,
|
||||
bw_used += overhead + packet_size;
|
||||
|
||||
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
|
||||
* root port bandwidth domain. Include the number of active TTs
|
||||
* in the bandwidth used.
|
||||
*/
|
||||
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,
|
||||
@ -2695,7 +2693,7 @@ void xhci_update_tt_active_eps(struct xhci_hcd *xhci,
|
||||
if (!virt_dev->tt_info)
|
||||
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 &&
|
||||
virt_dev->tt_info->active_eps != 0) {
|
||||
rh_bw_info->num_active_tts += 1;
|
||||
|
@ -739,8 +739,7 @@ struct xhci_virt_device {
|
||||
/* Used for addressing devices and configuration changes */
|
||||
struct xhci_container_ctx *in_ctx;
|
||||
struct xhci_virt_ep eps[EP_CTX_PER_DEV];
|
||||
u8 fake_port;
|
||||
u8 real_port;
|
||||
struct xhci_port *rhub_port;
|
||||
struct xhci_interval_bw_table *bw_table;
|
||||
struct xhci_tt_bw_info *tt_info;
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user