This patch enables security commands (currently mostly OPAL hardware encryption) for UAS and usb-storage drivers. The SCSI layer uses security commands for the initial OPAL support check (discovery command) and for in-kernel sed-ioctl interface. Some adapters support these commands, but firmware can be buggy or implemented incorrectly; the patch also adds a new quirk IGNORE_OPAL to disable security commands for particular devices. If adapters do not implement needed commands (ATA-12 pass-thru), the commands are rejected, and OPAL support remains disabled. (This is how it already works if OPAL command is sent from userspace directly, like in sedutils.) Signed-off-by: Milan Broz <gmazyland@xxxxxxxxx> --- Documentation/admin-guide/kernel-parameters.txt | 2 ++ drivers/usb/storage/scsiglue.c | 4 ++++ drivers/usb/storage/uas.c | 5 +++++ drivers/usb/storage/usb.c | 5 ++++- include/linux/usb_usual.h | 2 ++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 0a1731a0f0ef..e3f072cbb833 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6885,6 +6885,8 @@ y = ALWAYS_SYNC (issue a SYNCHRONIZE_CACHE even if the device claims no cache, not on uas) + z = IGNORE_OPAL (the device security commands + (OPAL) are broken, do not enable them); Example: quirks=0419:aaf5:rl,0421:0433:rc user_debug= [KNL,ARM] diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index c54e9805da53..ef93813a2049 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -209,6 +209,10 @@ static int slave_configure(struct scsi_device *sdev) /* Do not attempt to use WRITE SAME */ sdev->no_write_same = 1; + /* Allow security commands (OPAL) passthrough */ + if (!(us->fflags & US_FL_IGNORE_OPAL)) + sdev->security_supported = 1; + /* * Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 8a1c4449dcc9..8967767d6753 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -865,6 +865,11 @@ static int uas_slave_configure(struct scsi_device *sdev) /* Some disks cannot handle WRITE_SAME */ if (devinfo->flags & US_FL_NO_SAME) sdev->no_write_same = 1; + + /* Allow security commands (OPAL) passthrough */ + if (!(devinfo->flags & US_FL_IGNORE_OPAL)) + sdev->security_supported = 1; + /* * Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index bb48ab1bd461..3facc80292d7 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -477,7 +477,7 @@ void usb_stor_adjust_quirks(struct usb_device *udev, u64 *fflags) US_FL_INITIAL_READ10 | US_FL_WRITE_CACHE | US_FL_NO_ATA_1X | US_FL_NO_REPORT_OPCODES | US_FL_MAX_SECTORS_240 | US_FL_NO_REPORT_LUNS | - US_FL_ALWAYS_SYNC); + US_FL_ALWAYS_SYNC | US_FL_IGNORE_OPAL); p = quirks; while (*p) { @@ -566,6 +566,9 @@ void usb_stor_adjust_quirks(struct usb_device *udev, u64 *fflags) case 'y': f |= US_FL_ALWAYS_SYNC; break; + case 'z': + f |= US_FL_IGNORE_OPAL; + break; /* Ignore unrecognized flag characters */ } } diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 712363c7a2e8..0181c94d7d91 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -88,6 +88,8 @@ /* Cannot handle WRITE_SAME */ \ US_FLAG(SENSE_AFTER_SYNC, 0x80000000) \ /* Do REQUEST_SENSE after SYNCHRONIZE_CACHE */ \ + US_FLAG(IGNORE_OPAL, 0x100000000) \ + /* Security commands (OPAL) are broken */ \ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; -- 2.42.0