From 75aabe595f2641a671a2da7e304e4779084a4238 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sun, 29 Oct 2023 16:23:30 +0900 Subject: [PATCH] usb: storage: Use the correct CBW lengths USB UFI uses fixed 12-byte commands (as does RBC, which is not supported), but SCSI does not have this limitation. Use the correct command block lengths depending on the subclass. Signed-off-by: Hector Martin Reviewed-by: Marek Vasut --- common/usb_storage.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/common/usb_storage.c b/common/usb_storage.c index 35c656db0d..774d5bdf54 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -102,6 +102,7 @@ struct us_data { trans_reset transport_reset; /* reset routine */ trans_cmnd transport; /* transport routine */ unsigned short max_xfer_blk; /* maximum transfer blocks */ + bool cmd12; /* use 12-byte commands (RBC/UFI) */ }; #if !CONFIG_IS_ENABLED(BLK) @@ -359,7 +360,7 @@ static void usb_show_srb(struct scsi_cmd *pccb) { int i; printf("SRB: len %d datalen 0x%lX\n ", pccb->cmdlen, pccb->datalen); - for (i = 0; i < 12; i++) + for (i = 0; i < pccb->cmdlen; i++) printf("%02X ", pccb->cmd[i]); printf("\n"); } @@ -898,7 +899,7 @@ do_retry: psrb->cmd[4] = 18; psrb->datalen = 18; psrb->pdata = &srb->sense_buf[0]; - psrb->cmdlen = 12; + psrb->cmdlen = us->cmd12 ? 12 : 6; /* issue the command */ result = usb_stor_CB_comdat(psrb, us); debug("auto request returned %d\n", result); @@ -999,7 +1000,7 @@ static int usb_inquiry(struct scsi_cmd *srb, struct us_data *ss) srb->cmd[1] = srb->lun << 5; srb->cmd[4] = 36; srb->datalen = 36; - srb->cmdlen = 12; + srb->cmdlen = ss->cmd12 ? 12 : 6; i = ss->transport(srb, ss); debug("inquiry returns %d\n", i); if (i == 0) @@ -1024,7 +1025,7 @@ static int usb_request_sense(struct scsi_cmd *srb, struct us_data *ss) srb->cmd[4] = 18; srb->datalen = 18; srb->pdata = &srb->sense_buf[0]; - srb->cmdlen = 12; + srb->cmdlen = ss->cmd12 ? 12 : 6; ss->transport(srb, ss); debug("Request Sense returned %02X %02X %02X\n", srb->sense_buf[2], srb->sense_buf[12], @@ -1042,7 +1043,7 @@ static int usb_test_unit_ready(struct scsi_cmd *srb, struct us_data *ss) srb->cmd[0] = SCSI_TST_U_RDY; srb->cmd[1] = srb->lun << 5; srb->datalen = 0; - srb->cmdlen = 12; + srb->cmdlen = ss->cmd12 ? 12 : 6; if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) { ss->flags |= USB_READY; return 0; @@ -1074,7 +1075,7 @@ static int usb_read_capacity(struct scsi_cmd *srb, struct us_data *ss) srb->cmd[0] = SCSI_RD_CAPAC; srb->cmd[1] = srb->lun << 5; srb->datalen = 8; - srb->cmdlen = 12; + srb->cmdlen = ss->cmd12 ? 12 : 10; if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) return 0; } while (retry--); @@ -1094,7 +1095,7 @@ static int usb_read_10(struct scsi_cmd *srb, struct us_data *ss, srb->cmd[5] = ((unsigned char) (start)) & 0xff; srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff; srb->cmd[8] = (unsigned char) blocks & 0xff; - srb->cmdlen = 12; + srb->cmdlen = ss->cmd12 ? 12 : 10; debug("read10: start %lx blocks %x\n", start, blocks); return ss->transport(srb, ss); } @@ -1111,7 +1112,7 @@ static int usb_write_10(struct scsi_cmd *srb, struct us_data *ss, srb->cmd[5] = ((unsigned char) (start)) & 0xff; srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff; srb->cmd[8] = (unsigned char) blocks & 0xff; - srb->cmdlen = 12; + srb->cmdlen = ss->cmd12 ? 12 : 10; debug("write10: start %lx blocks %x\n", start, blocks); return ss->transport(srb, ss); } @@ -1417,6 +1418,11 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum, printf("Sorry, protocol %d not yet supported.\n", ss->subclass); return 0; } + + /* UFI uses 12-byte commands (like RBC, unlike SCSI) */ + if (ss->subclass == US_SC_UFI) + ss->cmd12 = true; + if (ss->ep_int) { /* we had found an interrupt endpoint, prepare irq pipe * set up the IRQ pipe and handler -- 2.39.5