sources/common/libs/STM32Cube_F4/Middlewares/ST/STM32_USB_Device_Library/Class/MSC/Src/usbd_msc_scsi.c
/**
  * @brief  SCSI_Write12
  *         Process Write12 command
  * @param  lun: Logical unit number
  * @param  params: Command parameters
  * @retval status
  */
@brief  SCSI_Write12
Process Write12 command
@param  lun: Logical unit number
@param  params: Command parameters
@retval status
@brief SCSI_Write12 Process Write12 command @param lun : Logical unit number @param params : Command parameters @retval status
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];
  uint32_t len;
  if (hmsc == NULL)
  {
    return -1;
  }
#ifdef USE_USBD_COMPOSITE
  MSCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK);
#endif 
  if (hmsc->bot_state == USBD_BOT_IDLE) 
  {
    if (hmsc->cbw.dDataLength == 0U)
    {
      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
      return -1;
    }
    if ((hmsc->cbw.bmFlags & 0x80U) == 0x80U)
    {
      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
      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 (((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;
    }
    hmsc->scsi_blk_addr = ((uint32_t)params[2] << 24) |
                          ((uint32_t)params[3] << 16) |
                          ((uint32_t)params[4] << 8) |
                          (uint32_t)params[5];
    hmsc->scsi_blk_len = ((uint32_t)params[6] << 24) |
                         ((uint32_t)params[7] << 16) |
                         ((uint32_t)params[8] << 8) |
                         (uint32_t)params[9];
    if (SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr,
                               hmsc->scsi_blk_len) < 0)
    {
      return -1; 
    }
    len = hmsc->scsi_blk_len * hmsc->scsi_blk_size;
    if (hmsc->cbw.dDataLength != len)
    {
      SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
      return -1;
    }
    len = MIN(len, MSC_MEDIA_PACKET);
    hmsc->bot_state = USBD_BOT_DATA_OUT;
    (void)USBD_LL_PrepareReceive(pdev, MSCOutEpAdd, hmsc->bot_data, len);
  }
  else 
  {
    return SCSI_ProcessWrite(pdev, lun);
  }
  return 0;
}
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 ] ; uint32_t len ; if ( hmsc == NULL ) { return -1 ; } #ifdef USE_USBD_COMPOSITE MSCOutEpAdd = USBD_CoreGetEPAdd ( pdev , USBD_EP_OUT , USBD_EP_TYPE_BULK ) ; #endif if ( hmsc -> bot_state == USBD_BOT_IDLE ) { if ( hmsc -> cbw . dDataLength == 0U ) { SCSI_SenseCode ( pdev , hmsc -> cbw . bLUN , ILLEGAL_REQUEST , INVALID_CDB ) ; return -1 ; } if ( ( hmsc -> cbw . bmFlags & 0x80U ) == 0x80U ) { SCSI_SenseCode ( pdev , hmsc -> cbw . bLUN , ILLEGAL_REQUEST , INVALID_CDB ) ; 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 ( ( ( 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 ; } hmsc -> scsi_blk_addr = ( ( uint32_t ) params [ 2 ] << 24 ) | ( ( uint32_t ) params [ 3 ] << 16 ) | ( ( uint32_t ) params [ 4 ] << 8 ) | ( uint32_t ) params [ 5 ] ; hmsc -> scsi_blk_len = ( ( uint32_t ) params [ 6 ] << 24 ) | ( ( uint32_t ) params [ 7 ] << 16 ) | ( ( uint32_t ) params [ 8 ] << 8 ) | ( uint32_t ) params [ 9 ] ; if ( SCSI_CheckAddressRange ( pdev , lun , hmsc -> scsi_blk_addr , hmsc -> scsi_blk_len ) < 0 ) { return -1 ; } len = hmsc -> scsi_blk_len * hmsc -> scsi_blk_size ; if ( hmsc -> cbw . dDataLength != len ) { SCSI_SenseCode ( pdev , hmsc -> cbw . bLUN , ILLEGAL_REQUEST , INVALID_CDB ) ; return -1 ; } len = MIN ( len , MSC_MEDIA_PACKET ) ; hmsc -> bot_state = USBD_BOT_DATA_OUT ; ( void ) USBD_LL_PrepareReceive ( pdev , MSCOutEpAdd , hmsc -> bot_data , len ) ; } else { return SCSI_ProcessWrite ( pdev , lun ) ; } return 0 ; }
@brief  SCSI_Write12
         Process Write12 command
 @param  lun: Logical unit number
 @param  params: Command parameters
 @retval status
@brief SCSI_Write12 Process Write12 command @param lun : Logical unit number @param params : Command parameters @retval status
/* Get the Endpoints addresses allocated for this class instance */ /* USE_USBD_COMPOSITE */ /* Idle */ /* case 8 : Hi <> Do */ /* Check whether Media is ready */ /* Check If media is write-protected */ /* check if LBA address is in the right range */ /* error */ /* cases 3,11,13 : Hn,Ho <> D0 */ /* Prepare EP to receive first data packet */ /* Write Process ongoing */