Lines Matching +full:virtio +full:- +full:pci
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Virtio PCI driver - legacy device support
5 * This module allows virtio devices to be used over a virtual PCI device.
19 /* virtio config->get_features() implementation */
26 return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); in vp_get_features()
29 /* virtio config->finalize_features() implementation */
38 BUG_ON((u32)vdev->features != vdev->features); in vp_finalize_features()
41 iowrite32(vdev->features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); in vp_finalize_features()
46 /* virtio config->get() implementation */
51 void __iomem *ioaddr = vp_dev->ioaddr + in vp_get()
52 VIRTIO_PCI_CONFIG_OFF(vp_dev->msix_enabled) + in vp_get()
61 /* the config->set() implementation. it's symmetric to the config->get()
67 void __iomem *ioaddr = vp_dev->ioaddr + in vp_set()
68 VIRTIO_PCI_CONFIG_OFF(vp_dev->msix_enabled) + in vp_set()
77 /* config->{get,set}_status() implementations */
81 return ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); in vp_get_status()
89 iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); in vp_set_status()
96 iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); in vp_reset()
98 * including MSi-X interrupts, if any. */ in vp_reset()
99 ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); in vp_reset()
107 iowrite16(vector, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); in vp_config_vector()
110 return ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); in vp_config_vector()
127 iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); in setup_vq()
130 num = ioread16(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NUM); in setup_vq()
131 if (!num || ioread32(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN)) in setup_vq()
132 return ERR_PTR(-ENOENT); in setup_vq()
134 info->msix_vector = msix_vec; in setup_vq()
138 VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev, in setup_vq()
142 return ERR_PTR(-ENOMEM); in setup_vq()
146 dev_err(&vp_dev->pci_dev->dev, in setup_vq()
147 "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n", in setup_vq()
148 0x1ULL << (32 + PAGE_SHIFT - 30)); in setup_vq()
149 err = -E2BIG; in setup_vq()
154 iowrite32(q_pfn, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); in setup_vq()
156 vq->priv = (void __force *)vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY; in setup_vq()
159 iowrite16(msix_vec, vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); in setup_vq()
160 msix_vec = ioread16(vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); in setup_vq()
162 err = -EBUSY; in setup_vq()
170 iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); in setup_vq()
178 struct virtqueue *vq = info->vq; in del_vq()
179 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); in del_vq()
181 iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); in del_vq()
183 if (vp_dev->msix_enabled) { in del_vq()
185 vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); in del_vq()
187 ioread8(vp_dev->ioaddr + VIRTIO_PCI_ISR); in del_vq()
191 iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); in del_vq()
211 /* the PCI probing function */
214 struct pci_dev *pci_dev = vp_dev->pci_dev; in virtio_pci_legacy_probe()
218 if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) in virtio_pci_legacy_probe()
219 return -ENODEV; in virtio_pci_legacy_probe()
221 if (pci_dev->revision != VIRTIO_PCI_ABI_VERSION) { in virtio_pci_legacy_probe()
223 VIRTIO_PCI_ABI_VERSION, pci_dev->revision); in virtio_pci_legacy_probe()
224 return -ENODEV; in virtio_pci_legacy_probe()
227 rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64)); in virtio_pci_legacy_probe()
229 rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); in virtio_pci_legacy_probe()
232 * The virtio ring base address is expressed as a 32-bit PFN, in virtio_pci_legacy_probe()
235 dma_set_coherent_mask(&pci_dev->dev, in virtio_pci_legacy_probe()
240 …dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this migh… in virtio_pci_legacy_probe()
242 rc = pci_request_region(pci_dev, 0, "virtio-pci-legacy"); in virtio_pci_legacy_probe()
246 rc = -ENOMEM; in virtio_pci_legacy_probe()
247 vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); in virtio_pci_legacy_probe()
248 if (!vp_dev->ioaddr) in virtio_pci_legacy_probe()
251 vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; in virtio_pci_legacy_probe()
253 /* we use the subsystem vendor/device id as the virtio vendor/device in virtio_pci_legacy_probe()
254 * id. this allows us to use the same PCI vendor/device id for all in virtio_pci_legacy_probe()
255 * virtio devices and to identify the particular virtio driver by in virtio_pci_legacy_probe()
257 vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; in virtio_pci_legacy_probe()
258 vp_dev->vdev.id.device = pci_dev->subsystem_device; in virtio_pci_legacy_probe()
260 vp_dev->vdev.config = &virtio_pci_config_ops; in virtio_pci_legacy_probe()
262 vp_dev->config_vector = vp_config_vector; in virtio_pci_legacy_probe()
263 vp_dev->setup_vq = setup_vq; in virtio_pci_legacy_probe()
264 vp_dev->del_vq = del_vq; in virtio_pci_legacy_probe()
275 struct pci_dev *pci_dev = vp_dev->pci_dev; in virtio_pci_legacy_remove()
277 pci_iounmap(pci_dev, vp_dev->ioaddr); in virtio_pci_legacy_remove()