diff options
-rw-r--r-- | drivers/block/virtio_blk.c | 40 | ||||
-rw-r--r-- | drivers/char/hw_random/virtio-rng.c | 15 | ||||
-rw-r--r-- | drivers/char/virtio_console.c | 4 | ||||
-rw-r--r-- | drivers/misc/mic/card/mic_virtio.c | 6 | ||||
-rw-r--r-- | drivers/net/virtio_net.c | 44 | ||||
-rw-r--r-- | drivers/s390/kvm/kvm_virtio.c | 9 | ||||
-rw-r--r-- | drivers/s390/kvm/virtio_ccw.c | 6 | ||||
-rw-r--r-- | drivers/scsi/virtio_scsi.c | 42 | ||||
-rw-r--r-- | drivers/virtio/virtio.c | 103 | ||||
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 2 | ||||
-rw-r--r-- | drivers/virtio/virtio_mmio.c | 7 | ||||
-rw-r--r-- | drivers/virtio/virtio_pci.c | 33 | ||||
-rw-r--r-- | include/linux/virtio.h | 14 | ||||
-rw-r--r-- | include/linux/virtio_config.h | 17 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 2 |
15 files changed, 207 insertions, 137 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 0a581400de0f..930fee886917 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -41,12 +41,6 @@ struct virtio_blk | |||
41 | /* Process context for config space updates */ | 41 | /* Process context for config space updates */ |
42 | struct work_struct config_work; | 42 | struct work_struct config_work; |
43 | 43 | ||
44 | /* Lock for config space updates */ | ||
45 | struct mutex config_lock; | ||
46 | |||
47 | /* enable config space updates */ | ||
48 | bool config_enable; | ||
49 | |||
50 | /* What host tells us, plus 2 for header & tailer. */ | 44 | /* What host tells us, plus 2 for header & tailer. */ |
51 | unsigned int sg_elems; | 45 | unsigned int sg_elems; |
52 | 46 | ||
@@ -347,10 +341,6 @@ static void virtblk_config_changed_work(struct work_struct *work) | |||
347 | char *envp[] = { "RESIZE=1", NULL }; | 341 | char *envp[] = { "RESIZE=1", NULL }; |
348 | u64 capacity, size; | 342 | u64 capacity, size; |
349 | 343 | ||
350 | mutex_lock(&vblk->config_lock); | ||
351 | if (!vblk->config_enable) | ||
352 | goto done; | ||
353 | |||
354 | /* Host must always specify the capacity. */ | 344 | /* Host must always specify the capacity. */ |
355 | virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity); | 345 | virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity); |
356 | 346 | ||
@@ -374,8 +364,6 @@ static void virtblk_config_changed_work(struct work_struct *work) | |||
374 | set_capacity(vblk->disk, capacity); | 364 | set_capacity(vblk->disk, capacity); |
375 | revalidate_disk(vblk->disk); | 365 | revalidate_disk(vblk->disk); |
376 | kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp); | 366 | kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp); |
377 | done: | ||
378 | mutex_unlock(&vblk->config_lock); | ||
379 | } | 367 | } |
380 | 368 | ||
381 | static void virtblk_config_changed(struct virtio_device *vdev) | 369 | static void virtblk_config_changed(struct virtio_device *vdev) |
@@ -606,10 +594,8 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
606 | 594 | ||
607 | vblk->vdev = vdev; | 595 | vblk->vdev = vdev; |
608 | vblk->sg_elems = sg_elems; | 596 | vblk->sg_elems = sg_elems; |
609 | mutex_init(&vblk->config_lock); | ||
610 | 597 | ||
611 | INIT_WORK(&vblk->config_work, virtblk_config_changed_work); | 598 | INIT_WORK(&vblk->config_work, virtblk_config_changed_work); |
612 | vblk->config_enable = true; | ||
613 | 599 | ||
614 | err = init_vq(vblk); | 600 | err = init_vq(vblk); |
615 | if (err) | 601 | if (err) |
@@ -733,6 +719,8 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
733 | if (!err && opt_io_size) | 719 | if (!err && opt_io_size) |
734 | blk_queue_io_opt(q, blk_size * opt_io_size); | 720 | blk_queue_io_opt(q, blk_size * opt_io_size); |
735 | 721 | ||
722 | virtio_device_ready(vdev); | ||
723 | |||
736 | add_disk(vblk->disk); | 724 | add_disk(vblk->disk); |
737 | err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); | 725 | err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial); |
738 | if (err) | 726 | if (err) |
@@ -771,10 +759,8 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
771 | int index = vblk->index; | 759 | int index = vblk->index; |
772 | int refc; | 760 | int refc; |
773 | 761 | ||
774 | /* Prevent config work handler from accessing the device. */ | 762 | /* Make sure no work handler is accessing the device. */ |
775 | mutex_lock(&vblk->config_lock); | 763 | flush_work(&vblk->config_work); |
776 | vblk->config_enable = false; | ||
777 | mutex_unlock(&vblk->config_lock); | ||
778 | 764 | ||
779 | del_gendisk(vblk->disk); | 765 | del_gendisk(vblk->disk); |
780 | blk_cleanup_queue(vblk->disk->queue); | 766 | blk_cleanup_queue(vblk->disk->queue); |
@@ -784,8 +770,6 @@ static void virtblk_remove(struct virtio_device *vdev) | |||
784 | /* Stop all the virtqueues. */ | 770 | /* Stop all the virtqueues. */ |
785 | vdev->config->reset(vdev); | 771 | vdev->config->reset(vdev); |
786 | 772 | ||
787 | flush_work(&vblk->config_work); | ||
788 | |||
789 | refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount); | 773 | refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount); |
790 | put_disk(vblk->disk); | 774 | put_disk(vblk->disk); |
791 | vdev->config->del_vqs(vdev); | 775 | vdev->config->del_vqs(vdev); |
@@ -805,11 +789,7 @@ static int virtblk_freeze(struct virtio_device *vdev) | |||
805 | /* Ensure we don't receive any more interrupts */ | 789 | /* Ensure we don't receive any more interrupts */ |
806 | vdev->config->reset(vdev); | 790 | vdev->config->reset(vdev); |
807 | 791 | ||
808 | /* Prevent config work handler from accessing the device. */ | 792 | /* Make sure no work handler is accessing the device. */ |
809 | mutex_lock(&vblk->config_lock); | ||
810 | vblk->config_enable = false; | ||
811 | mutex_unlock(&vblk->config_lock); | ||
812 | |||
813 | flush_work(&vblk->config_work); | 793 | flush_work(&vblk->config_work); |
814 | 794 | ||
815 | blk_mq_stop_hw_queues(vblk->disk->queue); | 795 | blk_mq_stop_hw_queues(vblk->disk->queue); |
@@ -823,12 +803,14 @@ static int virtblk_restore(struct virtio_device *vdev) | |||
823 | struct virtio_blk *vblk = vdev->priv; | 803 | struct virtio_blk *vblk = vdev->priv; |
824 | int ret; | 804 | int ret; |
825 | 805 | ||
826 | vblk->config_enable = true; | ||
827 | ret = init_vq(vdev->priv); | 806 | ret = init_vq(vdev->priv); |
828 | if (!ret) | 807 | if (ret) |
829 | blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); | 808 | return ret; |
830 | 809 | ||
831 | return ret; | 810 | virtio_device_ready(vdev); |
811 | |||
812 | blk_mq_start_stopped_hw_queues(vblk->disk->queue, true); | ||
813 | return 0; | ||
832 | } | 814 | } |
833 | #endif | 815 | #endif |
834 | 816 | ||
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 132c9ccfdc62..72295ea2fd1c 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c | |||
@@ -109,8 +109,8 @@ static int probe_common(struct virtio_device *vdev) | |||
109 | 109 | ||
110 | vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL); | 110 | vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL); |
111 | if (index < 0) { | 111 | if (index < 0) { |
112 | kfree(vi); | 112 | err = index; |
113 | return index; | 113 | goto err_ida; |
114 | } | 114 | } |
115 | sprintf(vi->name, "virtio_rng.%d", index); | 115 | sprintf(vi->name, "virtio_rng.%d", index); |
116 | init_completion(&vi->have_data); | 116 | init_completion(&vi->have_data); |
@@ -128,13 +128,16 @@ static int probe_common(struct virtio_device *vdev) | |||
128 | vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input"); | 128 | vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input"); |
129 | if (IS_ERR(vi->vq)) { | 129 | if (IS_ERR(vi->vq)) { |
130 | err = PTR_ERR(vi->vq); | 130 | err = PTR_ERR(vi->vq); |
131 | vi->vq = NULL; | 131 | goto err_find; |
132 | kfree(vi); | ||
133 | ida_simple_remove(&rng_index_ida, index); | ||
134 | return err; | ||
135 | } | 132 | } |
136 | 133 | ||
137 | return 0; | 134 | return 0; |
135 | |||
136 | err_find: | ||
137 | ida_simple_remove(&rng_index_ida, index); | ||
138 | err_ida: | ||
139 | kfree(vi); | ||
140 | return err; | ||
138 | } | 141 | } |
139 | 142 | ||
140 | static void remove_common(struct virtio_device *vdev) | 143 | static void remove_common(struct virtio_device *vdev) |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index b585b4789822..bfa640023e64 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -1449,6 +1449,8 @@ static int add_port(struct ports_device *portdev, u32 id) | |||
1449 | spin_lock_init(&port->outvq_lock); | 1449 | spin_lock_init(&port->outvq_lock); |
1450 | init_waitqueue_head(&port->waitqueue); | 1450 | init_waitqueue_head(&port->waitqueue); |
1451 | 1451 | ||
1452 | virtio_device_ready(portdev->vdev); | ||
1453 | |||
1452 | /* Fill the in_vq with buffers so the host can send us data. */ | 1454 | /* Fill the in_vq with buffers so the host can send us data. */ |
1453 | nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock); | 1455 | nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock); |
1454 | if (!nr_added_bufs) { | 1456 | if (!nr_added_bufs) { |
@@ -2182,6 +2184,8 @@ static int virtcons_restore(struct virtio_device *vdev) | |||
2182 | if (ret) | 2184 | if (ret) |
2183 | return ret; | 2185 | return ret; |
2184 | 2186 | ||
2187 | virtio_device_ready(portdev->vdev); | ||
2188 | |||
2185 | if (use_multiport(portdev)) | 2189 | if (use_multiport(portdev)) |
2186 | fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); | 2190 | fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); |
2187 | 2191 | ||
diff --git a/drivers/misc/mic/card/mic_virtio.c b/drivers/misc/mic/card/mic_virtio.c index f14b60080c21..e64794730e21 100644 --- a/drivers/misc/mic/card/mic_virtio.c +++ b/drivers/misc/mic/card/mic_virtio.c | |||
@@ -462,16 +462,12 @@ static void mic_handle_config_change(struct mic_device_desc __iomem *d, | |||
462 | struct mic_device_ctrl __iomem *dc | 462 | struct mic_device_ctrl __iomem *dc |
463 | = (void __iomem *)d + mic_aligned_desc_size(d); | 463 | = (void __iomem *)d + mic_aligned_desc_size(d); |
464 | struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev); | 464 | struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev); |
465 | struct virtio_driver *drv; | ||
466 | 465 | ||
467 | if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED) | 466 | if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED) |
468 | return; | 467 | return; |
469 | 468 | ||
470 | dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__); | 469 | dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__); |
471 | drv = container_of(mvdev->vdev.dev.driver, | 470 | virtio_config_changed(&mvdev->vdev); |
472 | struct virtio_driver, driver); | ||
473 | if (drv->config_changed) | ||
474 | drv->config_changed(&mvdev->vdev); | ||
475 | iowrite8(1, &dc->guest_ack); | 471 | iowrite8(1, &dc->guest_ack); |
476 | } | 472 | } |
477 | 473 | ||
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 13d0a8bc8bf3..d75256bd1a6a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -123,9 +123,6 @@ struct virtnet_info { | |||
123 | /* Host can handle any s/g split between our header and packet data */ | 123 | /* Host can handle any s/g split between our header and packet data */ |
124 | bool any_header_sg; | 124 | bool any_header_sg; |
125 | 125 | ||
126 | /* enable config space updates */ | ||
127 | bool config_enable; | ||
128 | |||
129 | /* Active statistics */ | 126 | /* Active statistics */ |
130 | struct virtnet_stats __percpu *stats; | 127 | struct virtnet_stats __percpu *stats; |
131 | 128 | ||
@@ -135,9 +132,6 @@ struct virtnet_info { | |||
135 | /* Work struct for config space updates */ | 132 | /* Work struct for config space updates */ |
136 | struct work_struct config_work; | 133 | struct work_struct config_work; |
137 | 134 | ||
138 | /* Lock for config space updates */ | ||
139 | struct mutex config_lock; | ||
140 | |||
141 | /* Does the affinity hint is set for virtqueues? */ | 135 | /* Does the affinity hint is set for virtqueues? */ |
142 | bool affinity_hint_set; | 136 | bool affinity_hint_set; |
143 | 137 | ||
@@ -1414,13 +1408,9 @@ static void virtnet_config_changed_work(struct work_struct *work) | |||
1414 | container_of(work, struct virtnet_info, config_work); | 1408 | container_of(work, struct virtnet_info, config_work); |
1415 | u16 v; | 1409 | u16 v; |
1416 | 1410 | ||
1417 | mutex_lock(&vi->config_lock); | ||
1418 | if (!vi->config_enable) | ||
1419 | goto done; | ||
1420 | |||
1421 | if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS, | 1411 | if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS, |
1422 | struct virtio_net_config, status, &v) < 0) | 1412 | struct virtio_net_config, status, &v) < 0) |
1423 | goto done; | 1413 | return; |
1424 | 1414 | ||
1425 | if (v & VIRTIO_NET_S_ANNOUNCE) { | 1415 | if (v & VIRTIO_NET_S_ANNOUNCE) { |
1426 | netdev_notify_peers(vi->dev); | 1416 | netdev_notify_peers(vi->dev); |
@@ -1431,7 +1421,7 @@ static void virtnet_config_changed_work(struct work_struct *work) | |||
1431 | v &= VIRTIO_NET_S_LINK_UP; | 1421 | v &= VIRTIO_NET_S_LINK_UP; |
1432 | 1422 | ||
1433 | if (vi->status == v) | 1423 | if (vi->status == v) |
1434 | goto done; | 1424 | return; |
1435 | 1425 | ||
1436 | vi->status = v; | 1426 | vi->status = v; |
1437 | 1427 | ||
@@ -1442,8 +1432,6 @@ static void virtnet_config_changed_work(struct work_struct *work) | |||
1442 | netif_carrier_off(vi->dev); | 1432 | netif_carrier_off(vi->dev); |
1443 | netif_tx_stop_all_queues(vi->dev); | 1433 | netif_tx_stop_all_queues(vi->dev); |
1444 | } | 1434 | } |
1445 | done: | ||
1446 | mutex_unlock(&vi->config_lock); | ||
1447 | } | 1435 | } |
1448 | 1436 | ||
1449 | static void virtnet_config_changed(struct virtio_device *vdev) | 1437 | static void virtnet_config_changed(struct virtio_device *vdev) |
@@ -1764,8 +1752,6 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1764 | u64_stats_init(&virtnet_stats->rx_syncp); | 1752 | u64_stats_init(&virtnet_stats->rx_syncp); |
1765 | } | 1753 | } |
1766 | 1754 | ||
1767 | mutex_init(&vi->config_lock); | ||
1768 | vi->config_enable = true; | ||
1769 | INIT_WORK(&vi->config_work, virtnet_config_changed_work); | 1755 | INIT_WORK(&vi->config_work, virtnet_config_changed_work); |
1770 | 1756 | ||
1771 | /* If we can receive ANY GSO packets, we must allocate large ones. */ | 1757 | /* If we can receive ANY GSO packets, we must allocate large ones. */ |
@@ -1813,6 +1799,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1813 | goto free_vqs; | 1799 | goto free_vqs; |
1814 | } | 1800 | } |
1815 | 1801 | ||
1802 | virtio_device_ready(vdev); | ||
1803 | |||
1816 | /* Last of all, set up some receive buffers. */ | 1804 | /* Last of all, set up some receive buffers. */ |
1817 | for (i = 0; i < vi->curr_queue_pairs; i++) { | 1805 | for (i = 0; i < vi->curr_queue_pairs; i++) { |
1818 | try_fill_recv(&vi->rq[i], GFP_KERNEL); | 1806 | try_fill_recv(&vi->rq[i], GFP_KERNEL); |
@@ -1849,6 +1837,8 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
1849 | return 0; | 1837 | return 0; |
1850 | 1838 | ||
1851 | free_recv_bufs: | 1839 | free_recv_bufs: |
1840 | vi->vdev->config->reset(vdev); | ||
1841 | |||
1852 | free_receive_bufs(vi); | 1842 | free_receive_bufs(vi); |
1853 | unregister_netdev(dev); | 1843 | unregister_netdev(dev); |
1854 | free_vqs: | 1844 | free_vqs: |
@@ -1882,17 +1872,13 @@ static void virtnet_remove(struct virtio_device *vdev) | |||
1882 | 1872 | ||
1883 | unregister_hotcpu_notifier(&vi->nb); | 1873 | unregister_hotcpu_notifier(&vi->nb); |
1884 | 1874 | ||
1885 | /* Prevent config work handler from accessing the device. */ | 1875 | /* Make sure no work handler is accessing the device. */ |
1886 | mutex_lock(&vi->config_lock); | 1876 | flush_work(&vi->config_work); |
1887 | vi->config_enable = false; | ||
1888 | mutex_unlock(&vi->config_lock); | ||
1889 | 1877 | ||
1890 | unregister_netdev(vi->dev); | 1878 | unregister_netdev(vi->dev); |
1891 | 1879 | ||
1892 | remove_vq_common(vi); | 1880 | remove_vq_common(vi); |
1893 | 1881 | ||
1894 | flush_work(&vi->config_work); | ||
1895 | |||
1896 | free_percpu(vi->stats); | 1882 | free_percpu(vi->stats); |
1897 | free_netdev(vi->dev); | 1883 | free_netdev(vi->dev); |
1898 | } | 1884 | } |
@@ -1905,10 +1891,8 @@ static int virtnet_freeze(struct virtio_device *vdev) | |||
1905 | 1891 | ||
1906 | unregister_hotcpu_notifier(&vi->nb); | 1892 | unregister_hotcpu_notifier(&vi->nb); |
1907 | 1893 | ||
1908 | /* Prevent config work handler from accessing the device */ | 1894 | /* Make sure no work handler is accessing the device */ |
1909 | mutex_lock(&vi->config_lock); | 1895 | flush_work(&vi->config_work); |
1910 | vi->config_enable = false; | ||
1911 | mutex_unlock(&vi->config_lock); | ||
1912 | 1896 | ||
1913 | netif_device_detach(vi->dev); | 1897 | netif_device_detach(vi->dev); |
1914 | cancel_delayed_work_sync(&vi->refill); | 1898 | cancel_delayed_work_sync(&vi->refill); |
@@ -1923,8 +1907,6 @@ static int virtnet_freeze(struct virtio_device *vdev) | |||
1923 | 1907 | ||
1924 | remove_vq_common(vi); | 1908 | remove_vq_common(vi); |
1925 | 1909 | ||
1926 | flush_work(&vi->config_work); | ||
1927 | |||
1928 | return 0; | 1910 | return 0; |
1929 | } | 1911 | } |
1930 | 1912 | ||
@@ -1937,6 +1919,8 @@ static int virtnet_restore(struct virtio_device *vdev) | |||
1937 | if (err) | 1919 | if (err) |
1938 | return err; | 1920 | return err; |
1939 | 1921 | ||
1922 | virtio_device_ready(vdev); | ||
1923 | |||
1940 | if (netif_running(vi->dev)) { | 1924 | if (netif_running(vi->dev)) { |
1941 | for (i = 0; i < vi->curr_queue_pairs; i++) | 1925 | for (i = 0; i < vi->curr_queue_pairs; i++) |
1942 | if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) | 1926 | if (!try_fill_recv(&vi->rq[i], GFP_KERNEL)) |
@@ -1948,10 +1932,6 @@ static int virtnet_restore(struct virtio_device *vdev) | |||
1948 | 1932 | ||
1949 | netif_device_attach(vi->dev); | 1933 | netif_device_attach(vi->dev); |
1950 | 1934 | ||
1951 | mutex_lock(&vi->config_lock); | ||
1952 | vi->config_enable = true; | ||
1953 | mutex_unlock(&vi->config_lock); | ||
1954 | |||
1955 | rtnl_lock(); | 1935 | rtnl_lock(); |
1956 | virtnet_set_queues(vi, vi->curr_queue_pairs); | 1936 | virtnet_set_queues(vi, vi->curr_queue_pairs); |
1957 | rtnl_unlock(); | 1937 | rtnl_unlock(); |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index a1349653c6d9..643129070c51 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -406,15 +406,8 @@ static void kvm_extint_handler(struct ext_code ext_code, | |||
406 | 406 | ||
407 | switch (param) { | 407 | switch (param) { |
408 | case VIRTIO_PARAM_CONFIG_CHANGED: | 408 | case VIRTIO_PARAM_CONFIG_CHANGED: |
409 | { | 409 | virtio_config_changed(vq->vdev); |
410 | struct virtio_driver *drv; | ||
411 | drv = container_of(vq->vdev->dev.driver, | ||
412 | struct virtio_driver, driver); | ||
413 | if (drv->config_changed) | ||
414 | drv->config_changed(vq->vdev); | ||
415 | |||
416 | break; | 410 | break; |
417 | } | ||
418 | case VIRTIO_PARAM_DEV_ADD: | 411 | case VIRTIO_PARAM_DEV_ADD: |
419 | schedule_work(&hotplug_work); | 412 | schedule_work(&hotplug_work); |
420 | break; | 413 | break; |
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index d2c0b442bce5..6cbe6ef3c889 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c | |||
@@ -940,11 +940,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev, | |||
940 | vring_interrupt(0, vq); | 940 | vring_interrupt(0, vq); |
941 | } | 941 | } |
942 | if (test_bit(0, &vcdev->indicators2)) { | 942 | if (test_bit(0, &vcdev->indicators2)) { |
943 | drv = container_of(vcdev->vdev.dev.driver, | 943 | virtio_config_changed(&vcdev->vdev); |
944 | struct virtio_driver, driver); | ||
945 | |||
946 | if (drv && drv->config_changed) | ||
947 | drv->config_changed(&vcdev->vdev); | ||
948 | clear_bit(0, &vcdev->indicators2); | 944 | clear_bit(0, &vcdev->indicators2); |
949 | } | 945 | } |
950 | } | 946 | } |
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index eee1bc0b506e..b83846fc7859 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -110,6 +110,9 @@ struct virtio_scsi { | |||
110 | /* CPU hotplug notifier */ | 110 | /* CPU hotplug notifier */ |
111 | struct notifier_block nb; | 111 | struct notifier_block nb; |
112 | 112 | ||
113 | /* Protected by event_vq lock */ | ||
114 | bool stop_events; | ||
115 | |||
113 | struct virtio_scsi_vq ctrl_vq; | 116 | struct virtio_scsi_vq ctrl_vq; |
114 | struct virtio_scsi_vq event_vq; | 117 | struct virtio_scsi_vq event_vq; |
115 | struct virtio_scsi_vq req_vqs[]; | 118 | struct virtio_scsi_vq req_vqs[]; |
@@ -303,6 +306,11 @@ static void virtscsi_cancel_event_work(struct virtio_scsi *vscsi) | |||
303 | { | 306 | { |
304 | int i; | 307 | int i; |
305 | 308 | ||
309 | /* Stop scheduling work before calling cancel_work_sync. */ | ||
310 | spin_lock_irq(&vscsi->event_vq.vq_lock); | ||
311 | vscsi->stop_events = true; | ||
312 | spin_unlock_irq(&vscsi->event_vq.vq_lock); | ||
313 | |||
306 | for (i = 0; i < VIRTIO_SCSI_EVENT_LEN; i++) | 314 | for (i = 0; i < VIRTIO_SCSI_EVENT_LEN; i++) |
307 | cancel_work_sync(&vscsi->event_list[i].work); | 315 | cancel_work_sync(&vscsi->event_list[i].work); |
308 | } | 316 | } |
@@ -390,7 +398,8 @@ static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf) | |||
390 | { | 398 | { |
391 | struct virtio_scsi_event_node *event_node = buf; | 399 | struct virtio_scsi_event_node *event_node = buf; |
392 | 400 | ||
393 | schedule_work(&event_node->work); | 401 | if (!vscsi->stop_events) |
402 | queue_work(system_freezable_wq, &event_node->work); | ||
394 | } | 403 | } |
395 | 404 | ||
396 | static void virtscsi_event_done(struct virtqueue *vq) | 405 | static void virtscsi_event_done(struct virtqueue *vq) |
@@ -851,13 +860,6 @@ static void virtscsi_init_vq(struct virtio_scsi_vq *virtscsi_vq, | |||
851 | virtscsi_vq->vq = vq; | 860 | virtscsi_vq->vq = vq; |
852 | } | 861 | } |
853 | 862 | ||
854 | static void virtscsi_scan(struct virtio_device *vdev) | ||
855 | { | ||
856 | struct Scsi_Host *shost = (struct Scsi_Host *)vdev->priv; | ||
857 | |||
858 | scsi_scan_host(shost); | ||
859 | } | ||
860 | |||
861 | static void virtscsi_remove_vqs(struct virtio_device *vdev) | 863 | static void virtscsi_remove_vqs(struct virtio_device *vdev) |
862 | { | 864 | { |
863 | struct Scsi_Host *sh = virtio_scsi_host(vdev); | 865 | struct Scsi_Host *sh = virtio_scsi_host(vdev); |
@@ -916,9 +918,6 @@ static int virtscsi_init(struct virtio_device *vdev, | |||
916 | virtscsi_config_set(vdev, cdb_size, VIRTIO_SCSI_CDB_SIZE); | 918 | virtscsi_config_set(vdev, cdb_size, VIRTIO_SCSI_CDB_SIZE); |
917 | virtscsi_config_set(vdev, sense_size, VIRTIO_SCSI_SENSE_SIZE); | 919 | virtscsi_config_set(vdev, sense_size, VIRTIO_SCSI_SENSE_SIZE); |
918 | 920 | ||
919 | if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) | ||
920 | virtscsi_kick_event_all(vscsi); | ||
921 | |||
922 | err = 0; | 921 | err = 0; |
923 | 922 | ||
924 | out: | 923 | out: |
@@ -997,10 +996,13 @@ static int virtscsi_probe(struct virtio_device *vdev) | |||
997 | err = scsi_add_host(shost, &vdev->dev); | 996 | err = scsi_add_host(shost, &vdev->dev); |
998 | if (err) | 997 | if (err) |
999 | goto scsi_add_host_failed; | 998 | goto scsi_add_host_failed; |
1000 | /* | 999 | |
1001 | * scsi_scan_host() happens in virtscsi_scan() via virtio_driver->scan() | 1000 | virtio_device_ready(vdev); |
1002 | * after VIRTIO_CONFIG_S_DRIVER_OK has been set.. | 1001 | |
1003 | */ | 1002 | if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) |
1003 | virtscsi_kick_event_all(vscsi); | ||
1004 | |||
1005 | scsi_scan_host(shost); | ||
1004 | return 0; | 1006 | return 0; |
1005 | 1007 | ||
1006 | scsi_add_host_failed: | 1008 | scsi_add_host_failed: |
@@ -1048,8 +1050,15 @@ static int virtscsi_restore(struct virtio_device *vdev) | |||
1048 | return err; | 1050 | return err; |
1049 | 1051 | ||
1050 | err = register_hotcpu_notifier(&vscsi->nb); | 1052 | err = register_hotcpu_notifier(&vscsi->nb); |
1051 | if (err) | 1053 | if (err) { |
1052 | vdev->config->del_vqs(vdev); | 1054 | vdev->config->del_vqs(vdev); |
1055 | return err; | ||
1056 | } | ||
1057 | |||
1058 | virtio_device_ready(vdev); | ||
1059 | |||
1060 | if (virtio_has_feature(vdev, VIRTIO_SCSI_F_HOTPLUG)) | ||
1061 | virtscsi_kick_event_all(vscsi); | ||
1053 | 1062 | ||
1054 | return err; | 1063 | return err; |
1055 | } | 1064 | } |
@@ -1073,7 +1082,6 @@ static struct virtio_driver virtio_scsi_driver = { | |||
1073 | .driver.owner = THIS_MODULE, | 1082 | .driver.owner = THIS_MODULE, |
1074 | .id_table = id_table, | 1083 | .id_table = id_table, |
1075 | .probe = virtscsi_probe, | 1084 | .probe = virtscsi_probe, |
1076 | .scan = virtscsi_scan, | ||
1077 | #ifdef CONFIG_PM_SLEEP | 1085 | #ifdef CONFIG_PM_SLEEP |
1078 | .freeze = virtscsi_freeze, | 1086 | .freeze = virtscsi_freeze, |
1079 | .restore = virtscsi_restore, | 1087 | .restore = virtscsi_restore, |
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index fed0ce198ae3..df598dd8c5c8 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
@@ -117,6 +117,43 @@ void virtio_check_driver_offered_feature(const struct virtio_device *vdev, | |||
117 | } | 117 | } |
118 | EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature); | 118 | EXPORT_SYMBOL_GPL(virtio_check_driver_offered_feature); |
119 | 119 | ||
120 | static void __virtio_config_changed(struct virtio_device *dev) | ||
121 | { | ||
122 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); | ||
123 | |||
124 | if (!dev->config_enabled) | ||
125 | dev->config_change_pending = true; | ||
126 | else if (drv && drv->config_changed) | ||
127 | drv->config_changed(dev); | ||
128 | } | ||
129 | |||
130 | void virtio_config_changed(struct virtio_device *dev) | ||
131 | { | ||
132 | unsigned long flags; | ||
133 | |||
134 | spin_lock_irqsave(&dev->config_lock, flags); | ||
135 | __virtio_config_changed(dev); | ||
136 | spin_unlock_irqrestore(&dev->config_lock, flags); | ||
137 | } | ||
138 | EXPORT_SYMBOL_GPL(virtio_config_changed); | ||
139 | |||
140 | static void virtio_config_disable(struct virtio_device *dev) | ||
141 | { | ||
142 | spin_lock_irq(&dev->config_lock); | ||
143 | dev->config_enabled = false; | ||
144 | spin_unlock_irq(&dev->config_lock); | ||
145 | } | ||
146 | |||
147 | static void virtio_config_enable(struct virtio_device *dev) | ||
148 | { | ||
149 | spin_lock_irq(&dev->config_lock); | ||
150 | dev->config_enabled = true; | ||
151 | if (dev->config_change_pending) | ||
152 | __virtio_config_changed(dev); | ||
153 | dev->config_change_pending = false; | ||
154 | spin_unlock_irq(&dev->config_lock); | ||
155 | } | ||
156 | |||
120 | static int virtio_dev_probe(struct device *_d) | 157 | static int virtio_dev_probe(struct device *_d) |
121 | { | 158 | { |
122 | int err, i; | 159 | int err, i; |
@@ -153,6 +190,8 @@ static int virtio_dev_probe(struct device *_d) | |||
153 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); | 190 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); |
154 | if (drv->scan) | 191 | if (drv->scan) |
155 | drv->scan(dev); | 192 | drv->scan(dev); |
193 | |||
194 | virtio_config_enable(dev); | ||
156 | } | 195 | } |
157 | 196 | ||
158 | return err; | 197 | return err; |
@@ -163,6 +202,8 @@ static int virtio_dev_remove(struct device *_d) | |||
163 | struct virtio_device *dev = dev_to_virtio(_d); | 202 | struct virtio_device *dev = dev_to_virtio(_d); |
164 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); | 203 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); |
165 | 204 | ||
205 | virtio_config_disable(dev); | ||
206 | |||
166 | drv->remove(dev); | 207 | drv->remove(dev); |
167 | 208 | ||
168 | /* Driver should have reset device. */ | 209 | /* Driver should have reset device. */ |
@@ -211,6 +252,10 @@ int register_virtio_device(struct virtio_device *dev) | |||
211 | dev->index = err; | 252 | dev->index = err; |
212 | dev_set_name(&dev->dev, "virtio%u", dev->index); | 253 | dev_set_name(&dev->dev, "virtio%u", dev->index); |
213 | 254 | ||
255 | spin_lock_init(&dev->config_lock); | ||
256 | dev->config_enabled = false; | ||
257 | dev->config_change_pending = false; | ||
258 | |||
214 | /* We always start by resetting the device, in case a previous | 259 | /* We always start by resetting the device, in case a previous |
215 | * driver messed it up. This also tests that code path a little. */ | 260 | * driver messed it up. This also tests that code path a little. */ |
216 | dev->config->reset(dev); | 261 | dev->config->reset(dev); |
@@ -239,6 +284,64 @@ void unregister_virtio_device(struct virtio_device *dev) | |||
239 | } | 284 | } |
240 | EXPORT_SYMBOL_GPL(unregister_virtio_device); | 285 | EXPORT_SYMBOL_GPL(unregister_virtio_device); |
241 | 286 | ||
287 | #ifdef CONFIG_PM_SLEEP | ||
288 | int virtio_device_freeze(struct virtio_device *dev) | ||
289 | { | ||
290 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); | ||
291 | |||
292 | virtio_config_disable(dev); | ||
293 | |||
294 | dev->failed = dev->config->get_status(dev) & VIRTIO_CONFIG_S_FAILED; | ||
295 | |||
296 | if (drv && drv->freeze) | ||
297 | return drv->freeze(dev); | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | EXPORT_SYMBOL_GPL(virtio_device_freeze); | ||
302 | |||
303 | int virtio_device_restore(struct virtio_device *dev) | ||
304 | { | ||
305 | struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); | ||
306 | |||
307 | /* We always start by resetting the device, in case a previous | ||
308 | * driver messed it up. */ | ||
309 | dev->config->reset(dev); | ||
310 | |||
311 | /* Acknowledge that we've seen the device. */ | ||
312 | add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE); | ||
313 | |||
314 | /* Maybe driver failed before freeze. | ||
315 | * Restore the failed status, for debugging. */ | ||
316 | if (dev->failed) | ||
317 | add_status(dev, VIRTIO_CONFIG_S_FAILED); | ||
318 | |||
319 | if (!drv) | ||
320 | return 0; | ||
321 | |||
322 | /* We have a driver! */ | ||
323 | add_status(dev, VIRTIO_CONFIG_S_DRIVER); | ||
324 | |||
325 | dev->config->finalize_features(dev); | ||
326 | |||
327 | if (drv->restore) { | ||
328 | int ret = drv->restore(dev); | ||
329 | if (ret) { | ||
330 | add_status(dev, VIRTIO_CONFIG_S_FAILED); | ||
331 | return ret; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | /* Finally, tell the device we're all set */ | ||
336 | add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); | ||
337 | |||
338 | virtio_config_enable(dev); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | EXPORT_SYMBOL_GPL(virtio_device_restore); | ||
343 | #endif | ||
344 | |||
242 | static int virtio_init(void) | 345 | static int virtio_init(void) |
243 | { | 346 | { |
244 | if (bus_register(&virtio_bus) != 0) | 347 | if (bus_register(&virtio_bus) != 0) |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index f893148a107b..c9703d4d6f67 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -504,6 +504,8 @@ static int virtballoon_restore(struct virtio_device *vdev) | |||
504 | if (ret) | 504 | if (ret) |
505 | return ret; | 505 | return ret; |
506 | 506 | ||
507 | virtio_device_ready(vdev); | ||
508 | |||
507 | fill_balloon(vb, towards_target(vb)); | 509 | fill_balloon(vb, towards_target(vb)); |
508 | update_balloon_size(vb); | 510 | update_balloon_size(vb); |
509 | return 0; | 511 | return 0; |
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index c600ccfd6922..ef9a1650bb80 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
@@ -234,8 +234,6 @@ static irqreturn_t vm_interrupt(int irq, void *opaque) | |||
234 | { | 234 | { |
235 | struct virtio_mmio_device *vm_dev = opaque; | 235 | struct virtio_mmio_device *vm_dev = opaque; |
236 | struct virtio_mmio_vq_info *info; | 236 | struct virtio_mmio_vq_info *info; |
237 | struct virtio_driver *vdrv = container_of(vm_dev->vdev.dev.driver, | ||
238 | struct virtio_driver, driver); | ||
239 | unsigned long status; | 237 | unsigned long status; |
240 | unsigned long flags; | 238 | unsigned long flags; |
241 | irqreturn_t ret = IRQ_NONE; | 239 | irqreturn_t ret = IRQ_NONE; |
@@ -244,9 +242,8 @@ static irqreturn_t vm_interrupt(int irq, void *opaque) | |||
244 | status = readl(vm_dev->base + VIRTIO_MMIO_INTERRUPT_STATUS); | 242 | status = readl(vm_dev->base + VIRTIO_MMIO_INTERRUPT_STATUS); |
245 | writel(status, vm_dev->base + VIRTIO_MMIO_INTERRUPT_ACK); | 243 | writel(status, vm_dev->base + VIRTIO_MMIO_INTERRUPT_ACK); |
246 | 244 | ||
247 | if (unlikely(status & VIRTIO_MMIO_INT_CONFIG) | 245 | if (unlikely(status & VIRTIO_MMIO_INT_CONFIG)) { |
248 | && vdrv && vdrv->config_changed) { | 246 | virtio_config_changed(&vm_dev->vdev); |
249 | vdrv->config_changed(&vm_dev->vdev); | ||
250 | ret = IRQ_HANDLED; | 247 | ret = IRQ_HANDLED; |
251 | } | 248 | } |
252 | 249 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 3d1463c6b120..d34ebfa604f3 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -57,9 +57,6 @@ struct virtio_pci_device | |||
57 | /* Vectors allocated, excluding per-vq vectors if any */ | 57 | /* Vectors allocated, excluding per-vq vectors if any */ |
58 | unsigned msix_used_vectors; | 58 | unsigned msix_used_vectors; |
59 | 59 | ||
60 | /* Status saved during hibernate/restore */ | ||
61 | u8 saved_status; | ||
62 | |||
63 | /* Whether we have vector per vq */ | 60 | /* Whether we have vector per vq */ |
64 | bool per_vq_vectors; | 61 | bool per_vq_vectors; |
65 | }; | 62 | }; |
@@ -211,12 +208,8 @@ static bool vp_notify(struct virtqueue *vq) | |||
211 | static irqreturn_t vp_config_changed(int irq, void *opaque) | 208 | static irqreturn_t vp_config_changed(int irq, void *opaque) |
212 | { | 209 | { |
213 | struct virtio_pci_device *vp_dev = opaque; | 210 | struct virtio_pci_device *vp_dev = opaque; |
214 | struct virtio_driver *drv; | ||
215 | drv = container_of(vp_dev->vdev.dev.driver, | ||
216 | struct virtio_driver, driver); | ||
217 | 211 | ||
218 | if (drv && drv->config_changed) | 212 | virtio_config_changed(&vp_dev->vdev); |
219 | drv->config_changed(&vp_dev->vdev); | ||
220 | return IRQ_HANDLED; | 213 | return IRQ_HANDLED; |
221 | } | 214 | } |
222 | 215 | ||
@@ -768,16 +761,9 @@ static int virtio_pci_freeze(struct device *dev) | |||
768 | { | 761 | { |
769 | struct pci_dev *pci_dev = to_pci_dev(dev); | 762 | struct pci_dev *pci_dev = to_pci_dev(dev); |
770 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 763 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
771 | struct virtio_driver *drv; | ||
772 | int ret; | 764 | int ret; |
773 | 765 | ||
774 | drv = container_of(vp_dev->vdev.dev.driver, | 766 | ret = virtio_device_freeze(&vp_dev->vdev); |
775 | struct virtio_driver, driver); | ||
776 | |||
777 | ret = 0; | ||
778 | vp_dev->saved_status = vp_get_status(&vp_dev->vdev); | ||
779 | if (drv && drv->freeze) | ||
780 | ret = drv->freeze(&vp_dev->vdev); | ||
781 | 767 | ||
782 | if (!ret) | 768 | if (!ret) |
783 | pci_disable_device(pci_dev); | 769 | pci_disable_device(pci_dev); |
@@ -788,27 +774,14 @@ static int virtio_pci_restore(struct device *dev) | |||
788 | { | 774 | { |
789 | struct pci_dev *pci_dev = to_pci_dev(dev); | 775 | struct pci_dev *pci_dev = to_pci_dev(dev); |
790 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 776 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
791 | struct virtio_driver *drv; | ||
792 | int ret; | 777 | int ret; |
793 | 778 | ||
794 | drv = container_of(vp_dev->vdev.dev.driver, | ||
795 | struct virtio_driver, driver); | ||
796 | |||
797 | ret = pci_enable_device(pci_dev); | 779 | ret = pci_enable_device(pci_dev); |
798 | if (ret) | 780 | if (ret) |
799 | return ret; | 781 | return ret; |
800 | 782 | ||
801 | pci_set_master(pci_dev); | 783 | pci_set_master(pci_dev); |
802 | vp_finalize_features(&vp_dev->vdev); | 784 | return virtio_device_restore(&vp_dev->vdev); |
803 | |||
804 | if (drv && drv->restore) | ||
805 | ret = drv->restore(&vp_dev->vdev); | ||
806 | |||
807 | /* Finally, tell the device we're all set */ | ||
808 | if (!ret) | ||
809 | vp_set_status(&vp_dev->vdev, vp_dev->saved_status); | ||
810 | |||
811 | return ret; | ||
812 | } | 785 | } |
813 | 786 | ||
814 | static const struct dev_pm_ops virtio_pci_pm_ops = { | 787 | static const struct dev_pm_ops virtio_pci_pm_ops = { |
diff --git a/include/linux/virtio.h b/include/linux/virtio.h index b46671e28de2..65261a7244fc 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h | |||
@@ -78,6 +78,10 @@ bool virtqueue_is_broken(struct virtqueue *vq); | |||
78 | /** | 78 | /** |
79 | * virtio_device - representation of a device using virtio | 79 | * virtio_device - representation of a device using virtio |
80 | * @index: unique position on the virtio bus | 80 | * @index: unique position on the virtio bus |
81 | * @failed: saved value for CONFIG_S_FAILED bit (for restore) | ||
82 | * @config_enabled: configuration change reporting enabled | ||
83 | * @config_change_pending: configuration change reported while disabled | ||
84 | * @config_lock: protects configuration change reporting | ||
81 | * @dev: underlying device. | 85 | * @dev: underlying device. |
82 | * @id: the device type identification (used to match it with a driver). | 86 | * @id: the device type identification (used to match it with a driver). |
83 | * @config: the configuration ops for this device. | 87 | * @config: the configuration ops for this device. |
@@ -88,6 +92,10 @@ bool virtqueue_is_broken(struct virtqueue *vq); | |||
88 | */ | 92 | */ |
89 | struct virtio_device { | 93 | struct virtio_device { |
90 | int index; | 94 | int index; |
95 | bool failed; | ||
96 | bool config_enabled; | ||
97 | bool config_change_pending; | ||
98 | spinlock_t config_lock; | ||
91 | struct device dev; | 99 | struct device dev; |
92 | struct virtio_device_id id; | 100 | struct virtio_device_id id; |
93 | const struct virtio_config_ops *config; | 101 | const struct virtio_config_ops *config; |
@@ -108,6 +116,12 @@ void unregister_virtio_device(struct virtio_device *dev); | |||
108 | 116 | ||
109 | void virtio_break_device(struct virtio_device *dev); | 117 | void virtio_break_device(struct virtio_device *dev); |
110 | 118 | ||
119 | void virtio_config_changed(struct virtio_device *dev); | ||
120 | #ifdef CONFIG_PM_SLEEP | ||
121 | int virtio_device_freeze(struct virtio_device *dev); | ||
122 | int virtio_device_restore(struct virtio_device *dev); | ||
123 | #endif | ||
124 | |||
111 | /** | 125 | /** |
112 | * virtio_driver - operations for a virtio I/O driver | 126 | * virtio_driver - operations for a virtio I/O driver |
113 | * @driver: underlying device driver (populate name and owner). | 127 | * @driver: underlying device driver (populate name and owner). |
diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h index e8f8f71e843c..7f4ef66873ef 100644 --- a/include/linux/virtio_config.h +++ b/include/linux/virtio_config.h | |||
@@ -109,6 +109,23 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev, | |||
109 | return vq; | 109 | return vq; |
110 | } | 110 | } |
111 | 111 | ||
112 | /** | ||
113 | * virtio_device_ready - enable vq use in probe function | ||
114 | * @vdev: the device | ||
115 | * | ||
116 | * Driver must call this to use vqs in the probe function. | ||
117 | * | ||
118 | * Note: vqs are enabled automatically after probe returns. | ||
119 | */ | ||
120 | static inline | ||
121 | void virtio_device_ready(struct virtio_device *dev) | ||
122 | { | ||
123 | unsigned status = dev->config->get_status(dev); | ||
124 | |||
125 | BUG_ON(status & VIRTIO_CONFIG_S_DRIVER_OK); | ||
126 | dev->config->set_status(dev, status | VIRTIO_CONFIG_S_DRIVER_OK); | ||
127 | } | ||
128 | |||
112 | static inline | 129 | static inline |
113 | const char *virtio_bus_name(struct virtio_device *vdev) | 130 | const char *virtio_bus_name(struct virtio_device *vdev) |
114 | { | 131 | { |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 6940d8fe8971..daa749c8b3fb 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -575,6 +575,8 @@ static int p9_virtio_probe(struct virtio_device *vdev) | |||
575 | /* Ceiling limit to avoid denial of service attacks */ | 575 | /* Ceiling limit to avoid denial of service attacks */ |
576 | chan->p9_max_pages = nr_free_buffer_pages()/4; | 576 | chan->p9_max_pages = nr_free_buffer_pages()/4; |
577 | 577 | ||
578 | virtio_device_ready(vdev); | ||
579 | |||
578 | mutex_lock(&virtio_9p_lock); | 580 | mutex_lock(&virtio_9p_lock); |
579 | list_add_tail(&chan->chan_list, &virtio_chan_list); | 581 | list_add_tail(&chan->chan_list, &virtio_chan_list); |
580 | mutex_unlock(&virtio_9p_lock); | 582 | mutex_unlock(&virtio_9p_lock); |