Commit | Line | Data |
---|---|---|
38eb4a29 | 1 | /* |
a90fdce9 | 2 | * Virtio PCI driver - legacy device support |
38eb4a29 MT |
3 | * |
4 | * This module allows virtio devices to be used over a virtual PCI device. | |
5 | * This can be used with QEMU based VMMs like KVM or Xen. | |
6 | * | |
7 | * Copyright IBM Corp. 2007 | |
a90fdce9 | 8 | * Copyright Red Hat, Inc. 2014 |
38eb4a29 MT |
9 | * |
10 | * Authors: | |
11 | * Anthony Liguori <aliguori@us.ibm.com> | |
a90fdce9 MT |
12 | * Rusty Russell <rusty@rustcorp.com.au> |
13 | * Michael S. Tsirkin <mst@redhat.com> | |
38eb4a29 MT |
14 | * |
15 | * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
16 | * See the COPYING file in the top-level directory. | |
17 | * | |
18 | */ | |
19 | ||
5f4c9760 | 20 | #include "virtio_pci_common.h" |
38eb4a29 | 21 | |
38eb4a29 MT |
22 | /* virtio config->get_features() implementation */ |
23 | static u64 vp_get_features(struct virtio_device *vdev) | |
24 | { | |
25 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
26 | ||
27 | /* When someone needs more than 32 feature bits, we'll need to | |
28 | * steal a bit to indicate that the rest are somewhere else. */ | |
29 | return ioread32(vp_dev->ioaddr + VIRTIO_PCI_HOST_FEATURES); | |
30 | } | |
31 | ||
32 | /* virtio config->finalize_features() implementation */ | |
33 | static int vp_finalize_features(struct virtio_device *vdev) | |
34 | { | |
35 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
36 | ||
37 | /* Give virtio_ring a chance to accept features. */ | |
38 | vring_transport_features(vdev); | |
39 | ||
40 | /* Make sure we don't have any features > 32 bits! */ | |
41 | BUG_ON((u32)vdev->features != vdev->features); | |
42 | ||
43 | /* We only support 32 feature bits. */ | |
44 | iowrite32(vdev->features, vp_dev->ioaddr + VIRTIO_PCI_GUEST_FEATURES); | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | /* virtio config->get() implementation */ | |
50 | static void vp_get(struct virtio_device *vdev, unsigned offset, | |
51 | void *buf, unsigned len) | |
52 | { | |
53 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
54 | void __iomem *ioaddr = vp_dev->ioaddr + | |
55 | VIRTIO_PCI_CONFIG(vp_dev) + offset; | |
56 | u8 *ptr = buf; | |
57 | int i; | |
58 | ||
59 | for (i = 0; i < len; i++) | |
60 | ptr[i] = ioread8(ioaddr + i); | |
61 | } | |
62 | ||
63 | /* the config->set() implementation. it's symmetric to the config->get() | |
64 | * implementation */ | |
65 | static void vp_set(struct virtio_device *vdev, unsigned offset, | |
66 | const void *buf, unsigned len) | |
67 | { | |
68 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
69 | void __iomem *ioaddr = vp_dev->ioaddr + | |
70 | VIRTIO_PCI_CONFIG(vp_dev) + offset; | |
71 | const u8 *ptr = buf; | |
72 | int i; | |
73 | ||
74 | for (i = 0; i < len; i++) | |
75 | iowrite8(ptr[i], ioaddr + i); | |
76 | } | |
77 | ||
78 | /* config->{get,set}_status() implementations */ | |
79 | static u8 vp_get_status(struct virtio_device *vdev) | |
80 | { | |
81 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
82 | return ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); | |
83 | } | |
84 | ||
85 | static void vp_set_status(struct virtio_device *vdev, u8 status) | |
86 | { | |
87 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
88 | /* We should never be setting status to 0. */ | |
89 | BUG_ON(status == 0); | |
90 | iowrite8(status, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | |
91 | } | |
92 | ||
93 | static void vp_reset(struct virtio_device *vdev) | |
94 | { | |
95 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | |
96 | /* 0 status means a reset. */ | |
97 | iowrite8(0, vp_dev->ioaddr + VIRTIO_PCI_STATUS); | |
98 | /* Flush out the status write, and flush in device writes, | |
99 | * including MSi-X interrupts, if any. */ | |
100 | ioread8(vp_dev->ioaddr + VIRTIO_PCI_STATUS); | |
101 | /* Flush pending VQ/configuration callbacks. */ | |
102 | vp_synchronize_vectors(vdev); | |
103 | } | |
104 | ||
105 | static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) | |
106 | { | |
107 | /* Setup the vector used for configuration events */ | |
108 | iowrite16(vector, vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); | |
109 | /* Verify we had enough resources to assign the vector */ | |
110 | /* Will also flush the write out to device */ | |
111 | return ioread16(vp_dev->ioaddr + VIRTIO_MSI_CONFIG_VECTOR); | |
112 | } | |
113 | ||
114 | static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, | |
0a9b3f47 | 115 | struct virtio_pci_vq_info *info, |
38eb4a29 MT |
116 | unsigned index, |
117 | void (*callback)(struct virtqueue *vq), | |
118 | const char *name, | |
f94682dd | 119 | bool ctx, |
38eb4a29 MT |
120 | u16 msix_vec) |
121 | { | |
122 | struct virtqueue *vq; | |
38eb4a29 MT |
123 | u16 num; |
124 | int err; | |
69599206 | 125 | u64 q_pfn; |
38eb4a29 MT |
126 | |
127 | /* Select the queue we're interested in */ | |
128 | iowrite16(index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); | |
129 | ||
130 | /* Check if queue is either not available or already active. */ | |
131 | num = ioread16(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NUM); | |
132 | if (!num || ioread32(vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN)) | |
133 | return ERR_PTR(-ENOENT); | |
134 | ||
0a9b3f47 MT |
135 | info->msix_vector = msix_vec; |
136 | ||
7a5589b2 AL |
137 | /* create the vring */ |
138 | vq = vring_create_virtqueue(index, num, | |
139 | VIRTIO_PCI_VRING_ALIGN, &vp_dev->vdev, | |
f94682dd MT |
140 | true, false, ctx, |
141 | vp_notify, callback, name); | |
7a5589b2 | 142 | if (!vq) |
38eb4a29 MT |
143 | return ERR_PTR(-ENOMEM); |
144 | ||
69599206 SP |
145 | q_pfn = virtqueue_get_desc_addr(vq) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; |
146 | if (q_pfn >> 32) { | |
147 | dev_err(&vp_dev->pci_dev->dev, | |
148 | "platform bug: legacy virtio-mmio must not be used with RAM above 0x%llxGB\n", | |
149 | 0x1ULL << (32 + PAGE_SHIFT - 30)); | |
150 | err = -E2BIG; | |
151 | goto out_del_vq; | |
152 | } | |
153 | ||
38eb4a29 | 154 | /* activate the queue */ |
69599206 | 155 | iowrite32(q_pfn, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
38eb4a29 | 156 | |
38eb4a29 MT |
157 | vq->priv = (void __force *)vp_dev->ioaddr + VIRTIO_PCI_QUEUE_NOTIFY; |
158 | ||
159 | if (msix_vec != VIRTIO_MSI_NO_VECTOR) { | |
160 | iowrite16(msix_vec, vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); | |
161 | msix_vec = ioread16(vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); | |
162 | if (msix_vec == VIRTIO_MSI_NO_VECTOR) { | |
163 | err = -EBUSY; | |
7a5589b2 | 164 | goto out_deactivate; |
38eb4a29 MT |
165 | } |
166 | } | |
167 | ||
168 | return vq; | |
169 | ||
7a5589b2 | 170 | out_deactivate: |
38eb4a29 | 171 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); |
69599206 | 172 | out_del_vq: |
7a5589b2 | 173 | vring_del_virtqueue(vq); |
38eb4a29 MT |
174 | return ERR_PTR(err); |
175 | } | |
176 | ||
0a9b3f47 | 177 | static void del_vq(struct virtio_pci_vq_info *info) |
38eb4a29 | 178 | { |
0a9b3f47 | 179 | struct virtqueue *vq = info->vq; |
38eb4a29 | 180 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); |
38eb4a29 MT |
181 | |
182 | iowrite16(vq->index, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_SEL); | |
183 | ||
2008c154 | 184 | if (vp_dev->msix_enabled) { |
38eb4a29 MT |
185 | iowrite16(VIRTIO_MSI_NO_VECTOR, |
186 | vp_dev->ioaddr + VIRTIO_MSI_QUEUE_VECTOR); | |
187 | /* Flush the write out to device */ | |
188 | ioread8(vp_dev->ioaddr + VIRTIO_PCI_ISR); | |
189 | } | |
190 | ||
38eb4a29 MT |
191 | /* Select and deactivate the queue */ |
192 | iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN); | |
193 | ||
7a5589b2 | 194 | vring_del_virtqueue(vq); |
38eb4a29 MT |
195 | } |
196 | ||
197 | static const struct virtio_config_ops virtio_pci_config_ops = { | |
198 | .get = vp_get, | |
199 | .set = vp_set, | |
200 | .get_status = vp_get_status, | |
201 | .set_status = vp_set_status, | |
202 | .reset = vp_reset, | |
203 | .find_vqs = vp_find_vqs, | |
204 | .del_vqs = vp_del_vqs, | |
205 | .get_features = vp_get_features, | |
206 | .finalize_features = vp_finalize_features, | |
207 | .bus_name = vp_bus_name, | |
208 | .set_vq_affinity = vp_set_vq_affinity, | |
bbaba479 | 209 | .get_vq_affinity = vp_get_vq_affinity, |
38eb4a29 MT |
210 | }; |
211 | ||
212 | /* the PCI probing function */ | |
ff31d2e2 | 213 | int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) |
38eb4a29 | 214 | { |
ff31d2e2 | 215 | struct pci_dev *pci_dev = vp_dev->pci_dev; |
59a5b0f7 | 216 | int rc; |
38eb4a29 MT |
217 | |
218 | /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ | |
219 | if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) | |
220 | return -ENODEV; | |
221 | ||
222 | if (pci_dev->revision != VIRTIO_PCI_ABI_VERSION) { | |
223 | printk(KERN_ERR "virtio_pci: expected ABI version %d, got %d\n", | |
224 | VIRTIO_PCI_ABI_VERSION, pci_dev->revision); | |
225 | return -ENODEV; | |
226 | } | |
227 | ||
a0be1db4 WD |
228 | rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64)); |
229 | if (rc) { | |
230 | rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)); | |
231 | } else { | |
232 | /* | |
233 | * The virtio ring base address is expressed as a 32-bit PFN, | |
234 | * with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT. | |
235 | */ | |
236 | dma_set_coherent_mask(&pci_dev->dev, | |
237 | DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT)); | |
238 | } | |
239 | ||
7a5589b2 AL |
240 | if (rc) |
241 | dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n"); | |
242 | ||
59a5b0f7 GH |
243 | rc = pci_request_region(pci_dev, 0, "virtio-pci-legacy"); |
244 | if (rc) | |
245 | return rc; | |
246 | ||
247 | rc = -ENOMEM; | |
38eb4a29 | 248 | vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); |
ff31d2e2 | 249 | if (!vp_dev->ioaddr) |
59a5b0f7 | 250 | goto err_iomap; |
38eb4a29 MT |
251 | |
252 | vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; | |
253 | ||
38eb4a29 MT |
254 | /* we use the subsystem vendor/device id as the virtio vendor/device |
255 | * id. this allows us to use the same PCI vendor/device id for all | |
256 | * virtio devices and to identify the particular virtio driver by | |
257 | * the subsystem ids */ | |
258 | vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; | |
259 | vp_dev->vdev.id.device = pci_dev->subsystem_device; | |
260 | ||
ff31d2e2 MT |
261 | vp_dev->vdev.config = &virtio_pci_config_ops; |
262 | ||
38eb4a29 MT |
263 | vp_dev->config_vector = vp_config_vector; |
264 | vp_dev->setup_vq = setup_vq; | |
265 | vp_dev->del_vq = del_vq; | |
266 | ||
38eb4a29 | 267 | return 0; |
59a5b0f7 GH |
268 | |
269 | err_iomap: | |
270 | pci_release_region(pci_dev, 0); | |
271 | return rc; | |
38eb4a29 MT |
272 | } |
273 | ||
ff31d2e2 | 274 | void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev) |
38eb4a29 | 275 | { |
ff31d2e2 | 276 | struct pci_dev *pci_dev = vp_dev->pci_dev; |
38eb4a29 | 277 | |
38eb4a29 | 278 | pci_iounmap(pci_dev, vp_dev->ioaddr); |
59a5b0f7 | 279 | pci_release_region(pci_dev, 0); |
38eb4a29 | 280 | } |