⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi_decoder.c

📁 Contiki是一个开源
💻 C
📖 第 1 页 / 共 2 页
字号:
      break;   }   return TRUE;}Bool sbc_read_capacity (void){   _MEM_TYPE_SLOW_ U32 mem_size_nb_sector;   switch ( mem_read_capacity( usb_LUN, &mem_size_nb_sector ) )   {   case CTRL_GOOD :      Usb_write_byte(MSB0(mem_size_nb_sector));  // return nb block      Usb_write_byte(MSB1(mem_size_nb_sector));      Usb_write_byte(MSB2(mem_size_nb_sector));      Usb_write_byte(MSB3(mem_size_nb_sector));      Usb_write_byte( 0               );        // return block size (= 512B)      Usb_write_byte( 0               );      Usb_write_byte( (U8)(512 >> 8)  );      Usb_write_byte( (U8)(512 & 0xFF));      Sbc_valid_write_usb(SBC_READ_CAPACITY_LENGTH);      sbc_lun_status_is_good();      return TRUE;      break;   case CTRL_NO_PRESENT :      sbc_lun_status_is_not_present();      break;   case CTRL_BUSY :      sbc_lun_status_is_busy_or_change();      break;   case CTRL_FAIL :   default :      sbc_lun_status_is_fail();      break;   }   return FALSE;}Bool sbc_read_10 (void){   U32   mass_addr;                    // rd or wr block address   U16   mass_size;                    // rd or write nb of blocks   MSB0(mass_addr) = g_scsi_command[2];  // read address   MSB1(mass_addr) = g_scsi_command[3];   MSB2(mass_addr) = g_scsi_command[4];   MSB3(mass_addr) = g_scsi_command[5];   MSB(mass_size) = g_scsi_command[7];  // read size   LSB(mass_size) = g_scsi_command[8];   if (mass_size != 0)   {      switch ( memory_2_usb( usb_LUN , mass_addr, mass_size ) )      {      case CTRL_GOOD :         sbc_lun_status_is_good();         g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);         return TRUE;         break;      case CTRL_NO_PRESENT :         sbc_lun_status_is_not_present();         return FALSE;         break;      case CTRL_BUSY :         sbc_lun_status_is_busy_or_change();         return FALSE;         break;      case CTRL_FAIL :      default :         sbc_lun_status_is_fail();         return FALSE;         break;      }   }   else   {  // No data to transfer      sbc_lun_status_is_good();   }   return TRUE;}Bool sbc_write_10 (void){   U32   mass_addr;                    // rd or wr block address   U16   mass_size;                    // rd or write nb of blocks   MSB0(mass_addr) = g_scsi_command[2];  // read address   MSB1(mass_addr) = g_scsi_command[3];   MSB2(mass_addr) = g_scsi_command[4];   MSB3(mass_addr) = g_scsi_command[5];   MSB(mass_size) = g_scsi_command[7];  // read size   LSB(mass_size) = g_scsi_command[8];   if (mass_size != 0)   {      if( TRUE == mem_wr_protect( usb_LUN ) )      {         sbc_lun_status_is_protected();         return FALSE;#warning For Win98 data must be read to avoid blocking      }      else      {         switch (usb_2_memory( usb_LUN , mass_addr, mass_size ))         {         case CTRL_GOOD :            sbc_lun_status_is_good();            g_scsi_data_remaining = g_scsi_data_remaining - (512 * (Uint32)mass_size);            return TRUE;            break;         case CTRL_NO_PRESENT :            sbc_lun_status_is_not_present();            return FALSE;            break;         case CTRL_BUSY :            sbc_lun_status_is_busy_or_change();            return FALSE;            break;         case CTRL_FAIL :         default :            sbc_lun_status_is_fail();            return FALSE;            break;         }      }   }   else   {  // No data to transfer      sbc_lun_status_is_good();   }   return TRUE;}/** * @brief This function manages the SCSI MODE SENSE command (0x1A for sense 6 and 0x5A for sense 10) * * The SCSI mode sense function returns parameters to an application client. * It is a complementary command to the SCSI MODE SELECT command. * * @warning Code:.. bytes (function code length) * * @param b_sense_10 ( TRUE = sense 10, TRUE = sense 6) * * @return  FALSE: result KO, *          TRUE:  result OK * */Bool sbc_mode_sense( Bool b_sense_10 ){   U8 allocation_length;   if( b_sense_10 )      allocation_length = g_scsi_command[8];   else      allocation_length = g_scsi_command[4];   // switch for page code   switch ( g_scsi_command[2] & SBC_MSK_PAGE_CODE )   {      case SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS:       /* Page Code: Informational exceptions control page */         sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS );         send_informational_exceptions_page();         Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_INFORMATIONAL_EXCEPTIONS + 1);         break;      case SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY:         sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY );         send_read_write_error_recovery_page(allocation_length);         Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_READ_WRITE_ERROR_RECOVERY + 1);         break;      case SBC_PAGE_CODE_ALL:         sbc_header_mode_sense( b_sense_10 , SBC_MODE_DATA_LENGTH_CODE_ALL );         if( b_sense_10 )         {            if (allocation_length == 8)            {               Sbc_valid_write_usb(8);               break;            }         }         else         {            if (allocation_length == 4)            {               Sbc_valid_write_usb(4);               break;            }         }         // send page by ascending order code         send_read_write_error_recovery_page(allocation_length);  // 12 bytes         if (allocation_length > 12)         {            send_informational_exceptions_page();                 // 12 bytes            Sbc_valid_write_usb(SBC_MODE_DATA_LENGTH_CODE_ALL + 1);         }         else         {            Sbc_valid_write_usb(allocation_length);         }         break;      default:           Sbc_send_failed();           Sbc_build_sense(SBC_SENSE_KEY_ILLEGAL_REQUEST, SBC_ASC_INVALID_FIELD_IN_CDB, 0x00);           return FALSE;           break;   }   sbc_lun_status_is_good();   return TRUE;}/** * @brief This function send the header of the SCSI MODE SENSE command * * @param b_sense_10 TRUE = sense 10, FALSE = sense 6 * @param u8_data_length data length in byte * */void sbc_header_mode_sense( Bool b_sense_10 , U8 u8_data_length ){   // Send Data length   if( b_sense_10 )   {      Usb_write_byte(0);   }   Usb_write_byte( u8_data_length );   // Send device type   Usb_write_byte(SBC_MEDIUM_TYPE);   // Write protect status   if (mem_wr_protect( usb_LUN ))   {      Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_PROTECT);  // Device is write protected   }   else   {      Usb_write_byte(SBC_DEV_SPEC_PARAM_WR_ENABLE);   // Device is write enabled   }   if( b_sense_10 )   {  // Reserved      Usb_write_byte(0);      Usb_write_byte(0);   }   // Send Block descriptor length   if( b_sense_10 )   {      Usb_write_byte(0);   }   Usb_write_byte(SBC_BLOCK_DESCRIPTOR_LENGTH);}/** * @brief This function writes informational exceptions page parameters * * @warning Code:.. bytes (function code length) * * @return  FALSE: result KO, *          TRUE:  result OK * */void send_informational_exceptions_page (void){   Usb_write_byte(SBC_PAGE_CODE_INFORMATIONAL_EXCEPTIONS);     /* Page Code: Informational exceptions control page */                                                               /* See chapter 8.3.8 on SPC-2 specification */   Usb_write_byte(SBC_PAGE_LENGTH_INFORMATIONAL_EXCEPTIONS);   /* Page Length */   Usb_write_byte(0x00);                                       /* ..., Test bit = 0, ... */   Usb_write_byte(SBC_MRIE);                                   /* MRIE = 0x05 */   Usb_write_byte(0x00);                                       /* Interval Timer (MSB) */   Usb_write_byte(0x00);   Usb_write_byte(0x00);   Usb_write_byte(0x00);                                       /* Interval Timer (LSB) */   Usb_write_byte(0x00);                                       /* Report Count (MSB) */   Usb_write_byte(0x00);   Usb_write_byte(0x00);   Usb_write_byte(0x01);                                       /* Report Count (LSB) */}/** * @brief This function writes error recovery page * * @warning Code:.. bytes (function code length) * * @param length The length of  * * @return  FALSE: result KO, *          TRUE:  result OK * */void send_read_write_error_recovery_page (U8 length){   Usb_write_byte(SBC_PAGE_CODE_READ_WRITE_ERROR_RECOVERY);   Usb_write_byte(SBC_PAGE_LENGTH_READ_WRITE_ERROR_RECOVERY);   /* Page Length */   Usb_write_byte(0x80);   Usb_write_byte(SBC_READ_RETRY_COUNT);   Usb_write_byte(SBC_CORRECTION_SPAN);   Usb_write_byte(SBC_HEAD_OFFSET_COUNT);   Usb_write_byte(SBC_DATA_STROBE_OFFSET);   Usb_write_byte(0x00);   /* Reserved */   if (length > 12)   {      Usb_write_byte(SBC_WRITE_RETRY_COUNT);      Usb_write_byte(0x00);      Usb_write_byte(SBC_RECOVERY_LIMIT_MSB);      Usb_write_byte(SBC_RECOVERY_LIMIT_LSB);   }}/** * @brief This function manages the SCSI PREVENT ALLOW MEDIUM REMOVAL *        command (0x1E) * * The SCSI prevent allow medium removal command requests that the target * enable or disable the removal of the medium in the logical unit. * * @warning Code:.. bytes (function code length) * * @return  FALSE: result KO, *          TRUE:  result OK * */Bool sbc_prevent_allow_medium_removal(void){   sbc_lun_status_is_good();   return TRUE;}//! This fonction send the UFI status GOOD//!void sbc_lun_status_is_good(void){   Sbc_send_good();   Sbc_build_sense(SBC_SENSE_KEY_NO_SENSE, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);}//! This fonction send the UFI status "lun not present"//!void sbc_lun_status_is_not_present(void){   Sbc_send_failed();   Sbc_build_sense(SBC_SENSE_KEY_NOT_READY, SBC_ASC_MEDIUM_NOT_PRESENT, 0x00);}//! This fonction send the UFI status busy and change//!void sbc_lun_status_is_busy_or_change(void){   Sbc_send_failed();   Sbc_build_sense(SBC_SENSE_KEY_UNIT_ATTENTION, SBC_ASC_NOT_READY_TO_READY_CHANGE, 0x00 );}//! This fonction send the UFI status FAIL//!void sbc_lun_status_is_fail(void){   Sbc_send_failed();   Sbc_build_sense(SBC_SENSE_KEY_HARDWARE_ERROR, SBC_ASC_NO_ADDITIONAL_SENSE_INFORMATION, 0x00);}//! This fonction send the UFI status FAIL because write protection//!void sbc_lun_status_is_protected(void){   Sbc_send_failed();   Sbc_build_sense(SBC_SENSE_KEY_DATA_PROTECT, SBC_ASC_WRITE_PROTECTED, 0x00);}/** @} */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -