Skip to content

Commit 518cfe9

Browse files
Epicuriusjfvogel
authored andcommitted
usb: xhci: set page size to the xHCI-supported size
[ Upstream commit 68c1f1671650b49bbd26e6a65ddcf33f2565efa3 ] The current xHCI driver does not validate whether a page size of 4096 bytes is supported. Address the issue by setting the page size to the value supported by the xHCI controller, as read from the Page Size register. In the event of an unexpected value; default to a 4K page size. Additionally, this commit removes unnecessary debug messages and instead prints the supported and used page size once. The xHCI controller supports page sizes of (2^{(n+12)}) bytes, where 'n' is the Page Size Bit. Only one page size is supported, with a maximum page size of 128 KB. Signed-off-by: Niklas Neronin <[email protected]> Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 1c171908807cb3717c7a38e51363d1fb8e887e13) Signed-off-by: Jack Vogel <[email protected]>
1 parent 02f1784 commit 518cfe9

File tree

2 files changed

+22
-20
lines changed

2 files changed

+22
-20
lines changed

drivers/usb/host/xhci-mem.c

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,7 +1959,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
19591959
xhci->interrupters = NULL;
19601960

19611961
xhci->page_size = 0;
1962-
xhci->page_shift = 0;
19631962
xhci->usb2_rhub.bus_state.bus_suspended = 0;
19641963
xhci->usb3_rhub.bus_state.bus_suspended = 0;
19651964
}
@@ -2378,14 +2377,30 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs,
23782377
}
23792378
EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter);
23802379

2380+
static void xhci_hcd_page_size(struct xhci_hcd *xhci)
2381+
{
2382+
u32 page_size;
2383+
2384+
page_size = readl(&xhci->op_regs->page_size) & XHCI_PAGE_SIZE_MASK;
2385+
if (!is_power_of_2(page_size)) {
2386+
xhci_warn(xhci, "Invalid page size register = 0x%x\n", page_size);
2387+
/* Fallback to 4K page size, since that's common */
2388+
page_size = 1;
2389+
}
2390+
2391+
xhci->page_size = page_size << 12;
2392+
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "HCD page size set to %iK",
2393+
xhci->page_size >> 10);
2394+
}
2395+
23812396
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
23822397
{
23832398
struct xhci_interrupter *ir;
23842399
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
23852400
dma_addr_t dma;
23862401
unsigned int val, val2;
23872402
u64 val_64;
2388-
u32 page_size, temp;
2403+
u32 temp;
23892404
int i;
23902405

23912406
INIT_LIST_HEAD(&xhci->cmd_list);
@@ -2394,20 +2409,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
23942409
INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout);
23952410
init_completion(&xhci->cmd_ring_stop_completion);
23962411

2397-
page_size = readl(&xhci->op_regs->page_size);
2398-
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
2399-
"Supported page size register = 0x%x", page_size);
2400-
val = ffs(page_size) - 1;
2401-
if (val < 16)
2402-
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
2403-
"Supported page size of %iK", (1 << (val + 12)) / 1024);
2404-
else
2405-
xhci_warn(xhci, "WARN: no supported page size\n");
2406-
/* Use 4K pages, since that's common and the minimum the HC supports */
2407-
xhci->page_shift = 12;
2408-
xhci->page_size = 1 << xhci->page_shift;
2409-
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
2410-
"HCD page size set to %iK", xhci->page_size / 1024);
2412+
xhci_hcd_page_size(xhci);
24112413

24122414
/*
24132415
* Program the Number of Device Slots Enabled field in the CONFIG

drivers/usb/host/xhci.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ struct xhci_op_regs {
211211
#define CONFIG_CIE (1 << 9)
212212
/* bits 10:31 - reserved and should be preserved */
213213

214+
/* bits 15:0 - HCD page shift bit */
215+
#define XHCI_PAGE_SIZE_MASK 0xffff
216+
214217
/**
215218
* struct xhci_intr_reg - Interrupt Register Set
216219
* @irq_pending: IMAN - Interrupt Management Register. Used to enable
@@ -1503,10 +1506,7 @@ struct xhci_hcd {
15031506
u16 max_interrupters;
15041507
/* imod_interval in ns (I * 250ns) */
15051508
u32 imod_interval;
1506-
/* 4KB min, 128MB max */
1507-
int page_size;
1508-
/* Valid values are 12 to 20, inclusive */
1509-
int page_shift;
1509+
u32 page_size;
15101510
/* MSI-X/MSI vectors */
15111511
int nvecs;
15121512
/* optional clocks */

0 commit comments

Comments
 (0)