MassStorageHost demo now retrieves Inquiry data from the device during enumeration...
authorDean Camera <dean@fourwalledcubicle.com>
Tue, 23 Jun 2009 09:01:23 +0000 (09:01 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Tue, 23 Jun 2009 09:01:23 +0000 (09:01 +0000)
Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c
Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h
Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c

index b89ad19..e2a64da 100644 (file)
@@ -301,6 +301,69 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex)
        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
index 78700de..8f3e8a1 100644 (file)
                        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
index 905077e..79a5592 100644 (file)
@@ -191,7 +191,7 @@ void MassStorage_Task(void)
                        }\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
@@ -216,9 +216,20 @@ void MassStorage_Task(void)
                                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