[PATCH 01/37] usb: host: xhci: dynamically allocate devs array

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of always defaulting to a 256-entry array,
we can dynamically allocate devs based on what HW
tells us it supports.

Note that we can't, yet, purge MAX_HC_SLOTS
completely because of struct
xhci_device_context_array reliance on it.

Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>

---

Changes since v1:
	- move allocation/deallocation of array to xhci_mem_init/cleanup()
---
 drivers/usb/host/xhci-hub.c  |  2 +-
 drivers/usb/host/xhci-mem.c  | 11 +++++++++--
 drivers/usb/host/xhci-ring.c |  2 +-
 drivers/usb/host/xhci.h      |  2 +-
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 0ef16900efed..ba5ffeef305d 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -356,7 +356,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 	enum usb_device_speed speed;
 
 	slot_id = 0;
-	for (i = 0; i < MAX_HC_SLOTS; i++) {
+	for (i = 0; i <= HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
 		if (!xhci->devs[i])
 			continue;
 		speed = xhci->devs[i]->udev->speed;
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 321de2e0161b..e7edc79851f2 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1828,7 +1828,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 		}
 	}
 
-	for (i = 1; i < MAX_HC_SLOTS; ++i)
+	for (i = 1; i <= HCS_MAX_SLOTS(xhci->hcs_params1); ++i)
 		xhci_free_virt_device(xhci, i);
 
 	dma_pool_destroy(xhci->segment_pool);
@@ -1867,6 +1867,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 		}
 	}
 
+	kfree(xhci->devs);
+
 no_bw:
 	xhci->cmd_ring_reserved_trbs = 0;
 	xhci->num_usb2_ports = 0;
@@ -2378,6 +2380,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 			"// Setting Max device slots reg = 0x%x.", val);
 	writel(val, &xhci->op_regs->config_reg);
 
+	xhci->devs = kcalloc(HCS_MAX_SLOTS(xhci->hcs_params1) + 1,
+			sizeof(struct xhci_virt_device *), GFP_KERNEL);
+	if (!xhci->devs)
+		goto fail;
+
 	/*
 	 * Section 5.4.8 - doorbell array must be
 	 * "physically contiguous and 64-byte (cache line) aligned".
@@ -2535,7 +2542,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 	 * something other than the default (~1ms minimum between interrupts).
 	 * See section 5.5.1.2.
 	 */
-	for (i = 0; i < MAX_HC_SLOTS; ++i)
+	for (i = 0; i <= HCS_MAX_SLOTS(xhci->hcs_params1); ++i)
 		xhci->devs[i] = NULL;
 	for (i = 0; i < USB_MAXCHILDREN; ++i) {
 		xhci->bus_state[0].resume_done[i] = 0;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index bdf6b13d9b67..76402b44f832 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -895,7 +895,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
 		 * doesn't touch the memory.
 		 */
 	}
-	for (i = 0; i < MAX_HC_SLOTS; i++) {
+	for (i = 0; i <= HCS_MAX_SLOTS(xhci->hcs_params1); i++) {
 		if (!xhci->devs[i])
 			continue;
 		for (j = 0; j < 31; j++)
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8ccc11a974b8..f6e5bc3d819b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1583,7 +1583,7 @@ struct xhci_hcd {
 	/* For USB 3.0 LPM enable/disable. */
 	struct xhci_command		*lpm_command;
 	/* Internal mirror of the HW's dcbaa */
-	struct xhci_virt_device	*devs[MAX_HC_SLOTS];
+	struct xhci_virt_device	**devs;
 	/* For keeping track of bandwidth domains per roothub. */
 	struct xhci_root_port_bw_info	*rh_bw;
 
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux