| From foo@baz Thu Mar 22 14:57:32 CET 2018 |
| From: David Gibson <david@gibson.dropbear.id.au> |
| Date: Thu, 13 Apr 2017 12:13:00 +1000 |
| Subject: scsi: virtio_scsi: Always try to read VPD pages |
| |
| From: David Gibson <david@gibson.dropbear.id.au> |
| |
| |
| [ Upstream commit 25d1d50e23275e141e3a3fe06c25a99f4c4bf4e0 ] |
| |
| Passed through SCSI targets may have transfer limits which come from the |
| host SCSI controller or something on the host side other than the target |
| itself. |
| |
| To make this work properly, the hypervisor can adjust the target's VPD |
| information to advertise these limits. But for that to work, the guest |
| has to look at the VPD pages, which we won't do by default if it is an |
| SPC-2 device, even if it does actually support it. |
| |
| This adds a workaround to address this, forcing devices attached to a |
| virtio-scsi controller to always check the VPD pages. This is modelled |
| on a similar workaround for the storvsc (Hyper-V) SCSI controller, |
| although that exists for slightly different reasons. |
| |
| A specific case which causes this is a volume from IBM's IPR RAID |
| controller (which presents as an SPC-2 device, although it does support |
| VPD) passed through with qemu's 'scsi-block' device. |
| |
| [mkp: fixed typo] |
| |
| Signed-off-by: David Gibson <david@gibson.dropbear.id.au> |
| Acked-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/scsi/virtio_scsi.c | 24 ++++++++++++++++++++++++ |
| 1 file changed, 24 insertions(+) |
| |
| --- a/drivers/scsi/virtio_scsi.c |
| +++ b/drivers/scsi/virtio_scsi.c |
| @@ -28,6 +28,7 @@ |
| #include <scsi/scsi_device.h> |
| #include <scsi/scsi_cmnd.h> |
| #include <scsi/scsi_tcq.h> |
| +#include <scsi/scsi_devinfo.h> |
| #include <linux/seqlock.h> |
| |
| #define VIRTIO_SCSI_MEMPOOL_SZ 64 |
| @@ -704,6 +705,28 @@ static int virtscsi_device_reset(struct |
| return virtscsi_tmf(vscsi, cmd); |
| } |
| |
| +static int virtscsi_device_alloc(struct scsi_device *sdevice) |
| +{ |
| + /* |
| + * Passed through SCSI targets (e.g. with qemu's 'scsi-block') |
| + * may have transfer limits which come from the host SCSI |
| + * controller or something on the host side other than the |
| + * target itself. |
| + * |
| + * To make this work properly, the hypervisor can adjust the |
| + * target's VPD information to advertise these limits. But |
| + * for that to work, the guest has to look at the VPD pages, |
| + * which we won't do by default if it is an SPC-2 device, even |
| + * if it does actually support it. |
| + * |
| + * So, set the blist to always try to read the VPD pages. |
| + */ |
| + sdevice->sdev_bflags = BLIST_TRY_VPD_PAGES; |
| + |
| + return 0; |
| +} |
| + |
| + |
| /** |
| * virtscsi_change_queue_depth() - Change a virtscsi target's queue depth |
| * @sdev: Virtscsi target whose queue depth to change |
| @@ -775,6 +798,7 @@ static struct scsi_host_template virtscs |
| .change_queue_depth = virtscsi_change_queue_depth, |
| .eh_abort_handler = virtscsi_abort, |
| .eh_device_reset_handler = virtscsi_device_reset, |
| + .slave_alloc = virtscsi_device_alloc, |
| |
| .can_queue = 1024, |
| .dma_boundary = UINT_MAX, |