summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2020-07-22 23:45:08 +1000
committerDamien George <damien@micropython.org>2020-07-25 01:12:07 +1000
commitfd2ff867a08fd174f0bbf7a03aa59547634e91ac (patch)
tree3606569212afbceffe7977599b4f4abac7d1f84f
parent37e1b5c891f9964bb6c95228bc2d718511507a69 (diff)
stm32/usbdev: Fix calculation of SCSI LUN size with multiple LUNs.
The SCSI driver calls GetCapacity to get the block size and number of blocks of the underlying block-device/LUN. It caches these values and uses them later on to verify that reads/writes are within the bounds of the LUN. But, prior to this commit, there was only one set of cached values for all LUNs, so the bounds checking for a LUN could use incorrect values, values from one of the other LUNs that most recently updated the cached values. This would lead to failed SCSI requests. This commit fixes this issue by having separate cached values for each LUN. Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--ports/stm32/usbd_msc_interface.h2
-rw-r--r--ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h7
-rw-r--r--ports/stm32/usbdev/class/src/usbd_msc_scsi.c34
3 files changed, 23 insertions, 20 deletions
diff --git a/ports/stm32/usbd_msc_interface.h b/ports/stm32/usbd_msc_interface.h
index 411c707ca..9d25a72a3 100644
--- a/ports/stm32/usbd_msc_interface.h
+++ b/ports/stm32/usbd_msc_interface.h
@@ -26,8 +26,6 @@
#ifndef MICROPY_INCLUDED_STM32_USBD_MSC_INTERFACE_H
#define MICROPY_INCLUDED_STM32_USBD_MSC_INTERFACE_H
-#define USBD_MSC_MAX_LUN (2)
-
extern const USBD_StorageTypeDef usbd_msc_fops;
void usbd_msc_init_lu(size_t lu_n, const void *lu_data);
diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
index d934f4676..d6c38bbd0 100644
--- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
+++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h
@@ -34,6 +34,9 @@
#define MSC_MEDIA_PACKET (2048) // was 8192; how low can it go whilst still working?
#define HID_DATA_FS_MAX_PACKET_SIZE (64) // endpoint IN & OUT packet size
+// Maximum number of LUN that can be exposed on the MSC interface
+#define USBD_MSC_MAX_LUN (2)
+
// Need to define here for BOT and SCSI layers
#define MSC_IN_EP (0x81)
#define MSC_OUT_EP (0x01)
@@ -78,8 +81,8 @@ typedef struct {
uint8_t scsi_sense_head;
uint8_t scsi_sense_tail;
- uint16_t scsi_blk_size;
- uint32_t scsi_blk_nbr;
+ uint16_t scsi_blk_size[USBD_MSC_MAX_LUN];
+ uint32_t scsi_blk_nbr[USBD_MSC_MAX_LUN];
uint32_t scsi_blk_addr_in_blks;
uint32_t scsi_blk_len;
diff --git a/ports/stm32/usbdev/class/src/usbd_msc_scsi.c b/ports/stm32/usbdev/class/src/usbd_msc_scsi.c
index d0413b758..2eb716ccd 100644
--- a/ports/stm32/usbdev/class/src/usbd_msc_scsi.c
+++ b/ports/stm32/usbdev/class/src/usbd_msc_scsi.c
@@ -247,7 +247,7 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_
{
USBD_MSC_BOT_HandleTypeDef *hmsc = &((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->MSC_BOT_ClassData;
- if(hmsc->bdev_ops->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0)
+ if(hmsc->bdev_ops->GetCapacity(lun, &hmsc->scsi_blk_nbr[lun], &hmsc->scsi_blk_size[lun]) != 0)
{
SCSI_SenseCode(pdev,
lun,
@@ -258,15 +258,17 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_
else
{
- hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 24);
- hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 16);
- hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 8);
- hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1);
+ uint32_t blk_nbr = hmsc->scsi_blk_nbr[lun];
+ hmsc->bot_data[0] = (uint8_t)((blk_nbr - 1) >> 24);
+ hmsc->bot_data[1] = (uint8_t)((blk_nbr - 1) >> 16);
+ hmsc->bot_data[2] = (uint8_t)((blk_nbr - 1) >> 8);
+ hmsc->bot_data[3] = (uint8_t)(blk_nbr - 1);
- hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24);
- hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16);
- hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8);
- hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size);
+ uint32_t blk_size = hmsc->scsi_blk_size[lun];
+ hmsc->bot_data[4] = (uint8_t)(blk_size >> 24);
+ hmsc->bot_data[5] = (uint8_t)(blk_size >> 16);
+ hmsc->bot_data[6] = (uint8_t)(blk_size >> 8);
+ hmsc->bot_data[7] = (uint8_t)(blk_size);
hmsc->bot_data_length = 8;
return 0;
@@ -516,7 +518,7 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *para
}
hmsc->bot_state = USBD_BOT_DATA_IN;
- hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
+ hmsc->scsi_blk_len *= hmsc->scsi_blk_size[lun];
/* cases 4,5 : Hi <> Dn */
if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
@@ -596,7 +598,7 @@ static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *pa
return -1; /* error */
}
- hmsc->scsi_blk_len *= hmsc->scsi_blk_size;
+ hmsc->scsi_blk_len *= hmsc->scsi_blk_size[lun];
/* cases 3,11,13 : Hn,Ho <> D0 */
if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len)
@@ -670,7 +672,7 @@ static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev, uint8_t lun , u
{
USBD_MSC_BOT_HandleTypeDef *hmsc = &((usbd_cdc_msc_hid_state_t*)pdev->pClassData)->MSC_BOT_ClassData;
- if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr )
+ if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr[lun])
{
SCSI_SenseCode(pdev,
lun,
@@ -697,7 +699,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun)
if( hmsc->bdev_ops->Read(lun ,
hmsc->bot_data,
hmsc->scsi_blk_addr_in_blks,
- len / hmsc->scsi_blk_size) < 0)
+ len / hmsc->scsi_blk_size[lun]) < 0)
{
SCSI_SenseCode(pdev,
@@ -714,7 +716,7 @@ static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun)
len);
- hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size;
+ hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size[lun];
hmsc->scsi_blk_len -= len;
/* case 6 : Hi = Di */
@@ -744,7 +746,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun)
if(hmsc->bdev_ops->Write(lun ,
hmsc->bot_data,
hmsc->scsi_blk_addr_in_blks,
- len / hmsc->scsi_blk_size) < 0)
+ len / hmsc->scsi_blk_size[lun]) < 0)
{
SCSI_SenseCode(pdev,
lun,
@@ -754,7 +756,7 @@ static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun)
}
- hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size;
+ hmsc->scsi_blk_addr_in_blks += len / hmsc->scsi_blk_size[lun];
hmsc->scsi_blk_len -= len;
/* case 12 : Ho = Do */