Index: head/sys/dev/virtio/mmio/virtio_mmio.c =================================================================== --- head/sys/dev/virtio/mmio/virtio_mmio.c +++ head/sys/dev/virtio/mmio/virtio_mmio.c @@ -145,6 +145,7 @@ /* Bus interface. */ DEVMETHOD(bus_driver_added, vtmmio_driver_added), DEVMETHOD(bus_child_detached, vtmmio_child_detached), + DEVMETHOD(bus_child_pnpinfo_str, virtio_child_pnpinfo_str), DEVMETHOD(bus_read_ivar, vtmmio_read_ivar), DEVMETHOD(bus_write_ivar, vtmmio_write_ivar), @@ -331,6 +332,14 @@ break; case VIRTIO_IVAR_VENDOR: *result = vtmmio_read_config_4(sc, VIRTIO_MMIO_VENDOR_ID); + break; + case VIRTIO_IVAR_SUBVENDOR: + case VIRTIO_IVAR_DEVICE: + /* + * Dummy value for fields not present in this bus. Used by + * bus-agnostic virtio_child_pnpinfo_str. + */ + *result = 0; break; default: return (ENOENT); Index: head/sys/dev/virtio/pci/virtio_pci.c =================================================================== --- head/sys/dev/virtio/pci/virtio_pci.c +++ head/sys/dev/virtio/pci/virtio_pci.c @@ -200,6 +200,7 @@ /* Bus interface. */ DEVMETHOD(bus_driver_added, vtpci_driver_added), DEVMETHOD(bus_child_detached, vtpci_child_detached), + DEVMETHOD(bus_child_pnpinfo_str, virtio_child_pnpinfo_str), DEVMETHOD(bus_read_ivar, vtpci_read_ivar), DEVMETHOD(bus_write_ivar, vtpci_write_ivar), Index: head/sys/dev/virtio/virtio.h =================================================================== --- head/sys/dev/virtio/virtio.h +++ head/sys/dev/virtio/virtio.h @@ -81,6 +81,8 @@ int virtio_config_generation(device_t dev); int virtio_reinit(device_t dev, uint64_t features); void virtio_reinit_complete(device_t dev); +int virtio_child_pnpinfo_str(device_t busdev, device_t child, char *buf, + size_t buflen); /* * Read/write a variable amount from the device specific (ie, network) Index: head/sys/dev/virtio/virtio.c =================================================================== --- head/sys/dev/virtio/virtio.c +++ head/sys/dev/virtio/virtio.c @@ -263,6 +263,30 @@ offset, dst, len); } +int +virtio_child_pnpinfo_str(device_t busdev __unused, device_t child, char *buf, + size_t buflen) +{ + + /* + * All of these PCI fields will be only 16 bits, but on the vtmmio bus + * the corresponding fields (only "vendor" and "device_type") are 32 + * bits. Many virtio drivers can attach below either bus. + * Gratuitously expand these two fields to 32-bits to allow sharing PNP + * match table data between the mostly-similar buses. + * + * Subdevice and device_type are redundant in both buses, so I don't + * see a lot of PNP utility in exposing the same value under a + * different name. + */ + snprintf(buf, buflen, "vendor=0x%08x device=0x%04x subvendor=0x%04x " + "device_type=0x%08x", (unsigned)virtio_get_vendor(child), + (unsigned)virtio_get_device(child), + (unsigned)virtio_get_subvendor(child), + (unsigned)virtio_get_device_type(child)); + return (0); +} + static int virtio_modevent(module_t mod, int type, void *unused) {