Example #1
0
File: SCSI.c Project: TomMD/teensy
/** 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;
}
Example #2
0
/** 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;
}
Example #3
0
	/*
	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);
}