MassStorageHost demo now retrieves Inquiry data from the device during enumeration, and prints the device's Vendor and Product IDs.

pull/1469/head
Dean Camera 16 years ago
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…
Cancel
Save