forked from mfulz_github/qmk_firmware
MassStorageHost demo now retrieves Inquiry data from the device during enumeration, and prints the device's Vendor and Product IDs.
This commit is contained in:
parent
bb23e55f11
commit
64937a6206
|
@ -301,6 +301,69 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex)
|
||||||
return ErrorCode;
|
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
|
/** 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.
|
* gives error codes for the last issued SCSI command to the device.
|
||||||
*
|
*
|
||||||
|
|
|
@ -128,6 +128,43 @@
|
||||||
uint8_t SenseKeySpecific[3];
|
uint8_t SenseKeySpecific[3];
|
||||||
} SCSI_Request_Sense_Response_t;
|
} 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
|
/** 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
|
* 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.
|
* the device when the MassStore_ReadCapacity() function is called.
|
||||||
|
@ -162,6 +199,8 @@
|
||||||
uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);
|
uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);
|
||||||
uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)
|
uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)
|
||||||
ATTR_NON_NULL_PTR_ARG(2);
|
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,
|
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);
|
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,
|
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 */
|
/* 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 */
|
/* Reset the Mass Storage device interface, ready for use */
|
||||||
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
|
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
|
||||||
|
@ -216,9 +216,20 @@ void MassStorage_Task(void)
|
||||||
break;
|
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 */
|
/* Wait until disk ready */
|
||||||
|
puts_P(PSTR("Waiting until ready.."));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Serial_TxByte('.');
|
Serial_TxByte('.');
|
||||||
|
|
Loading…
Reference in New Issue