Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Erik Strand
lufa
Commits
f8905928
Commit
f8905928
authored
Aug 27, 2009
by
Dean Camera
Browse files
Completed initial Host mode Mass Storage class driver.
parent
559ca2ba
Changes
2
Show whitespace changes
Inline
Side-by-side
LUFA/Drivers/USB/Class/Host/MassStorage.c
View file @
f8905928
...
...
@@ -34,8 +34,6 @@
#define INCLUDE_FROM_MS_CLASS_HOST_C
#include
"MassStorage.h"
#warning The Mass Storage Host mode Class driver is currently incomplete and is for preview purposes only.
uint8_t
MS_Host_ConfigurePipes
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint16_t
ConfigDescriptorLength
,
uint8_t
*
DeviceConfigDescriptor
)
{
...
...
@@ -478,14 +476,224 @@ uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* MSInterfaceInfo, uin
}
uint8_t
MS_Host_RequestSense
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
SCSI_Request_Sense_Response_t
*
SenseData
);
SCSI_Request_Sense_Response_t
*
SenseData
)
{
if
((
USB_HostState
!=
HOST_STATE_Configured
)
||
!
(
MSInterfaceInfo
->
State
.
Active
))
return
HOST_SENDCONTROL_DeviceDisconnect
;
uint8_t
ErrorCode
=
PIPE_RWSTREAM_NoError
;
MS_CommandBlockWrapper_t
SCSICommandBlock
=
(
MS_CommandBlockWrapper_t
)
{
.
Signature
=
CBW_SIGNATURE
,
.
Tag
=
MSInterfaceInfo
->
State
.
TransactionTag
,
.
DataTransferLength
=
sizeof
(
SCSI_Request_Sense_Response_t
),
.
Flags
=
COMMAND_DIRECTION_DATA_IN
,
.
LUN
=
LUNIndex
,
.
SCSICommandLength
=
6
,
.
SCSICommandData
=
{
SCSI_CMD_REQUEST_SENSE
,
0x00
,
// Reserved
0x00
,
// Reserved
0x00
,
// Reserved
sizeof
(
SCSI_Request_Sense_Response_t
),
// Allocation Length
0x00
// Unused (control)
}
};
if
((
ErrorCode
=
MS_Host_SendCommand
(
MSInterfaceInfo
,
&
SCSICommandBlock
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
uint8_t
MS_Host_PreventAllowMediumRemoval
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
bool
PreventRemoval
);
if
((
ErrorCode
=
MS_Host_WaitForDataReceived
(
MSInterfaceInfo
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
uint8_t
MS_Host_ReadDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddr
,
uint8_t
Blocks
,
uint16_t
BlockSize
,
void
*
BlockBuffer
);
if
((
ErrorCode
=
MS_Host_SendReceiveData
(
MSInterfaceInfo
,
&
SCSICommandBlock
,
SenseData
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
MS_CommandStatusWrapper_t
SCSICommandStatus
;
if
((
ErrorCode
=
MS_Host_GetReturnedStatus
(
MSInterfaceInfo
,
&
SCSICommandStatus
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
(
SCSICommandStatus
.
Status
!=
SCSI_Command_Pass
)
ErrorCode
=
MS_ERROR_LOGICAL_CMD_FAILED
;
return
ErrorCode
;
}
uint8_t
MS_Host_PreventAllowMediumRemoval
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
bool
PreventRemoval
)
{
if
((
USB_HostState
!=
HOST_STATE_Configured
)
||
!
(
MSInterfaceInfo
->
State
.
Active
))
return
HOST_SENDCONTROL_DeviceDisconnect
;
uint8_t
ErrorCode
=
PIPE_RWSTREAM_NoError
;
MS_CommandBlockWrapper_t
SCSICommandBlock
=
(
MS_CommandBlockWrapper_t
)
{
.
Signature
=
CBW_SIGNATURE
,
.
Tag
=
MSInterfaceInfo
->
State
.
TransactionTag
,
.
DataTransferLength
=
0
,
.
Flags
=
COMMAND_DIRECTION_DATA_OUT
,
.
LUN
=
LUNIndex
,
.
SCSICommandLength
=
6
,
.
SCSICommandData
=
{
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
,
0x00
,
// Reserved
0x00
,
// Reserved
PreventRemoval
,
// Prevent flag
0x00
,
// Reserved
0x00
// Unused (control)
}
};
if
((
ErrorCode
=
MS_Host_SendCommand
(
MSInterfaceInfo
,
&
SCSICommandBlock
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
MS_CommandStatusWrapper_t
SCSICommandStatus
;
if
((
ErrorCode
=
MS_Host_GetReturnedStatus
(
MSInterfaceInfo
,
&
SCSICommandStatus
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
(
SCSICommandStatus
.
Status
!=
SCSI_Command_Pass
)
ErrorCode
=
MS_ERROR_LOGICAL_CMD_FAILED
;
return
ErrorCode
;
}
uint8_t
MS_Host_WriteDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddr
,
uint8_t
Blocks
,
uint16_t
BlockSize
,
void
*
BlockBuffer
);
uint8_t
MS_Host_ReadDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddress
,
uint8_t
Blocks
,
uint16_t
BlockSize
,
void
*
BlockBuffer
)
{
if
((
USB_HostState
!=
HOST_STATE_Configured
)
||
!
(
MSInterfaceInfo
->
State
.
Active
))
return
HOST_SENDCONTROL_DeviceDisconnect
;
uint8_t
ErrorCode
=
PIPE_RWSTREAM_NoError
;
MS_CommandBlockWrapper_t
SCSICommandBlock
=
(
MS_CommandBlockWrapper_t
)
{
.
Signature
=
CBW_SIGNATURE
,
.
Tag
=
MSInterfaceInfo
->
State
.
TransactionTag
,
.
DataTransferLength
=
((
uint32_t
)
Blocks
*
BlockSize
),
.
Flags
=
COMMAND_DIRECTION_DATA_IN
,
.
LUN
=
LUNIndex
,
.
SCSICommandLength
=
10
,
.
SCSICommandData
=
{
SCSI_CMD_READ_10
,
0x00
,
// Unused (control bits, all off)
(
BlockAddress
>>
24
),
// MSB of Block Address
(
BlockAddress
>>
16
),
(
BlockAddress
>>
8
),
(
BlockAddress
&
0xFF
),
// LSB of Block Address
0x00
,
// Unused (reserved)
0x00
,
// MSB of Total Blocks to Read
Blocks
,
// LSB of Total Blocks to Read
0x00
// Unused (control)
}
};
if
((
ErrorCode
=
MS_Host_SendCommand
(
MSInterfaceInfo
,
&
SCSICommandBlock
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
((
ErrorCode
=
MS_Host_WaitForDataReceived
(
MSInterfaceInfo
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
((
ErrorCode
=
MS_Host_SendReceiveData
(
MSInterfaceInfo
,
&
SCSICommandBlock
,
BlockBuffer
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
MS_CommandStatusWrapper_t
SCSICommandStatus
;
if
((
ErrorCode
=
MS_Host_GetReturnedStatus
(
MSInterfaceInfo
,
&
SCSICommandStatus
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
(
SCSICommandStatus
.
Status
!=
SCSI_Command_Pass
)
ErrorCode
=
MS_ERROR_LOGICAL_CMD_FAILED
;
return
ErrorCode
;
}
uint8_t
MS_Host_WriteDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddress
,
uint8_t
Blocks
,
uint16_t
BlockSize
,
void
*
BlockBuffer
)
{
if
((
USB_HostState
!=
HOST_STATE_Configured
)
||
!
(
MSInterfaceInfo
->
State
.
Active
))
return
HOST_SENDCONTROL_DeviceDisconnect
;
uint8_t
ErrorCode
=
PIPE_RWSTREAM_NoError
;
MS_CommandBlockWrapper_t
SCSICommandBlock
=
(
MS_CommandBlockWrapper_t
)
{
.
Signature
=
CBW_SIGNATURE
,
.
Tag
=
MSInterfaceInfo
->
State
.
TransactionTag
,
.
DataTransferLength
=
((
uint32_t
)
Blocks
*
BlockSize
),
.
Flags
=
COMMAND_DIRECTION_DATA_OUT
,
.
LUN
=
LUNIndex
,
.
SCSICommandLength
=
10
,
.
SCSICommandData
=
{
SCSI_CMD_WRITE_10
,
0x00
,
// Unused (control bits, all off)
(
BlockAddress
>>
24
),
// MSB of Block Address
(
BlockAddress
>>
16
),
(
BlockAddress
>>
8
),
(
BlockAddress
&
0xFF
),
// LSB of Block Address
0x00
,
// Unused (reserved)
0x00
,
// MSB of Total Blocks to Write
Blocks
,
// LSB of Total Blocks to Write
0x00
// Unused (control)
}
};
if
((
ErrorCode
=
MS_Host_SendCommand
(
MSInterfaceInfo
,
&
SCSICommandBlock
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
((
ErrorCode
=
MS_Host_SendReceiveData
(
MSInterfaceInfo
,
&
SCSICommandBlock
,
BlockBuffer
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
MS_CommandStatusWrapper_t
SCSICommandStatus
;
if
((
ErrorCode
=
MS_Host_GetReturnedStatus
(
MSInterfaceInfo
,
&
SCSICommandStatus
))
!=
PIPE_RWSTREAM_NoError
)
{
Pipe_Freeze
();
return
ErrorCode
;
}
if
(
SCSICommandStatus
.
Status
!=
SCSI_Command_Pass
)
ErrorCode
=
MS_ERROR_LOGICAL_CMD_FAILED
;
return
ErrorCode
;
}
#endif
LUFA/Drivers/USB/Class/Host/MassStorage.h
View file @
f8905928
...
...
@@ -226,21 +226,74 @@
uint8_t
MS_Host_GetInquiryData
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
SCSI_Inquiry_Response_t
*
InquiryData
)
ATTR_NON_NULL_PTR_ARG
(
1
,
3
);
/** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t
MS_Host_TestUnitReady
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
)
ATTR_NON_NULL_PTR_ARG
(
1
);
/** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
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
);
/** Retrieves the device sense data, indicating the current device state and error codes for the previously
* issued command.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[out] SenseData Pointer to the location where the sense information should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t
MS_Host_RequestSense
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
SCSI_Request_Sense_Response_t
*
SenseData
)
ATTR_NON_NULL_PTR_ARG
(
1
,
3
);
/** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock
* the device from removal so that blocks of data on the medium can be read or altered.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] PreventRemoval Boolean true if the device should be locked from removal, false otherwise
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t
MS_Host_PreventAllowMediumRemoval
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
bool
PreventRemoval
)
ATTR_NON_NULL_PTR_ARG
(
1
);
uint8_t
MS_Host_ReadDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddr
,
/** Reads blocks of data from the attached Mass Storage device's medium.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] BlockAddress Starting block address within the device to read from
* \param[in] Blocks Total number of blocks to read
* \param[out] BlockBuffer Pointer to where the read data from the device should be stored
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t
MS_Host_ReadDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddress
,
uint8_t
Blocks
,
uint16_t
BlockSize
,
void
*
BlockBuffer
)
ATTR_NON_NULL_PTR_ARG
(
1
,
6
);
uint8_t
MS_Host_WriteDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddr
,
/** Writes blocks of data to the attached Mass Storage device's medium.
*
* \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state
* \param[in] LUNIndex LUN index within the device the command is being issued to
* \param[in] BlockAddress Starting block address within the device to write to
* \param[in] Blocks Total number of blocks to read
* \param[in] BlockBuffer Pointer to where the data to write should be sourced from
*
* \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or MS_ERROR_LOGICAL_CMD_FAILED if not ready
*/
uint8_t
MS_Host_WriteDeviceBlocks
(
USB_ClassInfo_MS_Host_t
*
MSInterfaceInfo
,
uint8_t
LUNIndex
,
uint32_t
BlockAddress
,
uint8_t
Blocks
,
uint16_t
BlockSize
,
void
*
BlockBuffer
)
ATTR_NON_NULL_PTR_ARG
(
1
,
6
);
/* Private Interface - For use in library only: */
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment