aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/smartpqi
diff options
context:
space:
mode:
authorKevin Barnett <kevin.barnett@hpe.com>2017-05-03 18:53:18 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2017-06-12 20:48:02 -0400
commite1d213bdc3e359c6c5da8ebbc5b2e87b376e8777 (patch)
treeadc7e2c63848b14b8498cb7cea0ae06a90695ba7 /drivers/scsi/smartpqi
parentscsi: smartpqi: add heartbeat check (diff)
downloadlinux-dev-e1d213bdc3e359c6c5da8ebbc5b2e87b376e8777.tar.xz
linux-dev-e1d213bdc3e359c6c5da8ebbc5b2e87b376e8777.zip
scsi: smartpqi: correct bdma hw bug
add workaround for BDMA hardware bug that can cause hw to read up to 12 SGL elements (192 bytes) beyond the last element in the list. This fix avoids IOMMU violations Reviewed-by: Scott Benesh <scott.benesh@microsemi.com> Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com> Signed-off-by: Don Brace <don.brace@microsemi.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/smartpqi')
-rw-r--r--drivers/scsi/smartpqi/smartpqi_init.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index de33942860b3..6f31cd96e521 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -48,6 +48,8 @@
#define DRIVER_NAME "Microsemi PQI Driver (v" DRIVER_VERSION ")"
#define DRIVER_NAME_SHORT "smartpqi"
+#define PQI_EXTRA_SGL_MEMORY (12 * sizeof(struct pqi_sg_descriptor))
+
MODULE_AUTHOR("Microsemi");
MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version "
DRIVER_VERSION);
@@ -3202,6 +3204,8 @@ static int pqi_alloc_operational_queues(struct pqi_ctrl_info *ctrl_info)
alloc_length = (size_t)aligned_pointer +
PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT;
+ alloc_length += PQI_EXTRA_SGL_MEMORY;
+
ctrl_info->queue_memory_base =
dma_zalloc_coherent(&ctrl_info->pci_dev->dev,
alloc_length,
@@ -4319,7 +4323,8 @@ static void pqi_calculate_io_resources(struct pqi_ctrl_info *ctrl_info)
max_transfer_size = (max_sg_entries - 1) * PAGE_SIZE;
ctrl_info->sg_chain_buffer_length =
- max_sg_entries * sizeof(struct pqi_sg_descriptor);
+ (max_sg_entries * sizeof(struct pqi_sg_descriptor)) +
+ PQI_EXTRA_SGL_MEMORY;
ctrl_info->sg_tablesize = max_sg_entries;
ctrl_info->max_sectors = max_transfer_size / 512;
}