mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
drivers/char: add support for selecting specific xhci
Handle parameters similar to dbgp=ehci. Implement this by not resettting dbc->sbdf again in dbc_init_xhc(), but using a value found there if non-zero. Additionally, add xue->xhc_num to select n-th controller. Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
3a669ea835
commit
deb23751e1
2 files changed
+48
-13
No files matched your search
@@ -721,7 +721,7 @@ Available alternatives, with their meaning, are:
|
||||
|
||||
### dbgp
|
||||
> `= ehci[ <integer> | @pci<bus>:<slot>.<func> ]`
|
||||
> `= xhci`
|
||||
> `= xhci[ <integer> | @pci<bus>:<slot>.<func> ]`
|
||||
|
||||
Specify the USB controller to use, either by instance number (when going
|
||||
over the PCI busses sequentially) or by PCI device (must be on segment 0).
|
||||
|
||||
+47
-12
@@ -246,6 +246,7 @@ struct dbc {
|
||||
void __iomem *xhc_mmio;
|
||||
|
||||
bool open;
|
||||
unsigned int xhc_num; /* look for n-th xhc */
|
||||
};
|
||||
|
||||
static void *dbc_sys_map_xhc(uint64_t phys, size_t size)
|
||||
@@ -278,24 +279,37 @@ static bool __init dbc_init_xhc(struct dbc *dbc)
|
||||
uint16_t cmd;
|
||||
size_t xhc_mmio_size;
|
||||
|
||||
/*
|
||||
* Search PCI bus 0 for the xHC. All the host controllers supported so far
|
||||
* are part of the chipset and are on bus 0.
|
||||
*/
|
||||
for ( devfn = 0; devfn < 256; devfn++ )
|
||||
if ( dbc->sbdf.sbdf == 0 )
|
||||
{
|
||||
pci_sbdf_t sbdf = PCI_SBDF(0, 0, devfn);
|
||||
uint8_t hdr = pci_conf_read8(sbdf, PCI_HEADER_TYPE);
|
||||
|
||||
if ( hdr == 0 || hdr == 0x80 )
|
||||
/*
|
||||
* Search PCI bus 0 for the xHC. All the host controllers supported so
|
||||
* far are part of the chipset and are on bus 0.
|
||||
*/
|
||||
for ( devfn = 0; devfn < 256; devfn++ )
|
||||
{
|
||||
if ( (pci_conf_read32(sbdf, PCI_CLASS_REVISION) >> 8) == DBC_XHC_CLASSC )
|
||||
pci_sbdf_t sbdf = PCI_SBDF(0, 0, devfn);
|
||||
uint8_t hdr = pci_conf_read8(sbdf, PCI_HEADER_TYPE);
|
||||
|
||||
if ( hdr == 0 || hdr == 0x80 )
|
||||
{
|
||||
dbc->sbdf = sbdf;
|
||||
break;
|
||||
if ( (pci_conf_read32(sbdf, PCI_CLASS_REVISION) >> 8) ==
|
||||
DBC_XHC_CLASSC )
|
||||
{
|
||||
if ( dbc->xhc_num-- )
|
||||
continue;
|
||||
dbc->sbdf = sbdf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Verify if selected device is really xHC */
|
||||
if ( (pci_conf_read32(dbc->sbdf, PCI_CLASS_REVISION) >> 8) !=
|
||||
DBC_XHC_CLASSC )
|
||||
dbc->sbdf.sbdf = 0;
|
||||
}
|
||||
|
||||
if ( !dbc->sbdf.sbdf )
|
||||
{
|
||||
@@ -1052,12 +1066,33 @@ void __init xhci_dbc_uart_init(void)
|
||||
{
|
||||
struct dbc_uart *uart = &dbc_uart;
|
||||
struct dbc *dbc = &uart->dbc;
|
||||
const char *e;
|
||||
|
||||
if ( strncmp(opt_dbgp, "xhci", 4) )
|
||||
return;
|
||||
|
||||
memset(dbc, 0, sizeof(*dbc));
|
||||
|
||||
if ( isdigit(opt_dbgp[4]) )
|
||||
{
|
||||
dbc->xhc_num = simple_strtoul(opt_dbgp + 4, &e, 10);
|
||||
}
|
||||
else if ( strncmp(opt_dbgp + 4, "@pci", 4) == 0 )
|
||||
{
|
||||
unsigned int bus, slot, func;
|
||||
|
||||
e = parse_pci(opt_dbgp + 8, NULL, &bus, &slot, &func);
|
||||
if ( !e || *e )
|
||||
{
|
||||
printk(XENLOG_ERR
|
||||
"Invalid dbgp= PCI device spec: '%s'\n",
|
||||
opt_dbgp + 8);
|
||||
return;
|
||||
}
|
||||
|
||||
dbc->sbdf = PCI_SBDF(0, bus, slot, func);
|
||||
}
|
||||
|
||||
dbc->dbc_ctx = &ctx;
|
||||
dbc->dbc_erst = &erst;
|
||||
dbc->dbc_ering.trb = evt_trb;
|
||||
|
||||