platform: distinct USB4 from other USB PCI devices

Our usb_host driver supports UHCI, OHCI, EHCI, and XHCI host
controllers. The USB4 host interface / Thunderbolt is currently not
supported and must therefore not be passed to the USB host driver.
This commit is contained in:
Christian Helmuth 2022-03-24 16:21:47 +01:00
parent 1b4cd93dc2
commit 77b572f36a
2 changed files with 52 additions and 41 deletions

View File

@ -133,21 +133,23 @@ that drivers may start to operate with the platform driver.
Supported PCI class aliases Supported PCI class aliases
--------------------------- ---------------------------
The following class names are supported which corresponds to the The following class names are supported which correspond to the
specified PCI class(C), subclass(S) and programming interface(P): specified PCI base class (B), sub class (S) and programming interface
(P) combinations. ('-' matches all devices in the category)
alias C S P alias B S P
**********************
ALL 0x0 0x00 0x0 ALL - - -
AHCI 0x1 0x06 0x0 AHCI 01 06 -
AUDIO 0x4 0x01 0x0 AUDIO 04 01 -
ETHERNET 0x2 0x00 0x0 ETHERNET 02 00 -
HDAUDIO 0x4 0x03 0x0 HDAUDIO 04 03 -
NVME 0x1 0x08 0x2 ISABRIDGE 06 01 -
USB 0xc 0x03 0x0 NVME 01 08 02
VGA 0x3 0x00 0x0 USB 0c 03 00 10 20 30
WIFI 0x2 0x80 0x0 USB4 0c 03 40
ISABRIDGE 0x6 0x01 0x0 VGA 03 00 00
WIFI 02 80 -
Supported non PCI devices Supported non PCI devices

View File

@ -293,37 +293,49 @@ class Platform::Session_component : public Rpc_object<Session>
typedef String<32> Alias_name; typedef String<32> Alias_name;
/* /*
* List of aliases for PCI Class/Subclas/Prog I/F triple used * List of aliases for PCI base class, sub class, and
* by xml config for this platform driver * programming interface triples supported in XML config
*/ */
unsigned class_subclass_prog(Alias_name const &name) bool valid_alias(Alias_name const &name, unsigned const class_code = ~0U)
{ {
static struct { /* wildcard 0xff matches all codes */
const char * alias; auto wildcard = [] (uint8_t v) { return v == 0xff; };
uint8_t pci_class, pci_subclass, pci_progif;
static struct Alias {
const char *name;
uint8_t b, s, p; /* base class, sub class, progif */
} const aliases [] = { } const aliases [] = {
{ "AHCI" , 0x1, 0x06, 0x0}, { "ALL" , 0xff, 0xff, 0xff},
{ "ALL" , 0x0, 0x00, 0x0}, { "AHCI" , 0x01, 0x06, 0xff},
{ "AUDIO" , 0x4, 0x01, 0x0}, { "AUDIO" , 0x04, 0x01, 0xff},
{ "ETHERNET" , 0x2, 0x00, 0x0}, { "ETHERNET" , 0x02, 0x00, 0xff},
{ "HDAUDIO" , 0x4, 0x03, 0x0}, { "HDAUDIO" , 0x04, 0x03, 0xff},
{ "NVME" , 0x1, 0x08, 0x2}, { "ISABRIDGE", 0x06, 0x01, 0xff},
{ "USB" , 0xc, 0x03, 0x0}, { "NVME" , 0x01, 0x08, 0x02},
{ "VGA" , 0x3, 0x00, 0x0}, { "USB" , 0x0c, 0x03, 0x00}, /* UHCI */
{ "WIFI" , 0x2, 0x80, 0x0}, { "USB" , 0x0c, 0x03, 0x10}, /* OHCI */
{ "ISABRIDGE", 0x6, 0x01, 0x0} { "USB" , 0x0c, 0x03, 0x20}, /* EHCI */
{ "USB" , 0x0c, 0x03, 0x30}, /* XHCI */
{ "USB4" , 0x0c, 0x03, 0x40}, /* USB4 NHI/Thunderbolt */
{ "VGA" , 0x03, 0x00, 0x00},
{ "WIFI" , 0x02, 0x80, 0xff},
}; };
for (unsigned i = 0; i < sizeof(aliases) / sizeof(aliases[0]); i++) { uint8_t const b = (class_code >> 16) & 0xff;
if (name != aliases[i].alias) uint8_t const s = (class_code >> 8) & 0xff;
uint8_t const p = class_code & 0xff;
for (Alias const &alias : aliases) {
if (name != alias.name)
continue; continue;
return 0U | aliases[i].pci_class << 16 | if ((wildcard(b) || wildcard(alias.b) || b == alias.b)
aliases[i].pci_subclass << 8 | && (wildcard(s) || wildcard(alias.s) || s == alias.s)
aliases[i].pci_progif; && (wildcard(p) || wildcard(alias.p) || p == alias.p))
return true;
} }
return ~0U; return false;
} }
/** /**
@ -394,11 +406,8 @@ class Platform::Session_component : public Rpc_object<Session>
/* enforce restriction based upon classes */ /* enforce restriction based upon classes */
auto alias = node.attribute_value("class", Alias_name()); auto alias = node.attribute_value("class", Alias_name());
unsigned const class_sub_prog = class_subclass_prog(alias);
enum { DONT_CHECK_PROGIF = 8 }; if (!valid_alias(alias, class_code))
/* if class/subclass don't match - deny */
if (class_sub_prog && (class_sub_prog ^ class_code) >> DONT_CHECK_PROGIF)
return; return;
/* if this bdf is used by some policy - deny */ /* if this bdf is used by some policy - deny */
@ -543,7 +552,7 @@ class Platform::Session_component : public Rpc_object<Session>
Alias_name const alias = node.attribute_value("class", Alias_name()); Alias_name const alias = node.attribute_value("class", Alias_name());
if (class_subclass_prog(alias) >= INVALID_CLASS) { if (!valid_alias(alias)) {
error("'", _label, "' - invalid 'class' ", error("'", _label, "' - invalid 'class' ",
"attribute '", alias, "'"); "attribute '", alias, "'");
throw Service_denied(); throw Service_denied();