From 64937a62062368504cc9982d15a7d332566d8fac Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 23 Jun 2009 09:01:23 +0000 Subject: MassStorageHost demo now retrieves Inquiry data from the device during enumeration, and prints the device's Vendor and Product IDs. --- .../MassStorageHost/Lib/MassStoreCommands.c | 63 ++++++++++++++++++++++ .../MassStorageHost/Lib/MassStoreCommands.h | 39 ++++++++++++++ .../LowLevel/MassStorageHost/MassStorageHost.c | 15 +++++- 3 files changed, 115 insertions(+), 2 deletions(-) (limited to 'Demos/Host/LowLevel/MassStorageHost') diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c index b89ad1969..e2a64da90 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c @@ -301,6 +301,69 @@ 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 LUNIndex Index of the LUN inside the device the command is being addressed to + * \param 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. * diff --git a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h index 78700de84..8f3e8a12e 100644 --- a/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h +++ b/Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h @@ -128,6 +128,43 @@ uint8_t SenseKeySpecific[3]; } SCSI_Request_Sense_Response_t; + /** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the + * device via the MassStore_Inquiry() function, retrieving the attached device's information. + * For details of the structure contents, refer to the SCSI specifications. + */ + typedef struct + { + unsigned char DeviceType : 5; + unsigned char PeripheralQualifier : 3; + + unsigned char _RESERVED1 : 7; + unsigned char Removable : 1; + + uint8_t Version; + + unsigned char ResponseDataFormat : 4; + unsigned char _RESERVED2 : 1; + unsigned char NormACA : 1; + unsigned char TrmTsk : 1; + unsigned char AERC : 1; + + uint8_t AdditionalLength; + uint8_t _RESERVED3[2]; + + unsigned char SoftReset : 1; + unsigned char CmdQue : 1; + unsigned char _RESERVED4 : 1; + unsigned char Linked : 1; + unsigned char Sync : 1; + unsigned char WideBus16Bit : 1; + unsigned char WideBus32Bit : 1; + unsigned char RelAddr : 1; + + uint8_t VendorID[8]; + uint8_t ProductID[16]; + uint8_t RevisionID[4]; + } SCSI_Inquiry_Response_t; + /** SCSI capacity structure, to hold the total capacity of the device in both the number * of blocks in the current LUN, and the size of each block. This structure is filled by * the device when the MassStore_ReadCapacity() function is called. @@ -162,6 +199,8 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex); uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr) ATTR_NON_NULL_PTR_ARG(2); + uint8_t MassStore_Inquiry(const uint8_t LUNIndex, const SCSI_Inquiry_Response_t* const InquiryPtr) + ATTR_NON_NULL_PTR_ARG(2); uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress, const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5); uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress, diff --git a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c index 905077e81..79a559234 100644 --- a/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c +++ b/Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c @@ -191,7 +191,7 @@ void MassStorage_Task(void) } /* Print number of LUNs detected in the attached device */ - printf_P(PSTR("Total LUNs: %d.\r\n"), (MassStore_MaxLUNIndex + 1)); + printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1)); /* Reset the Mass Storage device interface, ready for use */ if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful) @@ -216,9 +216,20 @@ void MassStorage_Task(void) break; } - puts_P(PSTR("Waiting until ready..")); + /* Get inquiry data from the device */ + SCSI_Inquiry_Response_t InquiryData; + if (((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0) || (SCSICommandStatus.Status != Command_Pass)) + { + ShowDiskReadError(PSTR("Inquiry"), (SCSICommandStatus.Status != Command_Pass), ErrorCode); + break; + } + /* Print vendor and product names of attached device */ + printf_P(PSTR("Vendor: %s, Product: %s\r\n"), InquiryData.VendorID, InquiryData.ProductID); + /* Wait until disk ready */ + puts_P(PSTR("Waiting until ready..")); + do { Serial_TxByte('.'); -- cgit v1.2.3