diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/virtio_scsi.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index cdce502c3c46..eee1bc0b506e 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <scsi/scsi_host.h> | 27 | #include <scsi/scsi_host.h> |
28 | #include <scsi/scsi_device.h> | 28 | #include <scsi/scsi_device.h> |
29 | #include <scsi/scsi_cmnd.h> | 29 | #include <scsi/scsi_cmnd.h> |
30 | #include <scsi/scsi_tcq.h> | ||
30 | #include <linux/seqlock.h> | 31 | #include <linux/seqlock.h> |
31 | 32 | ||
32 | #define VIRTIO_SCSI_MEMPOOL_SZ 64 | 33 | #define VIRTIO_SCSI_MEMPOOL_SZ 64 |
@@ -654,6 +655,36 @@ static int virtscsi_device_reset(struct scsi_cmnd *sc) | |||
654 | return virtscsi_tmf(vscsi, cmd); | 655 | return virtscsi_tmf(vscsi, cmd); |
655 | } | 656 | } |
656 | 657 | ||
658 | /** | ||
659 | * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth | ||
660 | * @sdev: Virtscsi target whose queue depth to change | ||
661 | * @qdepth: New queue depth | ||
662 | * @reason: Reason for the queue depth change. | ||
663 | */ | ||
664 | static int virtscsi_change_queue_depth(struct scsi_device *sdev, | ||
665 | int qdepth, | ||
666 | int reason) | ||
667 | { | ||
668 | struct Scsi_Host *shost = sdev->host; | ||
669 | int max_depth = shost->cmd_per_lun; | ||
670 | |||
671 | switch (reason) { | ||
672 | case SCSI_QDEPTH_QFULL: /* Drop qdepth in response to BUSY state */ | ||
673 | scsi_track_queue_full(sdev, qdepth); | ||
674 | break; | ||
675 | case SCSI_QDEPTH_RAMP_UP: /* Raise qdepth after BUSY state resolved */ | ||
676 | case SCSI_QDEPTH_DEFAULT: /* Manual change via sysfs */ | ||
677 | scsi_adjust_queue_depth(sdev, | ||
678 | scsi_get_tag_type(sdev), | ||
679 | min(max_depth, qdepth)); | ||
680 | break; | ||
681 | default: | ||
682 | return -EOPNOTSUPP; | ||
683 | } | ||
684 | |||
685 | return sdev->queue_depth; | ||
686 | } | ||
687 | |||
657 | static int virtscsi_abort(struct scsi_cmnd *sc) | 688 | static int virtscsi_abort(struct scsi_cmnd *sc) |
658 | { | 689 | { |
659 | struct virtio_scsi *vscsi = shost_priv(sc->device->host); | 690 | struct virtio_scsi *vscsi = shost_priv(sc->device->host); |
@@ -709,6 +740,7 @@ static struct scsi_host_template virtscsi_host_template_single = { | |||
709 | .this_id = -1, | 740 | .this_id = -1, |
710 | .cmd_size = sizeof(struct virtio_scsi_cmd), | 741 | .cmd_size = sizeof(struct virtio_scsi_cmd), |
711 | .queuecommand = virtscsi_queuecommand_single, | 742 | .queuecommand = virtscsi_queuecommand_single, |
743 | .change_queue_depth = virtscsi_change_queue_depth, | ||
712 | .eh_abort_handler = virtscsi_abort, | 744 | .eh_abort_handler = virtscsi_abort, |
713 | .eh_device_reset_handler = virtscsi_device_reset, | 745 | .eh_device_reset_handler = virtscsi_device_reset, |
714 | 746 | ||
@@ -726,6 +758,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { | |||
726 | .this_id = -1, | 758 | .this_id = -1, |
727 | .cmd_size = sizeof(struct virtio_scsi_cmd), | 759 | .cmd_size = sizeof(struct virtio_scsi_cmd), |
728 | .queuecommand = virtscsi_queuecommand_multi, | 760 | .queuecommand = virtscsi_queuecommand_multi, |
761 | .change_queue_depth = virtscsi_change_queue_depth, | ||
729 | .eh_abort_handler = virtscsi_abort, | 762 | .eh_abort_handler = virtscsi_abort, |
730 | .eh_device_reset_handler = virtscsi_device_reset, | 763 | .eh_device_reset_handler = virtscsi_device_reset, |
731 | 764 | ||