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/virtio/virtio_pci_common.c | |
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/virtio/virtio_pci_common.c')
-rw-r--r-- | drivers/virtio/virtio_pci_common.c | 69 |
1 files changed, 67 insertions, 2 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 = { |