Add UEFI locator for bus_get_device_path, pci acpi
Add a UEFI locator type. It prints the UEFI device names for a FreeBSD device_t name. It works with PCI and ACPI device nodes. USB forthcoming. Sponsored by: Netflix Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D32749
This commit is contained in:
parent
cae7d9ec83
commit
d0a20e401e
@ -958,6 +958,52 @@ acpi_get_device_path(device_t bus, device_t child, const char *locator, struct s
|
||||
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
|
||||
return (acpi_get_acpi_device_path(bus, child, locator, sb));
|
||||
|
||||
if (strcmp(locator, BUS_LOCATOR_UEFI) == 0) {
|
||||
ACPI_DEVICE_INFO *adinfo;
|
||||
if (!ACPI_FAILURE(AcpiGetObjectInfo(dinfo->ad_handle, &adinfo)) &&
|
||||
dinfo->ad_handle != 0 && (adinfo->Valid & ACPI_VALID_HID)) {
|
||||
const char *hid = adinfo->HardwareId.String;
|
||||
u_long uid = (adinfo->Valid & ACPI_VALID_UID) ?
|
||||
strtoul(adinfo->UniqueId.String, NULL, 10) : 0UL;
|
||||
u_long hidval;
|
||||
|
||||
/*
|
||||
* In UEFI Stanard Version 2.6, Section 9.6.1.6 Text
|
||||
* Device Node Reference, there's an insanely long table
|
||||
* 98. This implements the relevant bits from that
|
||||
* table. Newer versions appear to have not required
|
||||
* anything new. The EDK2 firmware presents both PciRoot
|
||||
* and PcieRoot as PciRoot. Follow the EDK2 standard.
|
||||
*/
|
||||
if (strncmp("PNP", hid, 3) != 0)
|
||||
goto nomatch;
|
||||
hidval = strtoul(hid + 3, NULL, 16);
|
||||
switch (hidval) {
|
||||
case 0x0301:
|
||||
sbuf_printf(sb, "Keyboard(0x%lx)", uid);
|
||||
break;
|
||||
case 0x0401:
|
||||
sbuf_printf(sb, "ParallelPort(0x%lx)", uid);
|
||||
break;
|
||||
case 0x0501:
|
||||
sbuf_printf(sb, "Serial(0x%lx)", uid);
|
||||
break;
|
||||
case 0x0604:
|
||||
sbuf_printf(sb, "Floppy(0x%lx)", uid);
|
||||
break;
|
||||
case 0x0a03:
|
||||
case 0x0a08:
|
||||
sbuf_printf(sb, "PciRoot(0x%lx)", uid);
|
||||
break;
|
||||
default: /* Everything else gets a generic encode */
|
||||
nomatch:
|
||||
sbuf_printf(sb, "Acpi(%s,0x%lx)", hid, uid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Not handled: AcpiAdr... unsure how to know it's one */
|
||||
}
|
||||
|
||||
/* For the rest, punt to the default handler */
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
}
|
||||
|
@ -206,8 +206,8 @@ acpi_pci_get_device_path(device_t bus, device_t child, const char *locator, stru
|
||||
if (strcmp(locator, BUS_LOCATOR_ACPI) == 0)
|
||||
return (acpi_get_acpi_device_path(bus, child, locator, sb));
|
||||
|
||||
/* For the rest, punt to the default handler */
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
/* Otherwise follow base class' actions */
|
||||
return (pci_get_device_path_method(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -138,7 +138,6 @@ static int pci_reset_child(device_t dev, device_t child,
|
||||
|
||||
static int pci_get_id_method(device_t dev, device_t child,
|
||||
enum pci_id_type type, uintptr_t *rid);
|
||||
|
||||
static struct pci_devinfo * pci_fill_devinfo(device_t pcib, device_t bus, int d,
|
||||
int b, int s, int f, uint16_t vid, uint16_t did);
|
||||
|
||||
@ -177,6 +176,7 @@ static device_method_t pci_methods[] = {
|
||||
DEVMETHOD(bus_child_detached, pci_child_detached),
|
||||
DEVMETHOD(bus_child_pnpinfo, pci_child_pnpinfo_method),
|
||||
DEVMETHOD(bus_child_location, pci_child_location_method),
|
||||
DEVMETHOD(bus_get_device_path, pci_get_device_path_method),
|
||||
DEVMETHOD(bus_hint_device_unit, pci_hint_device_unit),
|
||||
DEVMETHOD(bus_remap_intr, pci_remap_intr_method),
|
||||
DEVMETHOD(bus_suspend_child, pci_suspend_child),
|
||||
@ -5917,6 +5917,24 @@ pci_child_pnpinfo_method(device_t dev, device_t child, struct sbuf *sb)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pci_get_device_path_method(device_t bus, device_t child, const char *locator,
|
||||
struct sbuf *sb)
|
||||
{
|
||||
device_t parent = device_get_parent(bus);
|
||||
int rv;
|
||||
|
||||
if (strcmp(locator, BUS_LOCATOR_UEFI) == 0) {
|
||||
rv = bus_generic_get_device_path(parent, bus, locator, sb);
|
||||
if (rv == 0) {
|
||||
sbuf_printf(sb, "/Pci(0x%x,0x%x)", pci_get_slot(child),
|
||||
pci_get_function(child));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
return (bus_generic_get_device_path(bus, child, locator, sb));
|
||||
}
|
||||
|
||||
int
|
||||
pci_assign_interrupt_method(device_t dev, device_t child)
|
||||
{
|
||||
|
@ -138,6 +138,8 @@ int pci_child_location_method(device_t cbdev, device_t child,
|
||||
struct sbuf *sb);
|
||||
int pci_child_pnpinfo_method(device_t cbdev, device_t child,
|
||||
struct sbuf *sb);
|
||||
int pci_get_device_path_method(device_t dev, device_t child,
|
||||
const char *locator, struct sbuf *sb);
|
||||
int pci_assign_interrupt_method(device_t dev, device_t child);
|
||||
int pci_resume(device_t dev);
|
||||
int pci_resume_child(device_t dev, device_t child);
|
||||
|
@ -739,6 +739,7 @@ void bus_data_generation_update(void);
|
||||
|
||||
#define BUS_LOCATOR_ACPI "ACPI"
|
||||
#define BUS_LOCATOR_FREEBSD "FreeBSD"
|
||||
#define BUS_LOCATOR_UEFI "UEFI"
|
||||
|
||||
extern int bus_current_pass;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user