/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity * on the selected Logical Unit (drive), as a number of OS-sized blocks. * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with */ static void SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* MSInterfaceInfo) { uint32_t LastBlockAddressInLUN = (VIRTUAL_MEMORY_BLOCKS - 1); uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE; Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NO_STREAM_CALLBACK); Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NO_STREAM_CALLBACK); Endpoint_ClearIN(); /* Succeed the command and update the bytes transferred counter */ MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; }
/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity * on the selected Logical Unit (drive), as a number of OS-sized blocks. * * \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with * * \return Boolean \c true if the command completed successfully, \c false otherwise. */ static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) { uint32_t LastBlockAddressInLUN = (MMC_MediaBlocks() - 1); uint32_t MediaBlockSize = VIRTUAL_MEMORY_BLOCK_SIZE; Endpoint_Write_Stream_BE(&LastBlockAddressInLUN, sizeof(LastBlockAddressInLUN), NULL); Endpoint_Write_Stream_BE(&MediaBlockSize, sizeof(MediaBlockSize), NULL); Endpoint_ClearIN(); /* Succeed the command and update the bytes transferred counter */ MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8; return true; }
/* FAT_BOOT_RECORD fatBootData = { .bootstrap = {0xeb, 0x3c, 0x90}, .OEM = "OpenPCR ", .iBytesPerSector = 512, .iSectorsPerCluster = 1, .iReservedSectors = 1, .iFATs = 2, .iRootEntries = 16, .iTotalSectors = 128, .iMediaDescr = 0xf0, .iSectorsPerFAT = 1, .iSectorsPerTrack = 0, .iHeads = 0, .iHiddenSectors = 0, .iTotalSectorsEx = 0, .iLogicDriveNumber = 0, .extSignature = 0x29, .serialNumber = USE_INTERNAL_SERIAL, .volumeLabel = "No Name ", .fatName = "FAT16 ", .exeCode = "", .exeEndMarker = {0x55, 0xaa} }; FAT_BOOT_RECORD fatBootData = { .bootstrap = {0xeb, 0x3c, 0x90}, .OEM = "OpenPCR", .iBytesPerSector = 512, .iSectorsPerCluster = 1, .iReservedSectors = 1, .iFATs = 2, .iRootEntries = 512, .iTotalSectors = 128, .iMediaDescr = 0xf0, .iSectorsPerFAT = 64, .iSectorsPerTrack = 0, .iHeads = 0, .iHiddenSectors = 0, .iTotalSectorsEx = 0, .iLogicDriveNumber = 0, .extSignature = 0x29, .serialNumber = USE_INTERNAL_SERIAL, .volumeLabel = {'N', 'o', ' ', 'N', 'a', 'm', 'e'}, .fatName = {'F', 'A', 'T', '1', '6'}, .exeCode = {}, .exeEndMarker = {0x55, 0xaa} }; */ static void SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo, const bool IsDataRead) { uint32_t BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]); uint16_t TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]); /* Check if the block address is outside the maximum allowable value for the LUN */ if (BlockAddress >= LUN_MEDIA_BLOCKS) { // Block address is invalid, update SENSE key and return command fail SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST, SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, SCSI_ASENSEQ_NO_QUALIFIER); return; } #if (TOTAL_LUNS > 1) /* Adjust the given block address to the real media address based on the selected LUN */ BlockAddress += ((uint32_t)MSInterfaceInfo->State.CommandBlock.LUN * LUN_MEDIA_BLOCKS); #endif #if 0 /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */ if (IsDataRead == DATA_READ){ int block_index = 0; while (TotalBlocks){ if (BlockAddress == 0){ //BOOT Record Endpoint_Write_Stream_LE(&fatBootData, sizeof(FAT_BOOT_RECORD), NO_STREAM_CALLBACK); } else if (BlockAddress == 1 || BlockAddress == 2){ //FAT TABLE 1 and 2 uint16_t firstBlock = 0xfff0; uint16_t secondBlock = 0xffff; Endpoint_Write_Stream_BE(&firstBlock, sizeof(firstBlock), NO_STREAM_CALLBACK); Endpoint_Write_Stream_BE(&secondBlock, sizeof(secondBlock), NO_STREAM_CALLBACK); for (block_index=4; block_index<VIRTUAL_MEMORY_BLOCK_SIZE; block_index++){ Endpoint_Write_Byte(0x00); } } else{ for (block_index=0; block_index<VIRTUAL_MEMORY_BLOCK_SIZE; block_index++){ Endpoint_Write_Byte(0x00); } } BlockAddress++; TotalBlocks--; } } Endpoint_ClearIN(); #endif /* if (IsDataRead == DATA_READ) DataflashManager_ReadBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); else DataflashManager_WriteBlocks(MSInterfaceInfo, BlockAddress, TotalBlocks); */ /* Update the bytes transferred counter and succeed the command */ MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE); }