aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDean Camera <dean@fourwalledcubicle.com>2009-06-23 09:01:23 +0000
committerDean Camera <dean@fourwalledcubicle.com>2009-06-23 09:01:23 +0000
commit64937a62062368504cc9982d15a7d332566d8fac (patch)
tree98d98a143cfccdd6475d649de9cd0a54a8da9948
parentbb23e55f11a42f6214757483d010ebd24377caeb (diff)
downloadlufa-64937a62062368504cc9982d15a7d332566d8fac.tar.gz
lufa-64937a62062368504cc9982d15a7d332566d8fac.tar.bz2
lufa-64937a62062368504cc9982d15a7d332566d8fac.zip
MassStorageHost demo now retrieves Inquiry data from the device during enumeration, and prints the device's Vendor and Product IDs.
-rw-r--r--Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.c63
-rw-r--r--Demos/Host/LowLevel/MassStorageHost/Lib/MassStoreCommands.h39
-rw-r--r--Demos/Host/LowLevel/MassStorageHost/MassStorageHost.c15
3 files changed, 115 insertions, 2 deletions
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('.');