virtio(4): Expose PNP metadata through newbus

Expose the same fields and widths from both vtio buses, even though they
don't quite line up; several virtio drivers can attach to both buses,
and sharing a PNP info table for both seems more convenient.

In practice, I doubt any virtio driver really needs to match on anything
other than bus and device_type (eliminating the unused entries for
vtmmio), and also in practice device_type is << 2^16 (so far, values
range from 1 to 20).  So it might be fine to only expose a 16-bit
device_type for PNP purposes.  On the other hand, I don't see much harm
in overkill here.

Reviewed by:	bryanv, markj (earlier version)
Differential Revision:	https://reviews.freebsd.org/D20406
This commit is contained in:
cem 2019-06-04 02:34:59 +00:00
parent e114a5fd29
commit 5ec4a51814
4 changed files with 36 additions and 0 deletions

View File

@ -145,6 +145,7 @@ static device_method_t vtmmio_methods[] = {
/* 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),
@ -332,6 +333,14 @@ vtmmio_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
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);
}

View File

@ -200,6 +200,7 @@ static device_method_t vtpci_methods[] = {
/* 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),

View File

@ -263,6 +263,30 @@ virtio_write_device_config(device_t dev, bus_size_t offset, void *dst, int len)
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)
{

View File

@ -81,6 +81,8 @@ void virtio_stop(device_t dev);
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)