X-Git-Url: http://git.linex4red.de/pub/lufa.git/blobdiff_plain/f547eb36080dacf275cd94fc3ddfb4c618c587fa..ee744abb7efd5fef49782991d58895e10696809a:/LUFA/Drivers/USB/Class/Host/MassStorage.h diff --git a/LUFA/Drivers/USB/Class/Host/MassStorage.h b/LUFA/Drivers/USB/Class/Host/MassStorage.h index 18b2cf4ae..a8a957bab 100644 --- a/LUFA/Drivers/USB/Class/Host/MassStorage.h +++ b/LUFA/Drivers/USB/Class/Host/MassStorage.h @@ -78,25 +78,137 @@ uint16_t DataINPipeSize; /**< Size in bytes of the MS interface's IN data pipe */ uint16_t DataOUTPipeSize; /**< Size in bytes of the MS interface's OUT data pipe */ + + uint32_t TransactionTag; /**< Current transaction tag for data synchronising of packets */ } State; /**< State data for the USB class interface within the device. All elements in this section * may be set to initial values, but may also be ignored to default to sane values when * the interface is enumerated. */ } USB_ClassInfo_MS_Host_t; + /** Type define for a SCSI Sense structure. Structures of this type are filled out by the + * device via the MassStore_RequestSense() function, indicating the current sense data of the + * device (giving explicit error codes for the last issued command). For details of the + * structure contents, refer to the SCSI specifications. + */ + typedef struct + { + uint8_t ReponseCode; + + uint8_t SegmentNumber; + + unsigned char SenseKey : 4; + unsigned char _RESERVED1 : 1; + unsigned char ILI : 1; + unsigned char EOM : 1; + unsigned char FileMark : 1; + + uint8_t Information[4]; + uint8_t AdditionalLength; + uint8_t CmdSpecificInformation[4]; + uint8_t AdditionalSenseCode; + uint8_t AdditionalSenseQualifier; + uint8_t FieldReplaceableUnitCode; + 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. + */ + typedef struct + { + uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */ + uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */ + } SCSI_Capacity_t; + /* Enums: */ enum { MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully */ MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor */ - MS_ENUMERROR_NoMSInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor */ + MS_ENUMERROR_NoMSInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor */ MS_ENUMERROR_EndpointsNotFound = 3, /**< Compatible Mass Storage endpoints were not found in the device's interfaces */ } MSHost_EnumerationFailure_ErrorCodes_t; /* Function Prototypes: */ - void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* MSInterfaceInfo); + /** General management task for a given Mass Storage host class interface, required for the correct operation of + * the interface. This should be called frequently in the main program loop, before the master USB management task + * \ref USB_USBTask(). + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state + */ + void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Host interface configuration routine, to configure a given Mass Storage host interface instance using the + * Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass + * Storage Host instance's state values and configures the pipes required to communicate with the interface if it + * is found within the device. This should be called once after the stack has enumerated the attached device, while + * the host state machine is in the Addressed state. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state + * \param[in] ConfigDescriptorLength Length of the attached device's Configuration Descriptor + * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor + */ uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint16_t ConfigDescriptorLength, - uint8_t* DeviceConfigDescriptor); + uint8_t* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1, 3); + + /** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface + * and readying it for the next Mass Storage command. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum + */ + uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t* MaxLUNIndex) ATTR_NON_NULL_PTR_ARG(1, 2); + + uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, + SCSI_Inquiry_Response_t* InquiryData) ATTR_NON_NULL_PTR_ARG(1, 2); + + uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex, + bool* DeviceReady) ATTR_NON_NULL_PTR_ARG(1, 3); + + uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uint8_t LUNIndex, + SCSI_Capacity_t* DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1, 3); /* Private Interface - For use in library only: */ #if !defined(__DOXYGEN__) @@ -105,6 +217,17 @@ #define MASS_STORE_SUBCLASS 0x06 #define MASS_STORE_PROTOCOL 0x50 + #define REQ_MassStorageReset 0xFF + #define REQ_GetMaxLUN 0xFE + + #define CBW_SIGNATURE 0x43425355UL + #define CSW_SIGNATURE 0x53425355UL + + #define COMMAND_DIRECTION_DATA_OUT (0 << 7) + #define COMMAND_DIRECTION_DATA_IN (1 << 7) + + #define COMMAND_DATA_TIMEOUT_MS 2000 + #define MS_FOUND_DATAPIPE_IN (1 << 0) #define MS_FOUND_DATAPIPE_OUT (1 << 1) @@ -112,6 +235,14 @@ #if defined(INCLUDE_FROM_MS_CLASS_HOST_C) static uint8_t DComp_NextMassStorageInterface(void* CurrentDescriptor); static uint8_t DComp_NextInterfaceBulkDataEndpoint(void* CurrentDescriptor); + + static uint8_t MassStore_SendCommand(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, + MS_CommandBlockWrapper_t* SCSICommandBlock); + static uint8_t MassStore_WaitForDataReceived(USB_ClassInfo_MS_Host_t* MSInterfaceInfo); + static uint8_t MassStore_SendReceiveData(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, + MS_CommandBlockWrapper_t* SCSICommandBlock, void* BufferPtr); + static uint8_t MassStore_GetReturnedStatus(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, + MS_CommandStatusWrapper_t* SCSICommandStatus); #endif #endif