-
Notifications
You must be signed in to change notification settings - Fork 158
feat: add scsi mode sense operation to detect write protection #1524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/202502
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,6 +196,68 @@ ScsiDiskDriverBindingSupported ( | |
return Status; | ||
} | ||
|
||
// MU_CHANGE Begin: Add function to check whether the disk is write protected | ||
|
||
/** | ||
y * Check whether the SCSI disk is write protected. | ||
* | ||
* @param ScsiDiskDevice The SCSI disk device. | ||
* @param WriteProtectionEnabled A pointer to a boolean that will be set to TRUE if the disk is write protected, FALSE otherwise. | ||
* | ||
* @return EFI_SUCCESS The operation completed successfully. | ||
* @return EFI_INVALID_PARAMETER One of the input parameters was invalid. | ||
* @return other An error occurred while executing the SCSI command. | ||
*/ | ||
STATIC | ||
EFI_STATUS | ||
IsWriteProtected ( | ||
os-d marked this conversation as resolved.
Show resolved
Hide resolved
|
||
IN OUT SCSI_DISK_DEV *ScsiDiskDevice, | ||
OUT BOOLEAN *WriteProtectionEnabled | ||
) | ||
{ | ||
EFI_STATUS Status; | ||
EFI_SCSI_IO_SCSI_REQUEST_PACKET CommandPacket; | ||
UINT8 Cdb[6]; | ||
UINT8 DataBuffer[64]; | ||
|
||
if ((ScsiDiskDevice == NULL) || (WriteProtectionEnabled == NULL) || (ScsiDiskDevice->ScsiIo == NULL)) { | ||
return EFI_INVALID_PARAMETER; | ||
} | ||
|
||
// | ||
os-d marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Initialize SCSI REQUEST_PACKET and 6-byte Cdb | ||
// | ||
ZeroMem (&CommandPacket, sizeof (CommandPacket)); | ||
ZeroMem (Cdb, sizeof (Cdb)); | ||
|
||
// Initialize output parameter to default value | ||
*WriteProtectionEnabled = FALSE; | ||
|
||
Cdb[0] = ATA_CMD_MODE_SENSE6; | ||
Cdb[1] = 0b1000; // Setting the bit for Disable Block Descriptor | ||
Cdb[2] = ATA_PAGE_CODE_RETURN_ALL_PAGES; | ||
Cdb[4] = sizeof (DataBuffer); | ||
|
||
CommandPacket.Timeout = SCSI_DISK_TIMEOUT; | ||
CommandPacket.Cdb = Cdb; | ||
CommandPacket.CdbLength = (UINT8)sizeof (Cdb); | ||
CommandPacket.InDataBuffer = &DataBuffer; | ||
CommandPacket.InTransferLength = sizeof (DataBuffer); | ||
|
||
Status = ScsiDiskDevice->ScsiIo->ExecuteScsiCommand (ScsiDiskDevice->ScsiIo, &CommandPacket, NULL); | ||
|
||
if (EFI_ERROR (Status)) { | ||
return Status; | ||
} | ||
|
||
// Mode Sense 6 Byte Command returns the Write Protection status in the 3rd byte | ||
// Bit 7 of the 3rd byte indicates the Write Protection status | ||
*WriteProtectionEnabled = (DataBuffer[2] & 0x80) != 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where do you find this definition? I did a quick search and couldn't find it defined There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @spbrogan the SCSI stuff is not easily searchable, but copilot does a good job finding the write docs :). https://www.t10.org/ftp/t10/document.05/05-344r0.pdf see section 6.3.1. |
||
return EFI_SUCCESS; | ||
} | ||
|
||
// MU_CHANGE End: Add function to check whether the disk is write protected | ||
|
||
/** | ||
Start this driver on ControllerHandle. | ||
|
||
|
@@ -234,6 +296,8 @@ ScsiDiskDriverBindingStart ( | |
CHAR8 VendorStr[VENDOR_IDENTIFICATION_LENGTH + 1]; | ||
CHAR8 ProductStr[PRODUCT_IDENTIFICATION_LENGTH + 1]; | ||
CHAR16 DeviceStr[VENDOR_IDENTIFICATION_LENGTH + PRODUCT_IDENTIFICATION_LENGTH + 2]; | ||
// MU_CHANGE: Add variable to check whether the disk is write protected | ||
BOOLEAN WriteProtectionEnabled = FALSE; | ||
|
||
MustReadCapacity = TRUE; | ||
|
||
|
@@ -297,6 +361,20 @@ ScsiDiskDriverBindingStart ( | |
break; | ||
} | ||
|
||
// MU_CHANGE Begin: Check whether the disk is write protected and set the ReadOnly flag accordingly | ||
if (ScsiDiskDevice->DeviceType == EFI_SCSI_TYPE_DISK) { | ||
Status = IsWriteProtected (ScsiDiskDevice, &WriteProtectionEnabled); | ||
if (EFI_ERROR (Status)) { | ||
DEBUG ((DEBUG_ERROR, "ScsiDisk: IsWriteProtected() fails. Status = %r\n", Status)); | ||
} | ||
|
||
if (WriteProtectionEnabled) { | ||
ScsiDiskDevice->BlkIo.Media->ReadOnly = TRUE; | ||
} | ||
} | ||
|
||
// MU_CHANGE End: Check whether the disk is write protected and set the ReadOnly flag accordingly | ||
|
||
// | ||
// The Sense Data Array's initial size is 6 | ||
// | ||
|
Uh oh!
There was an error while loading. Please reload this page.