diff options
| author | Olof Johansson <olof@lixom.net> | 2014-07-22 09:17:18 -0700 |
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2014-07-22 09:17:18 -0700 |
| commit | e9a86d96be0dff611156ea89fbb6eb91478bddab (patch) | |
| tree | ad38c21c76e1c275264cb20482a7f2bdd54618ba /drivers/scsi/virtio_scsi.c | |
| parent | fc3791f3a95df5b76ecbda6952c13ff67251fd10 (diff) | |
| parent | ad8adbf2c7d6269d0100f7f460f4837ece060977 (diff) | |
Merge tag 'sti-defconfig-for-v3.17-1' of git://git.stlinux.com/devel/kernel/linux-sti into next/defconfig
Merge "ARM: STi: defconfig changes for v3.17" from Maxime Coquelin:
STi defconfig updates for v3.17
- Enable ST's Thermal controller driver
- Enable ST's Keyscan driver
- Enable ST's MiPHY365 Phy driver for STiH416 SATA & PCIe
- Enable ST's AHCI driver.
* tag 'sti-defconfig-for-v3.17-1' of git://git.stlinux.com/devel/kernel/linux-sti:
ARM: multi_v7_defconfig: Enable MiPHY365x - ST's Generic (SATA & PCIe) PHY
ARM: multi_v7_defconfig: Enable ST's (S)ATA driver
ARM: multi_v7_defconfig: add ST Keyscan driver
ARM: update multi_v7_defconfig for STI
ARM: multi_v7_defconfig: Configure in ST's Thermal Controller
+ Linux 3.16-rc6
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/scsi/virtio_scsi.c')
| -rw-r--r-- | drivers/scsi/virtio_scsi.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 89ee5929eb6d..308256b5e4cb 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -237,6 +237,16 @@ static void virtscsi_req_done(struct virtqueue *vq) virtscsi_vq_done(vscsi, req_vq, virtscsi_complete_cmd); }; +static void virtscsi_poll_requests(struct virtio_scsi *vscsi) +{ + int i, num_vqs; + + num_vqs = vscsi->num_queues; + for (i = 0; i < num_vqs; i++) + virtscsi_vq_done(vscsi, &vscsi->req_vqs[i], + virtscsi_complete_cmd); +} + static void virtscsi_complete_free(struct virtio_scsi *vscsi, void *buf) { struct virtio_scsi_cmd *cmd = buf; @@ -253,6 +263,8 @@ static void virtscsi_ctrl_done(struct virtqueue *vq) virtscsi_vq_done(vscsi, &vscsi->ctrl_vq, virtscsi_complete_free); }; +static void virtscsi_handle_event(struct work_struct *work); + static int virtscsi_kick_event(struct virtio_scsi *vscsi, struct virtio_scsi_event_node *event_node) { @@ -260,6 +272,7 @@ static int virtscsi_kick_event(struct virtio_scsi *vscsi, struct scatterlist sg; unsigned long flags; + INIT_WORK(&event_node->work, virtscsi_handle_event); sg_init_one(&sg, &event_node->event, sizeof(struct virtio_scsi_event)); spin_lock_irqsave(&vscsi->event_vq.vq_lock, flags); @@ -377,7 +390,6 @@ static void virtscsi_complete_event(struct virtio_scsi *vscsi, void *buf) { struct virtio_scsi_event_node *event_node = buf; - INIT_WORK(&event_node->work, virtscsi_handle_event); schedule_work(&event_node->work); } @@ -589,6 +601,18 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) ret = SUCCESS; + /* + * The spec guarantees that all requests related to the TMF have + * been completed, but the callback might not have run yet if + * we're using independent interrupts (e.g. MSI). Poll the + * virtqueues once. + * + * In the abort case, sc->scsi_done will do nothing, because + * the block layer must have detected a timeout and as a result + * REQ_ATOM_COMPLETE has been set. + */ + virtscsi_poll_requests(vscsi); + out: mempool_free(cmd, virtscsi_cmd_pool); return ret; |
