X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/ac70ddd0a1c412bb54def48e53caaebd0b5c9c61..2a0c28e6e47c8a173f32fc99cd8666a2633c5c12:/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c index 95aafca8c..d0518df1f 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c @@ -90,6 +90,7 @@ static uint8_t MassStore_SendCommand(void) /* Send the data in the OUT pipe to the attached device */ Pipe_ClearOUT(); + /* Wait until command has been sent */ while(!(Pipe_IsOUTReady())); /* Freeze pipe after use */ @@ -107,10 +108,6 @@ static uint8_t MassStore_WaitForDataReceived(void) { uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS; - /* Unfreeze the OUT pipe so that it can be checked */ - Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); - Pipe_Unfreeze(); - /* Select the IN data pipe for data reception */ Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); Pipe_Unfreeze(); @@ -130,32 +127,42 @@ static uint8_t MassStore_WaitForDataReceived(void) return PIPE_RWSTREAM_Timeout; } + Pipe_Freeze(); Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); + Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the OUT pipe */ - MassStore_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); + USB_Host_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE); return PIPE_RWSTREAM_PipeStalled; } - + + Pipe_Freeze(); Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); + Pipe_Unfreeze(); /* Check if pipe stalled (command failed by device) */ if (Pipe_IsStalled()) { /* Clear the stall condition on the IN pipe */ - MassStore_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); + USB_Host_ClearPipeStall(MASS_STORE_DATA_IN_PIPE); return PIPE_RWSTREAM_PipeStalled; } /* Check to see if the device was disconnected, if so exit function */ - if (!(USB_IsConnected)) + if (USB_HostState == HOST_STATE_Unattached) return PIPE_RWSTREAM_DeviceDisconnected; }; + + Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE); + Pipe_Freeze(); + + Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE); + Pipe_Freeze(); return PIPE_RWSTREAM_NoError; } @@ -163,7 +170,7 @@ static uint8_t MassStore_WaitForDataReceived(void) /** Sends or receives the transaction's data stage to or from the attached device, reading or * writing to the nominated buffer. * - * \param BufferPtr Pointer to the data buffer to read from or write to + * \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 */ @@ -199,7 +206,11 @@ static uint8_t MassStore_SendReceiveData(void* BufferPtr) /* Acknowledge the packet */ Pipe_ClearOUT(); - while (!(Pipe_IsOUTReady())); + while (!(Pipe_IsOUTReady())) + { + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + } } /* Freeze used pipe after use */ @@ -237,29 +248,6 @@ static uint8_t MassStore_GetReturnedStatus(void) return PIPE_RWSTREAM_NoError; } -/** Clears the stall condition in the attached device on the nominated endpoint number. - * - * \param EndpointNum Endpoint number in the attached device whose stall condition is to be cleared - * - * \return A value from the USB_Host_SendControlErrorCodes_t enum - */ -uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum) -{ - USB_ControlRequest = (USB_Request_Header_t) - { - .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), - .bRequest = REQ_ClearFeature, - .wValue = FEATURE_ENDPOINT_HALT, - .wIndex = EndpointNum, - .wLength = 0, - }; - - /* Select the control pipe for the request transfer */ - Pipe_SelectPipe(PIPE_CONTROLPIPE); - - return USB_Host_SendControlRequest(NULL); -} - /** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface, * readying the device for the next CBW. * @@ -285,7 +273,7 @@ uint8_t MassStore_MassStorageReset(void) /** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical * Unit in the attached device. * - * \param MaxLUNIndex Pointer to the location that the maximum LUN index value should be stored + * \param[out] MaxLUNIndex Pointer to the location that the maximum LUN index value should be stored * * \return A value from the USB_Host_SendControlErrorCodes_t enum */ @@ -317,11 +305,74 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex) return ErrorCode; } +/** Issues a SCSI Inquiry command to the attached device, to determine the device's information. This + * gives information on the device's capabilities. + * + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[out] InquiryPtr Pointer to the inquiry data structure where the inquiry data from the device is to be stored + * + * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum + */ +uint8_t MassStore_Inquiry(const uint8_t LUNIndex, const SCSI_Inquiry_Response_t* const InquiryPtr) +{ + uint8_t ReturnCode = PIPE_RWSTREAM_NoError; + + /* Create a CBW with a SCSI command to issue INQUIRY command */ + SCSICommandBlock = (CommandBlockWrapper_t) + { + .Header = + { + .Signature = CBW_SIGNATURE, + .Tag = MassStore_Tag, + .DataTransferLength = sizeof(SCSI_Inquiry_Response_t), + .Flags = COMMAND_DIRECTION_DATA_IN, + .LUN = LUNIndex, + .SCSICommandLength = 6 + }, + + .SCSICommandData = + { + SCSI_CMD_INQUIRY, + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Reserved + sizeof(SCSI_Inquiry_Response_t), // Allocation Length + 0x00 // Unused (control) + } + }; + + /* Send SCSI command to the attached device */ + MassStore_SendCommand(); + + /* Wait until data received from the device */ + if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError) + { + Pipe_Freeze(); + return ReturnCode; + } + + /* Read the returned sense data into the buffer */ + if ((ReturnCode = MassStore_SendReceiveData((uint8_t*)InquiryPtr)) != PIPE_RWSTREAM_NoError) + { + Pipe_Freeze(); + return ReturnCode; + } + + /* Read in the returned CSW from the device */ + if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError) + { + Pipe_Freeze(); + return ReturnCode; + } + + return PIPE_RWSTREAM_NoError; +} + /** Issues a SCSI Request Sense command to the attached device, to determine the current SCSI sense information. This * gives error codes for the last issued SCSI command to the device. * - * \param LUNIndex Index of the LUN inside the device the command is being addressed to - * \param SensePtr Pointer to the sense data structure where the sense data from the device is to be stored + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[out] SensePtr Pointer to the sense data structure where the sense data from the device is to be stored * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ @@ -383,11 +434,11 @@ uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_ /** Issues a SCSI Device Block Read command to the attached device, to read in one or more data blocks from the * storage medium into a buffer. * - * \param LUNIndex Index of the LUN inside the device the command is being addressed to - * \param BlockAddress Start block address to read from - * \param Blocks Number of blocks to read from the device - * \param BlockSize Size in bytes of each block to read - * \param BufferPtr Pointer to the buffer where the read data is to be written to + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[in] BlockAddress Start block address to read from + * \param[in] Blocks Number of blocks to read from the device + * \param[in] BlockSize Size in bytes of each block to read + * \param[out] BufferPtr Pointer to the buffer where the read data is to be written to * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ @@ -454,11 +505,11 @@ uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAd /** Issues a SCSI Device Block Write command to the attached device, to write one or more data blocks to the * storage medium from a buffer. * - * \param LUNIndex Index of the LUN inside the device the command is being addressed to - * \param BlockAddress Start block address to write to - * \param Blocks Number of blocks to write to in the device - * \param BlockSize Size in bytes of each block to write - * \param BufferPtr Pointer to the buffer where the write data is to be sourced from + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[in] BlockAddress Start block address to write to + * \param[in] Blocks Number of blocks to write to in the device + * \param[in] BlockSize Size in bytes of each block to write + * \param[in] BufferPtr Pointer to the buffer where the write data is to be sourced from * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ @@ -518,7 +569,7 @@ uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockA /** Issues a SCSI Device Test Unit Ready command to the attached device, to determine if the device is ready to accept * other commands. * - * \param LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ @@ -566,8 +617,8 @@ uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex) /** Issues a SCSI Device Read Capacity command to the attached device, to determine the capacity of the * given Logical Unit within the device. * - * \param LUNIndex Index of the LUN inside the device the command is being addressed to - * \param CapacityPtr Device capacity structure where the capacity data is to be stored + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[out] CapacityPtr Device capacity structure where the capacity data is to be stored * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */ @@ -638,8 +689,8 @@ uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const Ca * being removed. This is a legacy command for SCSI disks with removable storage (such as ZIP disks), but should still * be issued before the first read or write command is sent. * - * \param LUNIndex Index of the LUN inside the device the command is being addressed to - * \param PreventRemoval Whether or not the LUN media should be locked to prevent removal or not + * \param[in] LUNIndex Index of the LUN inside the device the command is being addressed to + * \param[in] PreventRemoval Whether or not the LUN media should be locked to prevent removal or not * * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum */