mirror of
https://github.com/STMicroelectronics/stm32-mw-usb-device.git
synced 2026-04-09 18:55:40 -04:00
Release v2.11.6
This commit is contained in:
@@ -85,6 +85,10 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
|
||||
static int8_t SCSI_RequestSense(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_ProcessModeSelect(USBD_HandleTypeDef *pdev, uint8_t lun,
|
||||
uint32_t param_list_length);
|
||||
static int8_t SCSI_ModeSelect6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_ModeSelect10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params);
|
||||
@@ -152,6 +156,14 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
|
||||
ret = SCSI_AllowPreventRemovable(pdev, lun, cmd);
|
||||
break;
|
||||
|
||||
case SCSI_MODE_SELECT6:
|
||||
ret = SCSI_ModeSelect6(pdev, lun, cmd);
|
||||
break;
|
||||
|
||||
case SCSI_MODE_SELECT10:
|
||||
ret = SCSI_ModeSelect10(pdev, lun, cmd);
|
||||
break;
|
||||
|
||||
case SCSI_MODE_SENSE6:
|
||||
ret = SCSI_ModeSense6(pdev, lun, cmd);
|
||||
break;
|
||||
@@ -202,6 +214,7 @@ int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *cmd)
|
||||
|
||||
default:
|
||||
SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
@@ -328,13 +341,15 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
|
||||
UNUSED(params);
|
||||
int8_t ret;
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr,
|
||||
&p_scsi_blk->size);
|
||||
|
||||
@@ -369,17 +384,19 @@ static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
|
||||
*/
|
||||
static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
UNUSED(params);
|
||||
uint32_t idx;
|
||||
uint32_t alloc_len;
|
||||
int8_t ret;
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
ret = ((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr,
|
||||
&p_scsi_blk->size);
|
||||
|
||||
@@ -389,12 +406,8 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
|
||||
return -1;
|
||||
}
|
||||
|
||||
hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
|
||||
((uint32_t)params[11] << 16) |
|
||||
((uint32_t)params[12] << 8) |
|
||||
(uint32_t)params[13];
|
||||
|
||||
for (idx = 0U; idx < hmsc->bot_data_length; idx++)
|
||||
/* READ CAPACITY(16) response is 32 bytes per SBC-3 */
|
||||
for (idx = 0U; idx < 32U; idx++)
|
||||
{
|
||||
hmsc->bot_data[idx] = 0U;
|
||||
}
|
||||
@@ -409,10 +422,13 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
|
||||
hmsc->bot_data[10] = (uint8_t)(p_scsi_blk->size >> 8);
|
||||
hmsc->bot_data[11] = (uint8_t)(p_scsi_blk->size);
|
||||
|
||||
hmsc->bot_data_length = ((uint32_t)params[10] << 24) |
|
||||
((uint32_t)params[11] << 16) |
|
||||
((uint32_t)params[12] << 8) |
|
||||
(uint32_t)params[13];
|
||||
/* Clamp transfer length to actual response size (32 bytes) */
|
||||
alloc_len = ((uint32_t)params[10] << 24) |
|
||||
((uint32_t)params[11] << 16) |
|
||||
((uint32_t)params[12] << 8) |
|
||||
(uint32_t)params[13];
|
||||
|
||||
hmsc->bot_data_length = MIN(alloc_len, 32U);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -427,8 +443,8 @@ static int8_t SCSI_ReadCapacity16(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t
|
||||
*/
|
||||
static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
UNUSED(params);
|
||||
uint16_t blk_size;
|
||||
uint16_t alloc_len;
|
||||
uint32_t blk_nbr;
|
||||
uint16_t i;
|
||||
int8_t ret;
|
||||
@@ -463,12 +479,116 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin
|
||||
hmsc->bot_data[10] = (uint8_t)(blk_size >> 8);
|
||||
hmsc->bot_data[11] = (uint8_t)(blk_size);
|
||||
|
||||
hmsc->bot_data_length = 12U;
|
||||
alloc_len = ((uint16_t)params[7] << 8) | (uint16_t)params[8];
|
||||
hmsc->bot_data_length = MIN(alloc_len, READ_FORMAT_CAPACITY_DATA_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SCSI_ProcessModeSelect
|
||||
* Drain MODE SELECT parameter data without applying mode pages
|
||||
* @param lun: Logical unit number
|
||||
* @param param_list_length: Mode parameter list length from the CDB
|
||||
* @retval status
|
||||
*/
|
||||
static int8_t SCSI_ProcessModeSelect(USBD_HandleTypeDef *pdev, uint8_t lun,
|
||||
uint32_t param_list_length)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
uint32_t packet_length;
|
||||
uint32_t rx_length;
|
||||
|
||||
UNUSED(param_list_length);
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
#endif /* USE_USBD_COMPOSITE */
|
||||
|
||||
if (hmsc->bot_state == USBD_BOT_IDLE)
|
||||
{
|
||||
if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
|
||||
{
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
hmsc->bot_data_length = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hmsc->cbw.dDataLength == 0U)
|
||||
{
|
||||
hmsc->bot_data_length = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_scsi_blk->len = hmsc->cbw.dDataLength;
|
||||
hmsc->bot_state = USBD_BOT_DATA_OUT;
|
||||
|
||||
packet_length = MIN(p_scsi_blk->len, MSC_MEDIA_PACKET);
|
||||
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, packet_length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
rx_length = USBD_LL_GetRxDataSize(pdev, MSCOutEpAdd);
|
||||
|
||||
if (rx_length >= p_scsi_blk->len)
|
||||
{
|
||||
hmsc->csw.dDataResidue -= p_scsi_blk->len;
|
||||
p_scsi_blk->len = 0U;
|
||||
MSC_BOT_SendCSW(pdev, USBD_CSW_CMD_PASSED);
|
||||
}
|
||||
else
|
||||
{
|
||||
p_scsi_blk->len -= rx_length;
|
||||
hmsc->csw.dDataResidue -= rx_length;
|
||||
packet_length = MIN(p_scsi_blk->len, MSC_MEDIA_PACKET);
|
||||
(void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, packet_length);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SCSI_ModeSelect6
|
||||
* Process Mode Select6 command
|
||||
* @param lun: Logical unit number
|
||||
* @param params: Command parameters
|
||||
* @retval status
|
||||
*/
|
||||
static int8_t SCSI_ModeSelect6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
return SCSI_ProcessModeSelect(pdev, lun, params[4]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SCSI_ModeSelect10
|
||||
* Process Mode Select10 command
|
||||
* @param lun: Logical unit number
|
||||
* @param params: Command parameters
|
||||
* @retval status
|
||||
*/
|
||||
static int8_t SCSI_ModeSelect10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
uint32_t param_list_length;
|
||||
|
||||
param_list_length = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
|
||||
|
||||
return SCSI_ProcessModeSelect(pdev, lun, param_list_length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief SCSI_ModeSense6
|
||||
* Process Mode Sense6 command
|
||||
@@ -478,7 +598,6 @@ static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uin
|
||||
*/
|
||||
static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
UNUSED(lun);
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint16_t len = MODE_SENSE6_LEN;
|
||||
|
||||
@@ -494,7 +613,7 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_Mode_Sense10_data[2] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */
|
||||
MSC_Mode_Sense6_data[2] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */
|
||||
}
|
||||
|
||||
if (params[4] <= len)
|
||||
@@ -517,9 +636,9 @@ static int8_t SCSI_ModeSense6(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
|
||||
*/
|
||||
static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
UNUSED(lun);
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint16_t len = MODE_SENSE10_LEN;
|
||||
uint16_t alloc_len;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
@@ -536,9 +655,12 @@ static int8_t SCSI_ModeSense10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *p
|
||||
MSC_Mode_Sense10_data[3] &= ~(0x1U << 7); /* Clear the WP (write protection) bit */
|
||||
}
|
||||
|
||||
if (params[8] <= len)
|
||||
/* Allocation length is a 16-bit field: CDB bytes 7-8 */
|
||||
alloc_len = ((uint16_t)params[7] << 8) | (uint16_t)params[8];
|
||||
|
||||
if (alloc_len < len)
|
||||
{
|
||||
len = params[8];
|
||||
len = alloc_len;
|
||||
}
|
||||
|
||||
(void)SCSI_UpdateBotData(hmsc, MSC_Mode_Sense10_data, len);
|
||||
@@ -631,6 +753,16 @@ void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t
|
||||
{
|
||||
hmsc->scsi_sense_tail = 0U;
|
||||
}
|
||||
|
||||
if (hmsc->scsi_sense_tail == hmsc->scsi_sense_head)
|
||||
{
|
||||
hmsc->scsi_sense_head++;
|
||||
|
||||
if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH)
|
||||
{
|
||||
hmsc->scsi_sense_head = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -722,13 +854,15 @@ static int8_t SCSI_AllowPreventRemovable(USBD_HandleTypeDef *pdev, uint8_t lun,
|
||||
static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
|
||||
{
|
||||
/* case 10 : Ho <> Di */
|
||||
@@ -788,13 +922,15 @@ static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
|
||||
static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */
|
||||
{
|
||||
/* case 10 : Ho <> Di */
|
||||
@@ -856,7 +992,7 @@ static int8_t SCSI_Read12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params
|
||||
static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
uint32_t len;
|
||||
|
||||
if (hmsc == NULL)
|
||||
@@ -864,6 +1000,8 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
@@ -884,10 +1022,18 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check whether Media is ready */
|
||||
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -895,6 +1041,7 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
|
||||
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsWriteProtected(lun) != 0)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, NOT_READY, WRITE_PROTECTED);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -946,13 +1093,16 @@ static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
|
||||
static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
uint32_t len;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
/* Get the Endpoints addresses allocated for this class instance */
|
||||
MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
|
||||
@@ -973,6 +1123,13 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check whether Media is ready */
|
||||
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
|
||||
{
|
||||
@@ -1039,20 +1196,51 @@ static int8_t SCSI_Write12(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *param
|
||||
static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
uint32_t blk_offset;
|
||||
uint32_t blk_nbr;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hmsc->cbw.dDataLength != 0U)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_CDB);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hmsc->scsi_medium_state == SCSI_MEDIUM_EJECTED)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->IsReady(lun) != 0)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, NOT_READY, MEDIUM_NOT_PRESENT);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((params[1] & 0x02U) == 0x02U)
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, INVALID_FIELD_IN_COMMAND);
|
||||
hmsc->bot_state = USBD_BOT_NO_DATA;
|
||||
return -1; /* Error, Verify Mode Not supported*/
|
||||
}
|
||||
|
||||
if (SCSI_CheckAddressRange(pdev, lun, p_scsi_blk->addr, p_scsi_blk->len) < 0)
|
||||
/* Decode LBA and verification length from current CDB */
|
||||
blk_offset = ((uint32_t)params[2] << 24) |
|
||||
((uint32_t)params[3] << 16) |
|
||||
((uint32_t)params[4] << 8) |
|
||||
(uint32_t)params[5];
|
||||
|
||||
blk_nbr = ((uint32_t)params[7] << 8) | (uint32_t)params[8];
|
||||
|
||||
if (SCSI_CheckAddressRange(pdev, lun, blk_offset, blk_nbr) < 0)
|
||||
{
|
||||
return -1; /* error */
|
||||
}
|
||||
@@ -1070,15 +1258,16 @@ static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *para
|
||||
static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc;
|
||||
uint32_t report_idx;
|
||||
uint32_t lun_list_length;
|
||||
uint32_t total_length;
|
||||
uint32_t alloc_len;
|
||||
uint8_t lun_idx;
|
||||
|
||||
UNUSED(lun);
|
||||
UNUSED(params);
|
||||
|
||||
/* Define the report LUNs buffer Each LUN entry is 8 bytes */
|
||||
static uint8_t lun_report[8U * (MSC_BOT_MAX_LUN + 1U)];
|
||||
/* Define the report LUNs buffer: 8-byte header + 8 bytes per LUN entry */
|
||||
static uint8_t lun_report[8U + (8U * (MSC_BOT_MAX_LUN + 1U))];
|
||||
|
||||
hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
|
||||
@@ -1088,7 +1277,10 @@ static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
|
||||
}
|
||||
|
||||
/* Initialize the report LUNs buffer */
|
||||
(void)USBD_memset(lun_report, 0, sizeof(lun_report));
|
||||
for (report_idx = 0U; report_idx < sizeof(lun_report); report_idx++)
|
||||
{
|
||||
lun_report[report_idx] = 0U;
|
||||
}
|
||||
|
||||
/* Set the LUN list length in the first 4 bytes */
|
||||
lun_list_length = 8U * (hmsc->max_lun + 1U);
|
||||
@@ -1107,6 +1299,17 @@ static int8_t SCSI_ReportLuns(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *pa
|
||||
/* Calculate the total length of the report LUNs buffer */
|
||||
total_length = lun_list_length + 8U;
|
||||
|
||||
/* Clamp to allocation length from CDB bytes 6-9 */
|
||||
alloc_len = ((uint32_t)params[6] << 24) |
|
||||
((uint32_t)params[7] << 16) |
|
||||
((uint32_t)params[8] << 8) |
|
||||
(uint32_t)params[9];
|
||||
|
||||
if (alloc_len < total_length)
|
||||
{
|
||||
total_length = alloc_len;
|
||||
}
|
||||
|
||||
/* Update the BOT data with the report LUNs buffer */
|
||||
(void)SCSI_UpdateBotData(hmsc, lun_report, (uint16_t)total_length);
|
||||
|
||||
@@ -1126,11 +1329,17 @@ static int8_t SCSI_ReceiveDiagnosticResults(USBD_HandleTypeDef *pdev, uint8_t lu
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
uint16_t allocation_length;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Extract the allocation length from the CDB */
|
||||
allocation_length = (((uint16_t)params[3] << 8) | (uint16_t)params[4]);
|
||||
|
||||
if (allocation_length == 0U)
|
||||
{
|
||||
hmsc->bot_data_length = 0U;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1158,14 +1367,21 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
|
||||
uint32_t blk_offset, uint32_t blk_nbr)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
|
||||
if (hmsc == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((blk_offset + blk_nbr) > p_scsi_blk->nbr)
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
/* Refresh cached capacity for this LUN so multi-LUN configs
|
||||
with different sizes use the correct block count. */
|
||||
(void)((USBD_StorageTypeDef *)pdev->pUserData[pdev->classId])->GetCapacity(lun, &p_scsi_blk->nbr,
|
||||
&p_scsi_blk->size);
|
||||
|
||||
if ((blk_nbr > p_scsi_blk->nbr) || (blk_offset > (p_scsi_blk->nbr - blk_nbr)))
|
||||
{
|
||||
SCSI_SenseCode(pdev, lun, ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
|
||||
return -1;
|
||||
@@ -1183,7 +1399,7 @@ static int8_t SCSI_CheckAddressRange(USBD_HandleTypeDef *pdev, uint8_t lun,
|
||||
static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
uint32_t len;
|
||||
|
||||
if (hmsc == NULL)
|
||||
@@ -1191,6 +1407,8 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
len = p_scsi_blk->len * p_scsi_blk->size;
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
@@ -1233,7 +1451,7 @@ static int8_t SCSI_ProcessRead(USBD_HandleTypeDef *pdev, uint8_t lun)
|
||||
static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
|
||||
{
|
||||
USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
USBD_MSC_BOT_LUN_TypeDef *p_scsi_blk;
|
||||
uint32_t len;
|
||||
|
||||
if (hmsc == NULL)
|
||||
@@ -1241,6 +1459,8 @@ static int8_t SCSI_ProcessWrite(USBD_HandleTypeDef *pdev, uint8_t lun)
|
||||
return -1;
|
||||
}
|
||||
|
||||
p_scsi_blk = &hmsc->scsi_blk[lun];
|
||||
|
||||
len = p_scsi_blk->len * p_scsi_blk->size;
|
||||
|
||||
#ifdef USE_USBD_COMPOSITE
|
||||
|
||||
Reference in New Issue
Block a user