aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/virtio_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/virtio_scsi.c')
-rw-r--r--drivers/scsi/virtio_scsi.c42
1 files changed, 25 insertions, 17 deletions
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
396static void virtscsi_event_done(struct virtqueue *vq) 405static 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
854static 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
861static void virtscsi_remove_vqs(struct virtio_device *vdev) 863static 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
924out: 923out:
@@ -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
1006scsi_add_host_failed: 1008scsi_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,