Commit 64937a62 authored by Dean Camera's avatar Dean Camera
Browse files

MassStorageHost demo now retrieves Inquiry data from the device during...

MassStorageHost demo now retrieves Inquiry data from the device during enumeration, and prints the device's Vendor and Product IDs.
parent bb23e55f
......@@ -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.
*
......
......@@ -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,
......
......@@ -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('.');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment