Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/virtio/pci/virtio_pci.c
Show First 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | |||||
#define VIRTIO_PCI_CONFIG(_sc) \ | #define VIRTIO_PCI_CONFIG(_sc) \ | ||||
VIRTIO_PCI_CONFIG_OFF((((_sc)->vtpci_flags & VTPCI_FLAG_MSIX)) != 0) | VIRTIO_PCI_CONFIG_OFF((((_sc)->vtpci_flags & VTPCI_FLAG_MSIX)) != 0) | ||||
/* | /* | ||||
* I/O port read/write wrappers. | * I/O port read/write wrappers. | ||||
*/ | */ | ||||
#define vtpci_read_config_1(sc, o) bus_read_1((sc)->vtpci_res, (o)) | #define vtpci_read_config_1(sc, o) bus_read_1((sc)->vtpci_res, (o)) | ||||
#define vtpci_read_config_2(sc, o) bus_read_2((sc)->vtpci_res, (o)) | |||||
#define vtpci_read_config_4(sc, o) bus_read_4((sc)->vtpci_res, (o)) | |||||
#define vtpci_write_config_1(sc, o, v) bus_write_1((sc)->vtpci_res, (o), (v)) | #define vtpci_write_config_1(sc, o, v) bus_write_1((sc)->vtpci_res, (o), (v)) | ||||
#define vtpci_write_config_2(sc, o, v) bus_write_2((sc)->vtpci_res, (o), (v)) | |||||
#define vtpci_write_config_4(sc, o, v) bus_write_4((sc)->vtpci_res, (o), (v)) | |||||
/* | /* | ||||
* Legacy VirtIO header is always PCI endianness (little), so if we | * Virtio-pci specifies that PCI Configuration area is guest endian. However, | ||||
* are in a BE machine we need to swap bytes from LE to BE when reading | * since PCI devices are inherently little-endian, on BE systems the bus layer | ||||
* and from BE to LE when writing. | * transparently converts it to BE. For virtio-legacy, this conversion is | ||||
* If we are in a LE machine, there will be no swaps. | * undesired, so an extra byte swap is required to fix it. | ||||
*/ | */ | ||||
#define vtpci_read_header_2(sc, o) le16toh(vtpci_read_config_2(sc, o)) | #define vtpci_read_config_2(sc, o) le16toh(bus_read_2((sc)->vtpci_res, (o))) | ||||
#define vtpci_read_header_4(sc, o) le32toh(vtpci_read_config_4(sc, o)) | #define vtpci_read_config_4(sc, o) le32toh(bus_read_4((sc)->vtpci_res, (o))) | ||||
#define vtpci_write_header_2(sc, o, v) vtpci_write_config_2(sc, o, (htole16(v))) | #define vtpci_write_config_2(sc, o, v) bus_write_2((sc)->vtpci_res, (o), (htole16(v))) | ||||
#define vtpci_write_header_4(sc, o, v) vtpci_write_config_4(sc, o, (htole32(v))) | #define vtpci_write_config_4(sc, o, v) bus_write_4((sc)->vtpci_res, (o), (htole32(v))) | ||||
/* PCI Header LE. On BE systems the bus layer takes care of byte swapping */ | |||||
#define vtpci_read_header_2(sc, o) (bus_read_2((sc)->vtpci_res, (o))) | |||||
#define vtpci_read_header_4(sc, o) (bus_read_4((sc)->vtpci_res, (o))) | |||||
#define vtpci_write_header_2(sc, o, v) bus_write_2((sc)->vtpci_res, (o), (v)) | |||||
#define vtpci_write_header_4(sc, o, v) bus_write_4((sc)->vtpci_res, (o), (v)) | |||||
/* Tunables. */ | /* Tunables. */ | ||||
static int vtpci_disable_msix = 0; | static int vtpci_disable_msix = 0; | ||||
TUNABLE_INT("hw.virtio.pci.disable_msix", &vtpci_disable_msix); | TUNABLE_INT("hw.virtio.pci.disable_msix", &vtpci_disable_msix); | ||||
static device_method_t vtpci_methods[] = { | static device_method_t vtpci_methods[] = { | ||||
/* Device interface. */ | /* Device interface. */ | ||||
DEVMETHOD(device_probe, vtpci_probe), | DEVMETHOD(device_probe, vtpci_probe), | ||||
DEVMETHOD(device_attach, vtpci_attach), | DEVMETHOD(device_attach, vtpci_attach), | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | vtpci_attach(device_t dev) | ||||
rid = PCIR_BAR(0); | rid = PCIR_BAR(0); | ||||
sc->vtpci_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, | sc->vtpci_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, | ||||
RF_ACTIVE); | RF_ACTIVE); | ||||
if (sc->vtpci_res == NULL) { | if (sc->vtpci_res == NULL) { | ||||
device_printf(dev, "cannot map I/O space\n"); | device_printf(dev, "cannot map I/O space\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
/* | |||||
* For legacy VirtIO, the device-specific configuration is guest | |||||
* endian, while the common configuration header is always | |||||
* PCI (little) endian and will be handled specifically in | |||||
* other parts of this file via functions | |||||
* 'vtpci_[read|write]_header_[2|4]' | |||||
*/ | |||||
#if _BYTE_ORDER == _BIG_ENDIAN | |||||
rman_set_bustag(sc->vtpci_res, &bs_be_tag); | |||||
#endif | |||||
if (pci_find_cap(dev, PCIY_MSI, NULL) != 0) | if (pci_find_cap(dev, PCIY_MSI, NULL) != 0) | ||||
sc->vtpci_flags |= VTPCI_FLAG_NO_MSI; | sc->vtpci_flags |= VTPCI_FLAG_NO_MSI; | ||||
if (pci_find_cap(dev, PCIY_MSIX, NULL) == 0) { | if (pci_find_cap(dev, PCIY_MSIX, NULL) == 0) { | ||||
rid = PCIR_BAR(1); | rid = PCIR_BAR(1); | ||||
sc->vtpci_msix_res = bus_alloc_resource_any(dev, | sc->vtpci_msix_res = bus_alloc_resource_any(dev, | ||||
SYS_RES_MEMORY, &rid, RF_ACTIVE); | SYS_RES_MEMORY, &rid, RF_ACTIVE); | ||||
▲ Show 20 Lines • Show All 1,046 Lines • Show Last 20 Lines |