Commit df9a6061 authored by Suganath Prabu's avatar Suganath Prabu Committed by Martin K. Petersen

scsi: mpt3sas: Use 63-bit DMA addressing on SAS35 HBA

Although SAS3 & SAS3.5 IT HBA controllers support 64-bit DMA addressing, as
per hardware design, if DMA-able range contains all 64-bits
set (0xFFFFFFFF-FFFFFFFF) then it results in a firmware fault.

E.g. SGE's start address is 0xFFFFFFFF-FFFF000 and data length is 0x1000
bytes. when HBA tries to DMA the data at 0xFFFFFFFF-FFFFFFFF location then
HBA will fault the firmware.

Driver will set 63-bit DMA mask to ensure the above address will not be
used.

Cc: <stable@vger.kernel.org> # 5.1.20+
Signed-off-by: default avatarSuganath Prabu <suganath-prabu.subramani@broadcom.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 18a56d69
...@@ -2703,6 +2703,8 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) ...@@ -2703,6 +2703,8 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
{ {
u64 required_mask, coherent_mask; u64 required_mask, coherent_mask;
struct sysinfo s; struct sysinfo s;
/* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */
int dma_mask = (ioc->hba_mpi_version_belonged > MPI2_VERSION) ? 63 : 64;
if (ioc->is_mcpu_endpoint) if (ioc->is_mcpu_endpoint)
goto try_32bit; goto try_32bit;
...@@ -2712,17 +2714,17 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) ...@@ -2712,17 +2714,17 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev)
goto try_32bit; goto try_32bit;
if (ioc->dma_mask) if (ioc->dma_mask)
coherent_mask = DMA_BIT_MASK(64); coherent_mask = DMA_BIT_MASK(dma_mask);
else else
coherent_mask = DMA_BIT_MASK(32); coherent_mask = DMA_BIT_MASK(32);
if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) || if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(dma_mask)) ||
dma_set_coherent_mask(&pdev->dev, coherent_mask)) dma_set_coherent_mask(&pdev->dev, coherent_mask))
goto try_32bit; goto try_32bit;
ioc->base_add_sg_single = &_base_add_sg_single_64; ioc->base_add_sg_single = &_base_add_sg_single_64;
ioc->sge_size = sizeof(Mpi2SGESimple64_t); ioc->sge_size = sizeof(Mpi2SGESimple64_t);
ioc->dma_mask = 64; ioc->dma_mask = dma_mask;
goto out; goto out;
try_32bit: try_32bit:
...@@ -2744,7 +2746,7 @@ static int ...@@ -2744,7 +2746,7 @@ static int
_base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc, _base_change_consistent_dma_mask(struct MPT3SAS_ADAPTER *ioc,
struct pci_dev *pdev) struct pci_dev *pdev)
{ {
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(ioc->dma_mask))) {
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)))
return -ENODEV; return -ENODEV;
} }
...@@ -4989,7 +4991,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) ...@@ -4989,7 +4991,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc)
total_sz += sz; total_sz += sz;
} while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count)); } while (ioc->rdpq_array_enable && (++i < ioc->reply_queue_count));
if (ioc->dma_mask == 64) { if (ioc->dma_mask > 32) {
if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) { if (_base_change_consistent_dma_mask(ioc, ioc->pdev) != 0) {
ioc_warn(ioc, "no suitable consistent DMA mask for %s\n", ioc_warn(ioc, "no suitable consistent DMA mask for %s\n",
pci_name(ioc->pdev)); pci_name(ioc->pdev));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment