aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio/virtio_pci_common.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2015-01-13 04:23:32 -0500
committerRusty Russell <rusty@rustcorp.com.au>2015-01-21 00:58:51 -0500
commitff31d2e28549c84d53252b3c36b6f0ba18b78697 (patch)
treec9fa6b04df782a19b50d923c8f1cdd4fbe29888c /drivers/virtio/virtio_pci_common.c
parent2bd56afd44123cea3741c7a46ddd96a46c92b8d9 (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.c69
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
465MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); 465MODULE_DEVICE_TABLE(pci, virtio_pci_id_table);
466 466
467static 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
467static int virtio_pci_probe(struct pci_dev *pci_dev, 478static 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
520err_register:
521 virtio_pci_legacy_remove(vp_dev);
522err_probe:
523 pci_release_regions(pci_dev);
524err_request_regions:
525 pci_disable_device(pci_dev);
526err_enable_device:
527 kfree(vp_dev);
528 return rc;
471} 529}
472 530
473static void virtio_pci_remove(struct pci_dev *pci_dev) 531static 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
478static struct pci_driver virtio_pci_driver = { 543static struct pci_driver virtio_pci_driver = {