Пример #1
0
/** Routine to receive the current CSW from the device.
 *
 *  \param[out] SCSICommandStatus  Pointer to a destination where the returned status data should be stored
 *
 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum, or MASS_STORE_SCSI_COMMAND_FAILED if the SCSI command fails
 */
static uint8_t MassStore_GetReturnedStatus(CommandStatusWrapper_t* const SCSICommandStatus)
{
	uint8_t ErrorCode = PIPE_RWSTREAM_NoError;

	/* If an error in the command occurred, abort */
	if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;

	/* Select the IN data pipe for data reception */
	Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);
	Pipe_Unfreeze();

	/* Load in the CSW from the attached device */
	if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(CommandStatusWrapper_t))) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;

	/* Clear the data ready for next reception */
	Pipe_ClearIN();

	/* Freeze the IN pipe after use */
	Pipe_Freeze();

	/* Check to see if command failed */
	if (SCSICommandStatus->Status != Command_Pass)
	  ErrorCode = MASS_STORE_SCSI_COMMAND_FAILED;

	return ErrorCode;
}
Пример #2
0
/** Sends or receives the transaction's data stage to or from the attached device, reading or
 *  writing to the nominated buffer.
 *
 *  \param[in] SCSICommandBlock  Pointer to a SCSI command block structure being sent to the attached device
 *  \param[in,out]  BufferPtr    Pointer to the data buffer to read from or write to
 *
 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
 */
static uint8_t MassStore_SendReceiveData(CommandBlockWrapper_t* const SCSICommandBlock,
                                         void* BufferPtr)
{
	uint8_t  ErrorCode = PIPE_RWSTREAM_NoError;
	uint16_t BytesRem  = SCSICommandBlock->DataTransferLength;

	/* Check the direction of the SCSI command data stage */
	if (SCSICommandBlock->Flags & COMMAND_DIRECTION_DATA_IN)
	{
		/* Wait until the device has replied with some data */
		if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)
		  return ErrorCode;

		/* Select the IN data pipe for data reception */
		Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);
		Pipe_Unfreeze();

		/* Read in the block data from the pipe */
		if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)
		  return ErrorCode;

		/* Acknowledge the packet */
		Pipe_ClearIN();
	}
	else
	{
		/* Select the OUT data pipe for data transmission */
		Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);
		Pipe_Unfreeze();

		/* Write the block data to the pipe */
		if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)
		  return ErrorCode;

		/* Acknowledge the packet */
		Pipe_ClearOUT();

		while (!(Pipe_IsOUTReady()))
		{
			if (USB_HostState == HOST_STATE_Unattached)
			  return PIPE_RWSTREAM_DeviceDisconnected;
		}
	}

	/* Freeze used pipe after use */
	Pipe_Freeze();

	return PIPE_RWSTREAM_NoError;
}
Пример #3
0
/** Routine to receive the current CSW from the device.
 *
 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
 */
static uint8_t MassStore_GetReturnedStatus(void)
{
	uint8_t ErrorCode = PIPE_RWSTREAM_NoError;

	/* If an error in the command ocurred, abort */
	if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;

	/* Select the IN data pipe for data reception */
	Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);
	Pipe_Unfreeze();
	
	/* Load in the CSW from the attached device */
	if ((ErrorCode = Pipe_Read_Stream_LE(&SCSICommandStatus, sizeof(CommandStatusWrapper_t))) != PIPE_RWSTREAM_NoError)
	  return ErrorCode;
	  
	/* Clear the data ready for next reception */
	Pipe_ClearIN();
	
	/* Freeze the IN pipe after use */
	Pipe_Freeze();
	
	return PIPE_RWSTREAM_NoError;
}