Exemplo n.º 1
0
bool
CmtUsbMsc::Init() {
  uint8   capasity[36];

  //Первый этап-чтение INQURY
  memset( &mCbw, 0, sizeof(MSC_CBW) );
  mCbw.bCBLength   = 6;
  mCbw.CB[0]       = SCSI_INQUIRY;
  mCbw.CB[4]       = 36;

  if( ReadSCSI( capasity, 36 ) != CMTE_OK ) return false;
  
  //Второй этап-чтение SENCE
  if( !RequestSense( capasity ) ) return false;
  
  //READ_FORMAT_CAPASITY
  memset( &mCbw, 0, sizeof(MSC_CBW) );
  mCbw.bCBLength   = 10;
  mCbw.CB[0]       = SCSI_READ_FORMAT_CAPACITIES;
  mCbw.CB[8]       = 12;

  if( ReadSCSI( capasity, 12 ) != CMTE_OK ) {
    //Для такого дебильного Flash подать SCSI_REQUEST_SENSE    
    if( !RequestSense( capasity ) ) return false;
    
    //Повторить CAPASITY
    memset( &mCbw, 0, sizeof(MSC_CBW) );
    mCbw.bCBLength   = 10;
    mCbw.CB[0]       = SCSI_READ_FORMAT_CAPACITIES;
    mCbw.CB[8]       = 12;
    
    if( ReadSCSI( capasity, 12 ) != CMTE_OK ) return false; //Повторный CAPASITY провалился
    }
  
  if( capasity[8] == 2 ) {
    mBlockSize = capasity[11] | (capasity[10] << 8) | (capasity[9] << 16);
    mBlockCount = capasity[7] | (capasity[6] << 8) | (capasity[5] << 16) | (capasity[4] << 24);
    }
  else {
    //Воспользуемся другой командой
    //CAPASITY
    memset( &mCbw, 0, sizeof(MSC_CBW) );
    mCbw.bCBLength   = 8;
    mCbw.CB[0]       = SCSI_READ_CAPACITY;
    if( ReadSCSI( capasity, 8 ) != CMTE_OK ) {
      //Для такого дебильного Flash подать SCSI_REQUEST_SENSE
      if( !RequestSense( capasity ) ) return false; //И Sense не помог

      memset( &mCbw, 0, sizeof(MSC_CBW) );
      mCbw.bCBLength   = 8;
      mCbw.CB[0]       = SCSI_READ_CAPACITY;
      if( ReadSCSI( capasity, 8 ) != CMTE_OK ) return false; //Повторный CAPASITY провалился
      }
    mBlockSize = capasity[7] | (capasity[6] << 8) | (capasity[5] << 16);
    mBlockCount = capasity[3] | (capasity[2] << 8) | (capasity[1] << 16) | (capasity[0] << 24);
    }
  //Инициализация прошла успешно
  return true;
  }
Exemplo n.º 2
0
/**
 * For driver use only.
 *
 * @param status
 * @return
 */
uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
        uint8_t ret = 0;

        switch(status) {
                case 0: return MASS_ERR_SUCCESS;

                case 2:
                        ErrorMessage<uint8_t > (PSTR("Phase Error"), status);
                        ErrorMessage<uint8_t > (PSTR("LUN"), bTheLUN);
                        ResetRecovery();
                        return MASS_ERR_GENERAL_SCSI_ERROR;

                case 1:
                        ErrorMessage<uint8_t > (PSTR("SCSI Error"), status);
                        ErrorMessage<uint8_t > (PSTR("LUN"), bTheLUN);
                        RequestSenseResponce rsp;

                        ret = RequestSense(bTheLUN, sizeof (RequestSenseResponce), (uint8_t*) & rsp);

                        if(ret) {
                                return MASS_ERR_GENERAL_SCSI_ERROR;
                        }
                        ErrorMessage<uint8_t > (PSTR("Response Code"), rsp.bResponseCode);
                        if(rsp.bResponseCode & 0x80) {
                                Notify(PSTR("Information field: "), 0x80);
                                for(int i = 0; i < 4; i++) {
                                        D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
                                        Notify(PSTR(" "), 0x80);
                                }
                                Notify(PSTR("\r\n"), 0x80);
                        }
                        ErrorMessage<uint8_t > (PSTR("Sense Key"), rsp.bmSenseKey);
                        ErrorMessage<uint8_t > (PSTR("Add Sense Code"), rsp.bAdditionalSenseCode);
                        ErrorMessage<uint8_t > (PSTR("Add Sense Qual"), rsp.bAdditionalSenseQualifier);
                        // warning, this is not testing ASQ, only SK and ASC.
                        switch(rsp.bmSenseKey) {
                                case SCSI_S_UNIT_ATTENTION:
                                        switch(rsp.bAdditionalSenseCode) {
                                                case SCSI_ASC_MEDIA_CHANGED:
                                                        return MASS_ERR_MEDIA_CHANGED;
                                                default:
                                                        return MASS_ERR_UNIT_NOT_READY;
                                        }
                                case SCSI_S_NOT_READY:
                                        switch(rsp.bAdditionalSenseCode) {
                                                case SCSI_ASC_MEDIUM_NOT_PRESENT:
                                                        return MASS_ERR_NO_MEDIA;
                                                default:
                                                        return MASS_ERR_UNIT_NOT_READY;
                                        }
                                case SCSI_S_ILLEGAL_REQUEST:
                                        switch(rsp.bAdditionalSenseCode) {
                                                case SCSI_ASC_LBA_OUT_OF_RANGE:
                                                        return MASS_ERR_BAD_LBA;
                                                default:
                                                        return MASS_ERR_CMD_NOT_SUPPORTED;
                                        }
                                default:
                                        return MASS_ERR_GENERAL_SCSI_ERROR;
                        }

                        // case 4: return MASS_ERR_UNIT_BUSY; // Busy means retry later.
                        //    case 0x05/0x14: we stalled out
                        //    case 0x15/0x16: we naked out.
                default:
                        ErrorMessage<uint8_t > (PSTR("Gen SCSI Err"), status);
                        ErrorMessage<uint8_t > (PSTR("LUN"), bTheLUN);
                        return status;
        } // switch
}