| From 38cc54182d1770d1e34ea634c3d6c354945ef40a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 11 May 2021 03:04:37 +0000 |
| Subject: scsi: BusLogic: Fix 64-bit system enumeration error for Buslogic |
| |
| From: Matt Wang <wwentao@vmware.com> |
| |
| [ Upstream commit 56f396146af278135c0ff958c79b5ee1bd22453d ] |
| |
| Commit 391e2f25601e ("[SCSI] BusLogic: Port driver to 64-bit") |
| introduced a serious issue for 64-bit systems. With this commit, |
| 64-bit kernel will enumerate 8*15 non-existing disks. This is caused |
| by the broken CCB structure. The change from u32 data to void *data |
| increased CCB length on 64-bit system, which introduced an extra 4 |
| byte offset of the CDB. This leads to incorrect response to INQUIRY |
| commands during enumeration. |
| |
| Fix disk enumeration failure by reverting the portion of the commit |
| above which switched the data pointer from u32 to void. |
| |
| Link: https://lore.kernel.org/r/C325637F-1166-4340-8F0F-3BCCD59D4D54@vmware.com |
| Acked-by: Khalid Aziz <khalid@gonehiking.org> |
| Signed-off-by: Matt Wang <wwentao@vmware.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/BusLogic.c | 6 +++--- |
| drivers/scsi/BusLogic.h | 2 +- |
| 2 files changed, 4 insertions(+), 4 deletions(-) |
| |
| diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c |
| index ccb061ab0a0a..7231de2767a9 100644 |
| --- a/drivers/scsi/BusLogic.c |
| +++ b/drivers/scsi/BusLogic.c |
| @@ -3078,11 +3078,11 @@ static int blogic_qcmd_lck(struct scsi_cmnd *command, |
| ccb->opcode = BLOGIC_INITIATOR_CCB_SG; |
| ccb->datalen = count * sizeof(struct blogic_sg_seg); |
| if (blogic_multimaster_type(adapter)) |
| - ccb->data = (void *)((unsigned int) ccb->dma_handle + |
| + ccb->data = (unsigned int) ccb->dma_handle + |
| ((unsigned long) &ccb->sglist - |
| - (unsigned long) ccb)); |
| + (unsigned long) ccb); |
| else |
| - ccb->data = ccb->sglist; |
| + ccb->data = virt_to_32bit_virt(ccb->sglist); |
| |
| scsi_for_each_sg(command, sg, count, i) { |
| ccb->sglist[i].segbytes = sg_dma_len(sg); |
| diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h |
| index 6182cc8a0344..e081ad47d1cf 100644 |
| --- a/drivers/scsi/BusLogic.h |
| +++ b/drivers/scsi/BusLogic.h |
| @@ -814,7 +814,7 @@ struct blogic_ccb { |
| unsigned char cdblen; /* Byte 2 */ |
| unsigned char sense_datalen; /* Byte 3 */ |
| u32 datalen; /* Bytes 4-7 */ |
| - void *data; /* Bytes 8-11 */ |
| + u32 data; /* Bytes 8-11 */ |
| unsigned char:8; /* Byte 12 */ |
| unsigned char:8; /* Byte 13 */ |
| enum blogic_adapter_status adapter_status; /* Byte 14 */ |
| -- |
| 2.30.2 |
| |