static void vtpci_write_dev_config(device_t dev, bus_size_t offset, void *src, int length) { struct vtpci_softc *sc; bus_size_t off; uint8_t *s; int size; sc = device_get_softc(dev); off = VIRTIO_PCI_CONFIG(sc) + offset; for (s = src; length > 0; s += size, off += size, length -= size) { if (length >= 4) { size = 4; vtpci_write_config_4(sc, off, *(uint32_t *)s); } else if (length >= 2) { size = 2; vtpci_write_config_2(sc, off, *(uint16_t *)s); } else { size = 1; vtpci_write_config_1(sc, off, *s); } } }
static void vtpci_read_dev_config(device_t dev, bus_size_t offset, void *dst, int length) { struct vtpci_softc *sc; bus_size_t off; uint8_t *d; int size; sc = device_get_softc(dev); off = VIRTIO_PCI_CONFIG(sc) + offset; for (d = dst; length > 0; d += size, off += size, length -= size) { if (length >= 4) { size = 4; *(uint32_t *)d = vtpci_read_config_4(sc, off); } else if (length >= 2) { size = 2; *(uint16_t *)d = vtpci_read_config_2(sc, off); } else { size = 1; *d = vtpci_read_config_1(sc, off); } } }
/* the config->set() implementation. it's symmetric to the config->get() * implementation */ static void vp_set(struct virtio_device *vdev, unsigned offset, const void *buf, unsigned len) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG(vp_dev) + offset; const u8 *ptr = buf; int i; for (i = 0; i < len; i++) iowrite8(ptr[i], ioaddr + i); }
/* virtio config->get() implementation */ static void vp_get(struct virtio_device *vdev, unsigned offset, void *buf, unsigned len) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG(vp_dev) + offset; u8 *ptr = buf; int i; for (i = 0; i < len; i++) ptr[i] = ioread8(ioaddr + i); }
void vtpci_write_dev_config(struct virtio_hw *hw, uint64_t offset, void *src, int length) { uint64_t off; uint8_t *s; int size; off = VIRTIO_PCI_CONFIG(hw) + offset; for (s = src; length > 0; s += size, off += size, length -= size) { if (length >= 4) { size = 4; VIRTIO_WRITE_REG_4(hw, off, *(uint32_t *)s); } else if (length >= 2) { size = 2; VIRTIO_WRITE_REG_2(hw, off, *(uint16_t *)s); } else { size = 1; VIRTIO_WRITE_REG_1(hw, off, *s); } } }
void vtpci_read_dev_config(struct virtio_hw *hw, uint64_t offset, void *dst, int length) { uint64_t off; uint8_t *d; int size; off = VIRTIO_PCI_CONFIG(hw) + offset; for (d = dst; length > 0; d += size, off += size, length -= size) { if (length >= 4) { size = 4; *(uint32_t *)d = VIRTIO_READ_REG_4(hw, off); } else if (length >= 2) { size = 2; *(uint16_t *)d = VIRTIO_READ_REG_2(hw, off); } else { size = 1; *d = VIRTIO_READ_REG_1(hw, off); } } }