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
9f7883fa
Commit
9f7883fa
authored
Nov 26, 2010
by
Dean Camera
Browse files
Added ability to write protect Mass Storage disk write operations from the host OS.
parent
b634ec50
Changes
20
Hide whitespace changes
Inline
Side-by-side
Demos/Device/ClassDriver/MassStorage/Lib/SCSI.c
View file @
9f7883fa
...
...
@@ -113,6 +113,9 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
case
SCSI_CMD_READ_10
:
CommandSuccess
=
SCSI_Command_ReadWrite_10
(
MSInterfaceInfo
,
DATA_READ
);
break
;
case
SCSI_CMD_MODE_SENSE_6
:
CommandSuccess
=
SCSI_Command_ModeSense_6
(
MSInterfaceInfo
);
break
;
case
SCSI_CMD_TEST_UNIT_READY
:
case
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
:
case
SCSI_CMD_VERIFY_10
:
...
...
@@ -281,6 +284,17 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
uint32_t
BlockAddress
;
uint16_t
TotalBlocks
;
/* Check if the disk is write protected or not */
if
((
IsDataRead
==
DATA_WRITE
)
&&
DISK_READ_ONLY
)
{
/* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE
(
SCSI_SENSE_KEY_DATA_PROTECT
,
SCSI_ASENSE_WRITE_PROTECTED
,
SCSI_ASENSEQ_NO_QUALIFIER
);
return
false
;
}
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
MSInterfaceInfo
->
State
.
CommandBlock
.
SCSICommandData
[
2
]);
...
...
@@ -302,7 +316,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
/* Adjust the given block address to the real media address based on the selected LUN */
BlockAddress
+=
((
uint32_t
)
MSInterfaceInfo
->
State
.
CommandBlock
.
LUN
*
LUN_MEDIA_BLOCKS
);
#endif
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if
(
IsDataRead
==
DATA_READ
)
DataflashManager_ReadBlocks
(
MSInterfaceInfo
,
BlockAddress
,
TotalBlocks
);
...
...
@@ -315,3 +329,24 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
true
;
}
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
* the SCSI device, as well as the device's Write Protect status.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
)
{
/* Send an empty header response with the Write Protect flag status */
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
DISK_READ_ONLY
?
0x80
:
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_ClearIN
();
/* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo
->
State
.
CommandBlock
.
DataTransferLength
-=
4
;
return
true
;
}
Demos/Device/ClassDriver/MassStorage/Lib/SCSI.h
View file @
9f7883fa
...
...
@@ -81,6 +81,7 @@
static
bool
SCSI_Command_Send_Diagnostic
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
static
bool
SCSI_Command_ReadWrite_10
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
bool
IsDataRead
);
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
#endif
#endif
...
...
Demos/Device/ClassDriver/MassStorage/MassStorage.h
View file @
9f7883fa
...
...
@@ -73,6 +73,9 @@
/** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */
#define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
/** Indicates if the disk is write protected or not. */
#define DISK_READ_ONLY false
/* Function Prototypes: */
void
SetupHardware
(
void
);
...
...
Demos/Device/ClassDriver/MassStorageKeyboard/Lib/DataflashManager.h
View file @
9f7883fa
...
...
@@ -63,12 +63,6 @@
/** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. */
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/** Total number of logical drives within the device - must be non-zero. */
#define TOTAL_LUNS 1
/** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */
#define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
/* Function Prototypes: */
void
DataflashManager_WriteBlocks
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
uint32_t
BlockAddress
,
...
...
Demos/Device/ClassDriver/MassStorageKeyboard/Lib/SCSI.c
View file @
9f7883fa
...
...
@@ -113,6 +113,9 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
case
SCSI_CMD_READ_10
:
CommandSuccess
=
SCSI_Command_ReadWrite_10
(
MSInterfaceInfo
,
DATA_READ
);
break
;
case
SCSI_CMD_MODE_SENSE_6
:
CommandSuccess
=
SCSI_Command_ModeSense_6
(
MSInterfaceInfo
);
break
;
case
SCSI_CMD_TEST_UNIT_READY
:
case
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
:
case
SCSI_CMD_VERIFY_10
:
...
...
@@ -281,6 +284,17 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
uint32_t
BlockAddress
;
uint16_t
TotalBlocks
;
/* Check if the disk is write protected or not */
if
((
IsDataRead
==
DATA_WRITE
)
&&
DISK_READ_ONLY
)
{
/* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE
(
SCSI_SENSE_KEY_DATA_PROTECT
,
SCSI_ASENSE_WRITE_PROTECTED
,
SCSI_ASENSEQ_NO_QUALIFIER
);
return
false
;
}
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
MSInterfaceInfo
->
State
.
CommandBlock
.
SCSICommandData
[
2
]);
...
...
@@ -315,3 +329,24 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
true
;
}
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
* the SCSI device, as well as the device's Write Protect status.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
)
{
/* Send an empty header response with the Write Protect flag status */
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
DISK_READ_ONLY
?
0x80
:
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_ClearIN
();
/* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo
->
State
.
CommandBlock
.
DataTransferLength
-=
4
;
return
true
;
}
Demos/Device/ClassDriver/MassStorageKeyboard/Lib/SCSI.h
View file @
9f7883fa
...
...
@@ -81,6 +81,7 @@
static
bool
SCSI_Command_Send_Diagnostic
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
static
bool
SCSI_Command_ReadWrite_10
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
bool
IsDataRead
);
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
#endif
#endif
...
...
Demos/Device/ClassDriver/MassStorageKeyboard/MassStorageKeyboard.h
View file @
9f7883fa
...
...
@@ -73,6 +73,15 @@
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2
/** Total number of logical drives within the device - must be non-zero. */
#define TOTAL_LUNS 1
/** Blocks in each LUN, calculated from the total capacity divided by the total number of Logical Units in the device. */
#define LUN_MEDIA_BLOCKS (VIRTUAL_MEMORY_BLOCKS / TOTAL_LUNS)
/** Indicates if the disk is write protected or not. */
#define DISK_READ_ONLY false
/* Function Prototypes: */
void
SetupHardware
(
void
);
...
...
Demos/Device/LowLevel/MassStorage/Lib/SCSI.c
View file @
9f7883fa
...
...
@@ -111,6 +111,9 @@ bool SCSI_DecodeSCSICommand(void)
case
SCSI_CMD_READ_10
:
CommandSuccess
=
SCSI_Command_ReadWrite_10
(
DATA_READ
);
break
;
case
SCSI_CMD_MODE_SENSE_6
:
CommandSuccess
=
SCSI_Command_ModeSense_6
();
break
;
case
SCSI_CMD_TEST_UNIT_READY
:
case
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
:
case
SCSI_CMD_VERIFY_10
:
...
...
@@ -278,9 +281,23 @@ static bool SCSI_Command_Send_Diagnostic(void)
*/
static
bool
SCSI_Command_ReadWrite_10
(
const
bool
IsDataRead
)
{
uint32_t
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
CommandBlock
.
SCSICommandData
[
2
]);
uint16_t
TotalBlocks
=
SwapEndian_16
(
*
(
uint16_t
*
)
&
CommandBlock
.
SCSICommandData
[
7
]);
uint32_t
BlockAddress
;
uint16_t
TotalBlocks
;
/* Check if the disk is write protected or not */
if
((
IsDataRead
==
DATA_WRITE
)
&&
DISK_READ_ONLY
)
{
/* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE
(
SCSI_SENSE_KEY_DATA_PROTECT
,
SCSI_ASENSE_WRITE_PROTECTED
,
SCSI_ASENSEQ_NO_QUALIFIER
);
return
false
;
}
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
CommandBlock
.
SCSICommandData
[
2
]);
TotalBlocks
=
SwapEndian_16
(
*
(
uint16_t
*
)
&
CommandBlock
.
SCSICommandData
[
7
]);
/* Check if the block address is outside the maximum allowable value for the LUN */
if
(
BlockAddress
>=
LUN_MEDIA_BLOCKS
)
{
...
...
@@ -309,3 +326,22 @@ static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)
return
true
;
}
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
* the SCSI device, as well as the device's Write Protect status.
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
static
bool
SCSI_Command_ModeSense_6
(
void
)
{
/* Send an empty header response with the Write Protect flag status */
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
DISK_READ_ONLY
?
0x80
:
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_ClearIN
();
/* Update the bytes transferred counter and succeed the command */
CommandBlock
.
DataTransferLength
-=
4
;
return
true
;
}
Demos/Device/LowLevel/MassStorage/Lib/SCSI.h
View file @
9f7883fa
...
...
@@ -143,6 +143,7 @@
static
bool
SCSI_Command_Read_Capacity_10
(
void
);
static
bool
SCSI_Command_Send_Diagnostic
(
void
);
static
bool
SCSI_Command_ReadWrite_10
(
const
bool
IsDataRead
);
static
bool
SCSI_Command_ModeSense_6
(
void
);
#endif
#endif
...
...
Demos/Device/LowLevel/MassStorage/MassStorage.h
View file @
9f7883fa
...
...
@@ -68,6 +68,9 @@
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY LEDS_LED2
/** Indicates if the disk is write protected or not. */
#define DISK_READ_ONLY false
/* Global Variables: */
extern
MS_CommandBlockWrapper_t
CommandBlock
;
extern
MS_CommandStatusWrapper_t
CommandStatus
;
...
...
LUFA/ManPages/ChangeLog.txt
View file @
9f7883fa
...
...
@@ -12,6 +12,7 @@
* - None
* - Library Applications:
* - Added new incomplete MIDIToneGenerator project
* - Added ability to write protect Mass Storage disk write operations from the host OS
*
* <b>Changed:</b>
* - Core:
...
...
Projects/Incomplete/StandaloneProgrammer/Lib/DataflashManager.h
View file @
9f7883fa
...
...
@@ -52,18 +52,21 @@
/* Defines: */
/** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */
#define VIRTUAL_MEMORY_BYTES
((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)
#define VIRTUAL_MEMORY_BYTES ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)
/** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying
* storage media (Dataflash) using a different native block size. Do not change this value.
*/
#define VIRTUAL_MEMORY_BLOCK_SIZE
512
#define VIRTUAL_MEMORY_BLOCK_SIZE 512
/** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. Do not
* change this value; change VIRTUAL_MEMORY_BYTES instead to alter the media size.
*/
#define VIRTUAL_MEMORY_BLOCKS
(VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/** Indicates if the disk is write protected or not. */
#define DISK_READ_ONLY false
/* Function Prototypes: */
#if defined(USB_CAN_BE_DEVICE)
void
DataflashManager_WriteBlocks
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
...
...
Projects/Incomplete/StandaloneProgrammer/Lib/SCSI.c
View file @
9f7883fa
...
...
@@ -114,6 +114,9 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
case
SCSI_CMD_READ_10
:
CommandSuccess
=
SCSI_Command_ReadWrite_10
(
MSInterfaceInfo
,
DATA_READ
);
break
;
case
SCSI_CMD_MODE_SENSE_6
:
CommandSuccess
=
SCSI_Command_ModeSense_6
(
MSInterfaceInfo
);
break
;
case
SCSI_CMD_TEST_UNIT_READY
:
case
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
:
case
SCSI_CMD_VERIFY_10
:
...
...
@@ -282,6 +285,17 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
uint32_t
BlockAddress
;
uint16_t
TotalBlocks
;
/* Check if the disk is write protected or not */
if
((
IsDataRead
==
DATA_WRITE
)
&&
DISK_READ_ONLY
)
{
/* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE
(
SCSI_SENSE_KEY_DATA_PROTECT
,
SCSI_ASENSE_WRITE_PROTECTED
,
SCSI_ASENSEQ_NO_QUALIFIER
);
return
false
;
}
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
MSInterfaceInfo
->
State
.
CommandBlock
.
SCSICommandData
[
2
]);
...
...
@@ -298,7 +312,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
false
;
}
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if
(
IsDataRead
==
DATA_READ
)
DataflashManager_ReadBlocks
(
MSInterfaceInfo
,
BlockAddress
,
TotalBlocks
);
...
...
@@ -310,5 +324,26 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
true
;
}
#endif
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
* the SCSI device, as well as the device's Write Protect status.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
)
{
/* Send an empty header response with the Write Protect flag status */
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
DISK_READ_ONLY
?
0x80
:
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_ClearIN
();
/* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo
->
State
.
CommandBlock
.
DataTransferLength
-=
4
;
return
true
;
}
#endif
\ No newline at end of file
Projects/Incomplete/StandaloneProgrammer/Lib/SCSI.h
View file @
9f7883fa
...
...
@@ -82,6 +82,7 @@
static
bool
SCSI_Command_Send_Diagnostic
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
static
bool
SCSI_Command_ReadWrite_10
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
bool
IsDataRead
);
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
#endif
#endif
...
...
Projects/TempDataLogger/Lib/SCSI.c
View file @
9f7883fa
...
...
@@ -113,6 +113,9 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
case
SCSI_CMD_READ_10
:
CommandSuccess
=
SCSI_Command_ReadWrite_10
(
MSInterfaceInfo
,
DATA_READ
);
break
;
case
SCSI_CMD_MODE_SENSE_6
:
CommandSuccess
=
SCSI_Command_ModeSense_6
(
MSInterfaceInfo
);
break
;
case
SCSI_CMD_TEST_UNIT_READY
:
case
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
:
case
SCSI_CMD_VERIFY_10
:
...
...
@@ -281,6 +284,17 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
uint32_t
BlockAddress
;
uint16_t
TotalBlocks
;
/* Check if the disk is write protected or not */
if
((
IsDataRead
==
DATA_WRITE
)
&&
DISK_READ_ONLY
)
{
/* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE
(
SCSI_SENSE_KEY_DATA_PROTECT
,
SCSI_ASENSE_WRITE_PROTECTED
,
SCSI_ASENSEQ_NO_QUALIFIER
);
return
false
;
}
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
MSInterfaceInfo
->
State
.
CommandBlock
.
SCSICommandData
[
2
]);
...
...
@@ -297,7 +311,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
false
;
}
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if
(
IsDataRead
==
DATA_READ
)
DataflashManager_ReadBlocks
(
MSInterfaceInfo
,
BlockAddress
,
TotalBlocks
);
...
...
@@ -310,3 +324,24 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
true
;
}
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
* the SCSI device, as well as the device's Write Protect status.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
)
{
/* Send an empty header response with the Write Protect flag status */
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
DISK_READ_ONLY
?
0x80
:
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_ClearIN
();
/* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo
->
State
.
CommandBlock
.
DataTransferLength
-=
4
;
return
true
;
}
Projects/TempDataLogger/Lib/SCSI.h
View file @
9f7883fa
...
...
@@ -81,6 +81,7 @@
static
bool
SCSI_Command_Send_Diagnostic
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
static
bool
SCSI_Command_ReadWrite_10
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
bool
IsDataRead
);
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
#endif
#endif
...
...
Projects/TempDataLogger/TempDataLogger.h
View file @
9f7883fa
...
...
@@ -78,6 +78,9 @@
/** Default log interval when the EEPROM is blank, in 500ms ticks. */
#define DEFAULT_LOG_INTERVAL 20
/** Indicates if the disk is write protected or not. */
#define DISK_READ_ONLY false
/* Type Defines: */
typedef
struct
{
...
...
Projects/Webserver/Lib/DataflashManager.h
View file @
9f7883fa
...
...
@@ -64,6 +64,9 @@
*/
#define VIRTUAL_MEMORY_BLOCKS (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)
/** Indicates if the disk is write protected or not. */
#define DISK_READ_ONLY false
/* Function Prototypes: */
void
DataflashManager_WriteBlocks
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
uint32_t
BlockAddress
,
...
...
Projects/Webserver/Lib/SCSI.c
View file @
9f7883fa
...
...
@@ -113,6 +113,9 @@ bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
case
SCSI_CMD_READ_10
:
CommandSuccess
=
SCSI_Command_ReadWrite_10
(
MSInterfaceInfo
,
DATA_READ
);
break
;
case
SCSI_CMD_MODE_SENSE_6
:
CommandSuccess
=
SCSI_Command_ModeSense_6
(
MSInterfaceInfo
);
break
;
case
SCSI_CMD_TEST_UNIT_READY
:
case
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
:
case
SCSI_CMD_VERIFY_10
:
...
...
@@ -281,6 +284,17 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
uint32_t
BlockAddress
;
uint16_t
TotalBlocks
;
/* Check if the disk is write protected or not */
if
((
IsDataRead
==
DATA_WRITE
)
&&
DISK_READ_ONLY
)
{
/* Block address is invalid, update SENSE key and return command fail */
SCSI_SET_SENSE
(
SCSI_SENSE_KEY_DATA_PROTECT
,
SCSI_ASENSE_WRITE_PROTECTED
,
SCSI_ASENSEQ_NO_QUALIFIER
);
return
false
;
}
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
BlockAddress
=
SwapEndian_32
(
*
(
uint32_t
*
)
&
MSInterfaceInfo
->
State
.
CommandBlock
.
SCSICommandData
[
2
]);
...
...
@@ -297,7 +311,7 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
false
;
}
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
if
(
IsDataRead
==
DATA_READ
)
DataflashManager_ReadBlocks
(
MSInterfaceInfo
,
BlockAddress
,
TotalBlocks
);
...
...
@@ -310,3 +324,24 @@ static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfa
return
true
;
}
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
* the SCSI device, as well as the device's Write Protect status.
*
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
*
* \return Boolean true if the command completed successfully, false otherwise.
*/
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
)
{
/* Send an empty header response with the Write Protect flag status */
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_Write_Byte
(
DISK_READ_ONLY
?
0x80
:
0x00
);
Endpoint_Write_Byte
(
0x00
);
Endpoint_ClearIN
();
/* Update the bytes transferred counter and succeed the command */
MSInterfaceInfo
->
State
.
CommandBlock
.
DataTransferLength
-=
4
;
return
true
;
}
Projects/Webserver/Lib/SCSI.h
View file @
9f7883fa
...
...
@@ -80,6 +80,7 @@
static
bool
SCSI_Command_Send_Diagnostic
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
static
bool
SCSI_Command_ReadWrite_10
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
,
const
bool
IsDataRead
);
static
bool
SCSI_Command_ModeSense_6
(
USB_ClassInfo_MS_Device_t
*
const
MSInterfaceInfo
);
#endif
#endif
...
...
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