diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2015-04-01 00:13:15 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-04-01 00:13:34 -0400 |
commit | a8557d32fe90a91d70dbbf57a034ad0c660ce237 (patch) | |
tree | bbb62a88af00743838db82c35b357c260f013b60 | |
parent | c5d4c2c9ce4f4b6980a71dec50f2db4c2e55778d (diff) |
virtio_pci_modern: switch to type-safe io accessors
As Rusty noted, we were accessing queue_enable with an incorrect width.
Switch to type-safe accessors so we don't make this mistake again in the
future.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | drivers/virtio/virtio_pci_modern.c | 83 |
1 files changed, 42 insertions, 41 deletions
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 826e500d4819..cb175f7179d1 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c | |||
@@ -57,6 +57,13 @@ static inline void vp_iowrite32(u32 value, u32 __iomem *addr) | |||
57 | iowrite32(value, addr); | 57 | iowrite32(value, addr); |
58 | } | 58 | } |
59 | 59 | ||
60 | static void vp_iowrite64_twopart(u64 val, | ||
61 | __le32 __iomem *lo, __le32 __iomem *hi) | ||
62 | { | ||
63 | vp_iowrite32((u32)val, lo); | ||
64 | vp_iowrite32(val >> 32, hi); | ||
65 | } | ||
66 | |||
60 | static void __iomem *map_capability(struct pci_dev *dev, int off, | 67 | static void __iomem *map_capability(struct pci_dev *dev, int off, |
61 | size_t minlen, | 68 | size_t minlen, |
62 | u32 align, | 69 | u32 align, |
@@ -131,22 +138,16 @@ static void __iomem *map_capability(struct pci_dev *dev, int off, | |||
131 | return p; | 138 | return p; |
132 | } | 139 | } |
133 | 140 | ||
134 | static void iowrite64_twopart(u64 val, __le32 __iomem *lo, __le32 __iomem *hi) | ||
135 | { | ||
136 | iowrite32((u32)val, lo); | ||
137 | iowrite32(val >> 32, hi); | ||
138 | } | ||
139 | |||
140 | /* virtio config->get_features() implementation */ | 141 | /* virtio config->get_features() implementation */ |
141 | static u64 vp_get_features(struct virtio_device *vdev) | 142 | static u64 vp_get_features(struct virtio_device *vdev) |
142 | { | 143 | { |
143 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 144 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
144 | u64 features; | 145 | u64 features; |
145 | 146 | ||
146 | iowrite32(0, &vp_dev->common->device_feature_select); | 147 | vp_iowrite32(0, &vp_dev->common->device_feature_select); |
147 | features = ioread32(&vp_dev->common->device_feature); | 148 | features = vp_ioread32(&vp_dev->common->device_feature); |
148 | iowrite32(1, &vp_dev->common->device_feature_select); | 149 | vp_iowrite32(1, &vp_dev->common->device_feature_select); |
149 | features |= ((u64)ioread32(&vp_dev->common->device_feature) << 32); | 150 | features |= ((u64)vp_ioread32(&vp_dev->common->device_feature) << 32); |
150 | 151 | ||
151 | return features; | 152 | return features; |
152 | } | 153 | } |
@@ -165,10 +166,10 @@ static int vp_finalize_features(struct virtio_device *vdev) | |||
165 | return -EINVAL; | 166 | return -EINVAL; |
166 | } | 167 | } |
167 | 168 | ||
168 | iowrite32(0, &vp_dev->common->guest_feature_select); | 169 | vp_iowrite32(0, &vp_dev->common->guest_feature_select); |
169 | iowrite32((u32)vdev->features, &vp_dev->common->guest_feature); | 170 | vp_iowrite32((u32)vdev->features, &vp_dev->common->guest_feature); |
170 | iowrite32(1, &vp_dev->common->guest_feature_select); | 171 | vp_iowrite32(1, &vp_dev->common->guest_feature_select); |
171 | iowrite32(vdev->features >> 32, &vp_dev->common->guest_feature); | 172 | vp_iowrite32(vdev->features >> 32, &vp_dev->common->guest_feature); |
172 | 173 | ||
173 | return 0; | 174 | return 0; |
174 | } | 175 | } |
@@ -247,14 +248,14 @@ static void vp_set(struct virtio_device *vdev, unsigned offset, | |||
247 | static u32 vp_generation(struct virtio_device *vdev) | 248 | static u32 vp_generation(struct virtio_device *vdev) |
248 | { | 249 | { |
249 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 250 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
250 | return ioread8(&vp_dev->common->config_generation); | 251 | return vp_ioread8(&vp_dev->common->config_generation); |
251 | } | 252 | } |
252 | 253 | ||
253 | /* config->{get,set}_status() implementations */ | 254 | /* config->{get,set}_status() implementations */ |
254 | static u8 vp_get_status(struct virtio_device *vdev) | 255 | static u8 vp_get_status(struct virtio_device *vdev) |
255 | { | 256 | { |
256 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 257 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
257 | return ioread8(&vp_dev->common->device_status); | 258 | return vp_ioread8(&vp_dev->common->device_status); |
258 | } | 259 | } |
259 | 260 | ||
260 | static void vp_set_status(struct virtio_device *vdev, u8 status) | 261 | static void vp_set_status(struct virtio_device *vdev, u8 status) |
@@ -262,17 +263,17 @@ static void vp_set_status(struct virtio_device *vdev, u8 status) | |||
262 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 263 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
263 | /* We should never be setting status to 0. */ | 264 | /* We should never be setting status to 0. */ |
264 | BUG_ON(status == 0); | 265 | BUG_ON(status == 0); |
265 | iowrite8(status, &vp_dev->common->device_status); | 266 | vp_iowrite8(status, &vp_dev->common->device_status); |
266 | } | 267 | } |
267 | 268 | ||
268 | static void vp_reset(struct virtio_device *vdev) | 269 | static void vp_reset(struct virtio_device *vdev) |
269 | { | 270 | { |
270 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | 271 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); |
271 | /* 0 status means a reset. */ | 272 | /* 0 status means a reset. */ |
272 | iowrite8(0, &vp_dev->common->device_status); | 273 | vp_iowrite8(0, &vp_dev->common->device_status); |
273 | /* Flush out the status write, and flush in device writes, | 274 | /* Flush out the status write, and flush in device writes, |
274 | * including MSI-X interrupts, if any. */ | 275 | * including MSI-X interrupts, if any. */ |
275 | ioread8(&vp_dev->common->device_status); | 276 | vp_ioread8(&vp_dev->common->device_status); |
276 | /* Flush pending VQ/configuration callbacks. */ | 277 | /* Flush pending VQ/configuration callbacks. */ |
277 | vp_synchronize_vectors(vdev); | 278 | vp_synchronize_vectors(vdev); |
278 | } | 279 | } |
@@ -280,10 +281,10 @@ static void vp_reset(struct virtio_device *vdev) | |||
280 | static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) | 281 | static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) |
281 | { | 282 | { |
282 | /* Setup the vector used for configuration events */ | 283 | /* Setup the vector used for configuration events */ |
283 | iowrite16(vector, &vp_dev->common->msix_config); | 284 | vp_iowrite16(vector, &vp_dev->common->msix_config); |
284 | /* Verify we had enough resources to assign the vector */ | 285 | /* Verify we had enough resources to assign the vector */ |
285 | /* Will also flush the write out to device */ | 286 | /* Will also flush the write out to device */ |
286 | return ioread16(&vp_dev->common->msix_config); | 287 | return vp_ioread16(&vp_dev->common->msix_config); |
287 | } | 288 | } |
288 | 289 | ||
289 | static size_t vring_pci_size(u16 num) | 290 | static size_t vring_pci_size(u16 num) |
@@ -323,15 +324,15 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, | |||
323 | u16 num, off; | 324 | u16 num, off; |
324 | int err; | 325 | int err; |
325 | 326 | ||
326 | if (index >= ioread16(&cfg->num_queues)) | 327 | if (index >= vp_ioread16(&cfg->num_queues)) |
327 | return ERR_PTR(-ENOENT); | 328 | return ERR_PTR(-ENOENT); |
328 | 329 | ||
329 | /* Select the queue we're interested in */ | 330 | /* Select the queue we're interested in */ |
330 | iowrite16(index, &cfg->queue_select); | 331 | vp_iowrite16(index, &cfg->queue_select); |
331 | 332 | ||
332 | /* Check if queue is either not available or already active. */ | 333 | /* Check if queue is either not available or already active. */ |
333 | num = ioread16(&cfg->queue_size); | 334 | num = vp_ioread16(&cfg->queue_size); |
334 | if (!num || ioread16(&cfg->queue_enable)) | 335 | if (!num || vp_ioread16(&cfg->queue_enable)) |
335 | return ERR_PTR(-ENOENT); | 336 | return ERR_PTR(-ENOENT); |
336 | 337 | ||
337 | if (num & (num - 1)) { | 338 | if (num & (num - 1)) { |
@@ -340,7 +341,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, | |||
340 | } | 341 | } |
341 | 342 | ||
342 | /* get offset of notification word for this vq */ | 343 | /* get offset of notification word for this vq */ |
343 | off = ioread16(&cfg->queue_notify_off); | 344 | off = vp_ioread16(&cfg->queue_notify_off); |
344 | 345 | ||
345 | info->num = num; | 346 | info->num = num; |
346 | info->msix_vector = msix_vec; | 347 | info->msix_vector = msix_vec; |
@@ -359,13 +360,13 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, | |||
359 | } | 360 | } |
360 | 361 | ||
361 | /* activate the queue */ | 362 | /* activate the queue */ |
362 | iowrite16(num, &cfg->queue_size); | 363 | vp_iowrite16(num, &cfg->queue_size); |
363 | iowrite64_twopart(virt_to_phys(info->queue), | 364 | vp_iowrite64_twopart(virt_to_phys(info->queue), |
364 | &cfg->queue_desc_lo, &cfg->queue_desc_hi); | 365 | &cfg->queue_desc_lo, &cfg->queue_desc_hi); |
365 | iowrite64_twopart(virt_to_phys(virtqueue_get_avail(vq)), | 366 | vp_iowrite64_twopart(virt_to_phys(virtqueue_get_avail(vq)), |
366 | &cfg->queue_avail_lo, &cfg->queue_avail_hi); | 367 | &cfg->queue_avail_lo, &cfg->queue_avail_hi); |
367 | iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)), | 368 | vp_iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)), |
368 | &cfg->queue_used_lo, &cfg->queue_used_hi); | 369 | &cfg->queue_used_lo, &cfg->queue_used_hi); |
369 | 370 | ||
370 | if (vp_dev->notify_base) { | 371 | if (vp_dev->notify_base) { |
371 | /* offset should not wrap */ | 372 | /* offset should not wrap */ |
@@ -394,8 +395,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev, | |||
394 | } | 395 | } |
395 | 396 | ||
396 | if (msix_vec != VIRTIO_MSI_NO_VECTOR) { | 397 | if (msix_vec != VIRTIO_MSI_NO_VECTOR) { |
397 | iowrite16(msix_vec, &cfg->queue_msix_vector); | 398 | vp_iowrite16(msix_vec, &cfg->queue_msix_vector); |
398 | msix_vec = ioread16(&cfg->queue_msix_vector); | 399 | msix_vec = vp_ioread16(&cfg->queue_msix_vector); |
399 | if (msix_vec == VIRTIO_MSI_NO_VECTOR) { | 400 | if (msix_vec == VIRTIO_MSI_NO_VECTOR) { |
400 | err = -EBUSY; | 401 | err = -EBUSY; |
401 | goto err_assign_vector; | 402 | goto err_assign_vector; |
@@ -430,8 +431,8 @@ static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned nvqs, | |||
430 | * this, there's no way to go back except reset. | 431 | * this, there's no way to go back except reset. |
431 | */ | 432 | */ |
432 | list_for_each_entry(vq, &vdev->vqs, list) { | 433 | list_for_each_entry(vq, &vdev->vqs, list) { |
433 | iowrite16(vq->index, &vp_dev->common->queue_select); | 434 | vp_iowrite16(vq->index, &vp_dev->common->queue_select); |
434 | iowrite16(1, &vp_dev->common->queue_enable); | 435 | vp_iowrite16(1, &vp_dev->common->queue_enable); |
435 | } | 436 | } |
436 | 437 | ||
437 | return 0; | 438 | return 0; |
@@ -442,13 +443,13 @@ static void del_vq(struct virtio_pci_vq_info *info) | |||
442 | struct virtqueue *vq = info->vq; | 443 | struct virtqueue *vq = info->vq; |
443 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); | 444 | struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); |
444 | 445 | ||
445 | iowrite16(vq->index, &vp_dev->common->queue_select); | 446 | vp_iowrite16(vq->index, &vp_dev->common->queue_select); |
446 | 447 | ||
447 | if (vp_dev->msix_enabled) { | 448 | if (vp_dev->msix_enabled) { |
448 | iowrite16(VIRTIO_MSI_NO_VECTOR, | 449 | vp_iowrite16(VIRTIO_MSI_NO_VECTOR, |
449 | &vp_dev->common->queue_msix_vector); | 450 | &vp_dev->common->queue_msix_vector); |
450 | /* Flush the write out to device */ | 451 | /* Flush the write out to device */ |
451 | ioread16(&vp_dev->common->queue_msix_vector); | 452 | vp_ioread16(&vp_dev->common->queue_msix_vector); |
452 | } | 453 | } |
453 | 454 | ||
454 | if (!vp_dev->notify_base) | 455 | if (!vp_dev->notify_base) |