diff mbox series

scsi: do not fill the LUN in the second CDB byte

Message ID 20250124-topic-sm8x50-ufs-fix-v1-1-18b7c220cc34@linaro.org
State New
Headers show
Series scsi: do not fill the LUN in the second CDB byte | expand

Commit Message

Neil Armstrong Jan. 24, 2025, 2:01 a.m. UTC
The SCSI specification originally required that the second
Command Data Byte contain the LUN value in its high-order bits,
but this field has been marked as reserved since the SCSI-3 spec
from 1996.

Some vendors uses this byte to pass vendor specific data,
and specifying the LUN can trigger strange behaviors.
For the record, this happened on an UFS device where LUN0 was
working perfectly and reading the other LUNs would get the last
buffer data that was read for LUN0, making this issue very very
hard to debug.

It's sane to assume U-Boot will probably never encounter
an SCSI-2 multi-LUN device, if somehow it happens the enquiry
command would need to get the SCSI level to handle this case.

The Linux fix was added in [1] to fix the exact same issue.

[1] https://lore.kernel.org/all/Pine.LNX.4.44L0.1409021108380.2308-100000@iolanthe.rowland.org/

Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
 drivers/scsi/scsi.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)


---
base-commit: a416d9e680718de1c76c4196e1db77e3ca07662f
change-id: 20250124-topic-sm8x50-ufs-fix-3280b05c6e76

Best regards,
diff mbox series

Patch

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index bcdeda95ed1514119057cc67974fec465cf5672c..cd0b84c062252118d250b9305728e03f61736600 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -38,7 +38,7 @@  void scsi_setup_read16(struct scsi_cmd *pccb, lbaint_t start,
 		       unsigned long blocks)
 {
 	pccb->cmd[0] = SCSI_READ16;
-	pccb->cmd[1] = pccb->lun << 5;
+	pccb->cmd[1] = 0;
 	pccb->cmd[2] = (unsigned char)(start >> 56) & 0xff;
 	pccb->cmd[3] = (unsigned char)(start >> 48) & 0xff;
 	pccb->cmd[4] = (unsigned char)(start >> 40) & 0xff;
@@ -66,7 +66,7 @@  void scsi_setup_read16(struct scsi_cmd *pccb, lbaint_t start,
 static void scsi_setup_inquiry(struct scsi_cmd *pccb)
 {
 	pccb->cmd[0] = SCSI_INQUIRY;
-	pccb->cmd[1] = pccb->lun << 5;
+	pccb->cmd[1] = 0;
 	pccb->cmd[2] = 0;
 	pccb->cmd[3] = 0;
 	if (pccb->datalen > 255)
@@ -82,7 +82,7 @@  static void scsi_setup_read_ext(struct scsi_cmd *pccb, lbaint_t start,
 				unsigned short blocks)
 {
 	pccb->cmd[0] = SCSI_READ10;
-	pccb->cmd[1] = pccb->lun << 5;
+	pccb->cmd[1] = 0;
 	pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
 	pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
 	pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
@@ -103,7 +103,7 @@  static void scsi_setup_write_ext(struct scsi_cmd *pccb, lbaint_t start,
 				 unsigned short blocks)
 {
 	pccb->cmd[0] = SCSI_WRITE10;
-	pccb->cmd[1] = pccb->lun << 5;
+	pccb->cmd[1] = 0;
 	pccb->cmd[2] = (unsigned char)(start >> 24) & 0xff;
 	pccb->cmd[3] = (unsigned char)(start >> 16) & 0xff;
 	pccb->cmd[4] = (unsigned char)(start >> 8) & 0xff;
@@ -289,7 +289,7 @@  static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb,
 
 	memset(pccb->cmd, '\0', sizeof(pccb->cmd));
 	pccb->cmd[0] = SCSI_RD_CAPAC10;
-	pccb->cmd[1] = pccb->lun << 5;
+	pccb->cmd[1] = 0;
 	pccb->cmdlen = 10;
 	pccb->dma_dir = DMA_FROM_DEVICE;
 	pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */
@@ -353,7 +353,7 @@  static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb,
 static void scsi_setup_test_unit_ready(struct scsi_cmd *pccb)
 {
 	pccb->cmd[0] = SCSI_TST_U_RDY;
-	pccb->cmd[1] = pccb->lun << 5;
+	pccb->cmd[1] = 0;
 	pccb->cmd[2] = 0;
 	pccb->cmd[3] = 0;
 	pccb->cmd[4] = 0;