return ErrorCode;\r
}\r
\r
+/** Issues a SCSI Inquiry command to the attached device, to determine the device's information. This\r
+ * gives information on the device's capabilities.\r
+ *\r
+ * \param LUNIndex Index of the LUN inside the device the command is being addressed to\r
+ * \param InquiryPtr Pointer to the inquiry data structure where the inquiry data from the device is to be stored\r
+ *\r
+ * \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_Inquiry(const uint8_t LUNIndex, const SCSI_Inquiry_Response_t* const InquiryPtr)\r
+{\r
+ uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
+\r
+ /* Create a CBW with a SCSI command to issue INQUIRY command */\r
+ SCSICommandBlock = (CommandBlockWrapper_t)\r
+ {\r
+ .Header =\r
+ {\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = sizeof(SCSI_Inquiry_Response_t),\r
+ .Flags = COMMAND_DIRECTION_DATA_IN,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 6\r
+ },\r
+ \r
+ .SCSICommandData =\r
+ {\r
+ SCSI_CMD_INQUIRY,\r
+ 0x00, // Reserved\r
+ 0x00, // Reserved\r
+ 0x00, // Reserved\r
+ sizeof(SCSI_Inquiry_Response_t), // Allocation Length\r
+ 0x00 // Unused (control)\r
+ }\r
+ };\r
+ \r
+ /* Send SCSI command to the attached device */\r
+ MassStore_SendCommand();\r
+\r
+ /* Wait until data received from the device */\r
+ if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
+ {\r
+ Pipe_Freeze();\r
+ return ReturnCode;\r
+ }\r
+\r
+ /* Read the returned sense data into the buffer */\r
+ if ((ReturnCode = MassStore_SendReceiveData((uint8_t*)InquiryPtr)) != PIPE_RWSTREAM_NoError)\r
+ {\r
+ Pipe_Freeze();\r
+ return ReturnCode;\r
+ } \r
+ \r
+ /* Read in the returned CSW from the device */\r
+ if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
+ {\r
+ Pipe_Freeze();\r
+ return ReturnCode;\r
+ }\r
+ \r
+ return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
/** Issues a SCSI Request Sense command to the attached device, to determine the current SCSI sense information. This\r
* gives error codes for the last issued SCSI command to the device.\r
*\r
uint8_t SenseKeySpecific[3];\r
} SCSI_Request_Sense_Response_t;\r
\r
+ /** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the\r
+ * device via the MassStore_Inquiry() function, retrieving the attached device's information.\r
+ * For details of the structure contents, refer to the SCSI specifications.\r
+ */\r
+ typedef struct\r
+ {\r
+ unsigned char DeviceType : 5;\r
+ unsigned char PeripheralQualifier : 3;\r
+ \r
+ unsigned char _RESERVED1 : 7;\r
+ unsigned char Removable : 1;\r
+ \r
+ uint8_t Version;\r
+ \r
+ unsigned char ResponseDataFormat : 4;\r
+ unsigned char _RESERVED2 : 1;\r
+ unsigned char NormACA : 1;\r
+ unsigned char TrmTsk : 1;\r
+ unsigned char AERC : 1;\r
+\r
+ uint8_t AdditionalLength;\r
+ uint8_t _RESERVED3[2];\r
+\r
+ unsigned char SoftReset : 1;\r
+ unsigned char CmdQue : 1;\r
+ unsigned char _RESERVED4 : 1;\r
+ unsigned char Linked : 1;\r
+ unsigned char Sync : 1;\r
+ unsigned char WideBus16Bit : 1;\r
+ unsigned char WideBus32Bit : 1;\r
+ unsigned char RelAddr : 1;\r
+ \r
+ uint8_t VendorID[8];\r
+ uint8_t ProductID[16];\r
+ uint8_t RevisionID[4];\r
+ } SCSI_Inquiry_Response_t;\r
+ \r
/** SCSI capacity structure, to hold the total capacity of the device in both the number\r
* of blocks in the current LUN, and the size of each block. This structure is filled by\r
* the device when the MassStore_ReadCapacity() function is called.\r
uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);\r
uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)\r
ATTR_NON_NULL_PTR_ARG(2);\r
+ uint8_t MassStore_Inquiry(const uint8_t LUNIndex, const SCSI_Inquiry_Response_t* const InquiryPtr)\r
+ ATTR_NON_NULL_PTR_ARG(2);\r
uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);\r
uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
}\r
\r
/* Print number of LUNs detected in the attached device */\r
- printf_P(PSTR("Total LUNs: %d.\r\n"), (MassStore_MaxLUNIndex + 1));\r
+ printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));\r
\r
/* Reset the Mass Storage device interface, ready for use */\r
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)\r
break;\r
}\r
\r
- puts_P(PSTR("Waiting until ready.."));\r
+ /* Get inquiry data from the device */\r
+ SCSI_Inquiry_Response_t InquiryData;\r
+ if (((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0) || (SCSICommandStatus.Status != Command_Pass))\r
+ {\r
+ ShowDiskReadError(PSTR("Inquiry"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);\r
+ break;\r
+ }\r
\r
+ /* Print vendor and product names of attached device */\r
+ printf_P(PSTR("Vendor: %s, Product: %s\r\n"), InquiryData.VendorID, InquiryData.ProductID);\r
+ \r
/* Wait until disk ready */\r
+ puts_P(PSTR("Waiting until ready.."));\r
+\r
do\r
{\r
Serial_TxByte('.');\r