diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2015-01-13 04:23:32 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-01-21 00:58:51 -0500 |
commit | ff31d2e28549c84d53252b3c36b6f0ba18b78697 (patch) | |
tree | c9fa6b04df782a19b50d923c8f1cdd4fbe29888c /drivers | |
parent | 2bd56afd44123cea3741c7a46ddd96a46c92b8d9 (diff) |
virtio_pci: move probe/remove code to common
Most of initialization is device-independent.
Let's move it to common.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/virtio/virtio_pci_common.c | 69 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci_common.h | 5 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci_legacy.c | 75 |
3 files changed, 77 insertions, 72 deletions
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 9756f21b809e..457cbe29c8c4 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c | |||
@@ -464,15 +464,80 @@ static const struct pci_device_id virtio_pci_id_table[] = { | |||
464 | 464 | ||
465 | MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); | 465 | MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); |
466 | 466 | ||
467 | static void virtio_pci_release_dev(struct device *_d) | ||
468 | { | ||
469 | struct virtio_device *vdev = dev_to_virtio(_d); | ||
470 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
471 | |||
472 | /* As struct device is a kobject, it's not safe to | ||
473 | * free the memory (including the reference counter itself) | ||
474 | * until it's release callback. */ | ||
475 | kfree(vp_dev); | ||
476 | } | ||
477 | |||
467 | static int virtio_pci_probe(struct pci_dev *pci_dev, | 478 | static int virtio_pci_probe(struct pci_dev *pci_dev, |
468 | const struct pci_device_id *id) | 479 | const struct pci_device_id *id) |
469 | { | 480 | { |
470 | return virtio_pci_legacy_probe(pci_dev, id); | 481 | struct virtio_pci_device *vp_dev; |
482 | int rc; | ||
483 | |||
484 | /* allocate our structure and fill it out */ | ||
485 | vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL); | ||
486 | if (!vp_dev) | ||
487 | return -ENOMEM; | ||
488 | |||
489 | pci_set_drvdata(pci_dev, vp_dev); | ||
490 | vp_dev->vdev.dev.parent = &pci_dev->dev; | ||
491 | vp_dev->vdev.dev.release = virtio_pci_release_dev; | ||
492 | vp_dev->pci_dev = pci_dev; | ||
493 | INIT_LIST_HEAD(&vp_dev->virtqueues); | ||
494 | spin_lock_init(&vp_dev->lock); | ||
495 | |||
496 | /* Disable MSI/MSIX to bring device to a known good state. */ | ||
497 | pci_msi_off(pci_dev); | ||
498 | |||
499 | /* enable the device */ | ||
500 | rc = pci_enable_device(pci_dev); | ||
501 | if (rc) | ||
502 | goto err_enable_device; | ||
503 | |||
504 | rc = pci_request_regions(pci_dev, "virtio-pci"); | ||
505 | if (rc) | ||
506 | goto err_request_regions; | ||
507 | |||
508 | rc = virtio_pci_legacy_probe(vp_dev); | ||
509 | if (rc) | ||
510 | goto err_probe; | ||
511 | |||
512 | pci_set_master(pci_dev); | ||
513 | |||
514 | rc = register_virtio_device(&vp_dev->vdev); | ||
515 | if (rc) | ||
516 | goto err_register; | ||
517 | |||
518 | return 0; | ||
519 | |||
520 | err_register: | ||
521 | virtio_pci_legacy_remove(vp_dev); | ||
522 | err_probe: | ||
523 | pci_release_regions(pci_dev); | ||
524 | err_request_regions: | ||
525 | pci_disable_device(pci_dev); | ||
526 | err_enable_device: | ||
527 | kfree(vp_dev); | ||
528 | return rc; | ||
471 | } | 529 | } |
472 | 530 | ||
473 | static void virtio_pci_remove(struct pci_dev *pci_dev) | 531 | static void virtio_pci_remove(struct pci_dev *pci_dev) |
474 | { | 532 | { |
475 | virtio_pci_legacy_remove(pci_dev); | 533 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
534 | |||
535 | unregister_virtio_device(&vp_dev->vdev); | ||
536 | |||
537 | virtio_pci_legacy_remove(pci_dev); | ||
538 | |||
539 | pci_release_regions(pci_dev); | ||
540 | pci_disable_device(pci_dev); | ||
476 | } | 541 | } |
477 | 542 | ||
478 | static struct pci_driver virtio_pci_driver = { | 543 | static struct pci_driver virtio_pci_driver = { |
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h index 5a497289b7e9..2b1e70db44a0 100644 --- a/drivers/virtio/virtio_pci_common.h +++ b/drivers/virtio/virtio_pci_common.h | |||
@@ -127,8 +127,7 @@ const char *vp_bus_name(struct virtio_device *vdev); | |||
127 | */ | 127 | */ |
128 | int vp_set_vq_affinity(struct virtqueue *vq, int cpu); | 128 | int vp_set_vq_affinity(struct virtqueue *vq, int cpu); |
129 | 129 | ||
130 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | 130 | int virtio_pci_legacy_probe(struct virtio_pci_device *); |
131 | const struct pci_device_id *id); | 131 | void virtio_pci_legacy_remove(struct virtio_pci_device *); |
132 | void virtio_pci_legacy_remove(struct pci_dev *pci_dev); | ||
133 | 132 | ||
134 | #endif | 133 | #endif |
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index 19f93096739a..256a5278a515 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c | |||
@@ -211,23 +211,10 @@ static const struct virtio_config_ops virtio_pci_config_ops = { | |||
211 | .set_vq_affinity = vp_set_vq_affinity, | 211 | .set_vq_affinity = vp_set_vq_affinity, |
212 | }; | 212 | }; |
213 | 213 | ||
214 | static void virtio_pci_release_dev(struct device *_d) | ||
215 | { | ||
216 | struct virtio_device *vdev = dev_to_virtio(_d); | ||
217 | struct virtio_pci_device *vp_dev = to_vp_device(vdev); | ||
218 | |||
219 | /* As struct device is a kobject, it's not safe to | ||
220 | * free the memory (including the reference counter itself) | ||
221 | * until it's release callback. */ | ||
222 | kfree(vp_dev); | ||
223 | } | ||
224 | |||
225 | /* the PCI probing function */ | 214 | /* the PCI probing function */ |
226 | int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | 215 | int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev) |
227 | const struct pci_device_id *id) | ||
228 | { | 216 | { |
229 | struct virtio_pci_device *vp_dev; | 217 | struct pci_dev *pci_dev = vp_dev->pci_dev; |
230 | int err; | ||
231 | 218 | ||
232 | /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ | 219 | /* We only own devices >= 0x1000 and <= 0x103f: leave the rest. */ |
233 | if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) | 220 | if (pci_dev->device < 0x1000 || pci_dev->device > 0x103f) |
@@ -239,41 +226,12 @@ int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | |||
239 | return -ENODEV; | 226 | return -ENODEV; |
240 | } | 227 | } |
241 | 228 | ||
242 | /* allocate our structure and fill it out */ | ||
243 | vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL); | ||
244 | if (vp_dev == NULL) | ||
245 | return -ENOMEM; | ||
246 | |||
247 | vp_dev->vdev.dev.parent = &pci_dev->dev; | ||
248 | vp_dev->vdev.dev.release = virtio_pci_release_dev; | ||
249 | vp_dev->vdev.config = &virtio_pci_config_ops; | ||
250 | vp_dev->pci_dev = pci_dev; | ||
251 | INIT_LIST_HEAD(&vp_dev->virtqueues); | ||
252 | spin_lock_init(&vp_dev->lock); | ||
253 | |||
254 | /* Disable MSI/MSIX to bring device to a known good state. */ | ||
255 | pci_msi_off(pci_dev); | ||
256 | |||
257 | /* enable the device */ | ||
258 | err = pci_enable_device(pci_dev); | ||
259 | if (err) | ||
260 | goto out; | ||
261 | |||
262 | err = pci_request_regions(pci_dev, "virtio-pci"); | ||
263 | if (err) | ||
264 | goto out_enable_device; | ||
265 | |||
266 | vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); | 229 | vp_dev->ioaddr = pci_iomap(pci_dev, 0, 0); |
267 | if (vp_dev->ioaddr == NULL) { | 230 | if (!vp_dev->ioaddr) |
268 | err = -ENOMEM; | 231 | return -ENOMEM; |
269 | goto out_req_regions; | ||
270 | } | ||
271 | 232 | ||
272 | vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; | 233 | vp_dev->isr = vp_dev->ioaddr + VIRTIO_PCI_ISR; |
273 | 234 | ||
274 | pci_set_drvdata(pci_dev, vp_dev); | ||
275 | pci_set_master(pci_dev); | ||
276 | |||
277 | /* we use the subsystem vendor/device id as the virtio vendor/device | 235 | /* we use the subsystem vendor/device id as the virtio vendor/device |
278 | * id. this allows us to use the same PCI vendor/device id for all | 236 | * id. this allows us to use the same PCI vendor/device id for all |
279 | * virtio devices and to identify the particular virtio driver by | 237 | * virtio devices and to identify the particular virtio driver by |
@@ -281,35 +239,18 @@ int virtio_pci_legacy_probe(struct pci_dev *pci_dev, | |||
281 | vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; | 239 | vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor; |
282 | vp_dev->vdev.id.device = pci_dev->subsystem_device; | 240 | vp_dev->vdev.id.device = pci_dev->subsystem_device; |
283 | 241 | ||
242 | vp_dev->vdev.config = &virtio_pci_config_ops; | ||
243 | |||
284 | vp_dev->config_vector = vp_config_vector; | 244 | vp_dev->config_vector = vp_config_vector; |
285 | vp_dev->setup_vq = setup_vq; | 245 | vp_dev->setup_vq = setup_vq; |
286 | vp_dev->del_vq = del_vq; | 246 | vp_dev->del_vq = del_vq; |
287 | 247 | ||
288 | /* finally register the virtio device */ | ||
289 | err = register_virtio_device(&vp_dev->vdev); | ||
290 | if (err) | ||
291 | goto out_set_drvdata; | ||
292 | |||
293 | return 0; | 248 | return 0; |
294 | |||
295 | out_set_drvdata: | ||
296 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
297 | out_req_regions: | ||
298 | pci_release_regions(pci_dev); | ||
299 | out_enable_device: | ||
300 | pci_disable_device(pci_dev); | ||
301 | out: | ||
302 | kfree(vp_dev); | ||
303 | return err; | ||
304 | } | 249 | } |
305 | 250 | ||
306 | void virtio_pci_legacy_remove(struct pci_dev *pci_dev) | 251 | void virtio_pci_legacy_remove(struct virtio_pci_device *vp_dev) |
307 | { | 252 | { |
308 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 253 | struct pci_dev *pci_dev = vp_dev->pci_dev; |
309 | |||
310 | unregister_virtio_device(&vp_dev->vdev); | ||
311 | 254 | ||
312 | pci_iounmap(pci_dev, vp_dev->ioaddr); | 255 | pci_iounmap(pci_dev, vp_dev->ioaddr); |
313 | pci_release_regions(pci_dev); | ||
314 | pci_disable_device(pci_dev); | ||
315 | } | 256 | } |