Mailing List Archive

[xen staging] drivers/char: add support for selecting specific xhci
commit deb23751e11a559ca9b9b4c2dc355e2f5250c0d2
Author: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
AuthorDate: Tue Aug 16 11:22:54 2022 +0200
Commit: Jan Beulich <jbeulich@suse.com>
CommitDate: Tue Aug 16 11:22:54 2022 +0200

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>
---
docs/misc/xen-command-line.pandoc | 2 +-
xen/drivers/char/xhci-dbc.c | 59 +++++++++++++++++++++++++++++++--------
2 files changed, 48 insertions(+), 13 deletions(-)

diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc
index cbfd163813..9a79385a37 100644
--- a/docs/misc/xen-command-line.pandoc
+++ b/docs/misc/xen-command-line.pandoc
@@ -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).
diff --git a/xen/drivers/char/xhci-dbc.c b/xen/drivers/char/xhci-dbc.c
index 8c9dfa6cfc..ca7d4a6213 100644
--- a/xen/drivers/char/xhci-dbc.c
+++ b/xen/drivers/char/xhci-dbc.c
@@ -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;
--
generated by git-patchbot for /home/xen/git/xen.git#staging