From: Tom Yan <tom.t...@gmail.com>

With this patch, users can make use of the SANITIZE DEVICE feature
set through utility like sg_sanitize.

Support for BLOCK ERASE, CRYPTOGRAPHIC ERASE and EXIT FAILURE MODE
has been implemented. Support for OVERWRITE that involves a
parameter list has been left out for now.

Further support for command with IMMED bit set to zero, REQUEST
SENSE translation for user-space status polling, and support
checking in IDENTIFY DEVICE data log (return proper sense data
when designated method is not supported) should be implemented
in the future as well.

`sg_sanitize -e -B|-C|-F /dev/sdX` should work fine with this.

Signed-off-by: Tom Yan <tom.t...@gmail.com>

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index bfec66f..a64991b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3346,6 +3346,63 @@ invalid_opcode:
        return 1;
 }
 
+static unsigned int ata_scsi_sanitize_xlat(struct ata_queued_cmd *qc) {
+       struct ata_taskfile *tf = &qc->tf;
+       struct scsi_cmnd *scmd = qc->scsicmd;
+       struct ata_device *dev = qc->dev;
+       const u8 *cdb = scmd->cmnd;
+       u16 fp;
+       u8 bp = 0xff;
+
+       /* for now we only support SANITIZE with IMMED bit set */
+       if (unlikely(!(cdb[1] & 0x80))) {
+               fp = 1;
+               bp = 7;
+               goto invalid_fld;
+       }
+
+       tf->protocol = ATA_PROT_NODATA;
+       tf->command = ATA_CMD_SANITIZE_DEVICE;
+       tf->hob_nsect |= (cdb[1] & 0x40) << 1;
+       tf->nsect |= (cdb[1] & 0x20) >> 1;
+       tf->flags |= ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+
+       switch (cdb[1] & 0x1f) {
+       /* TODO: add support for OVERWRITE */
+       case 0x2: /* BLOCK ERASE */
+               tf->hob_feature = 0x0;
+               tf->feature = 0x12;
+               tf->hob_lbal = 0x42;
+               tf->lbah = 0x6b;
+               tf->lbam = 0x45;
+               tf->lbal = 0x72;
+               break;
+       case 0x3: /* CRYPTOGRAPHIC ERASE */
+               tf->hob_feature = 0x0;
+               tf->feature = 0x11;
+               tf->hob_lbal = 0x43;
+               tf->lbah = 0x72;
+               tf->lbam = 0x79;
+               tf->lbal = 0x70;
+               break;
+       case 0x1f: /* EXIT FAILURE MODE */
+               tf->hob_feature = 0x0;
+               tf->feature = 0x0;
+               tf->nsect |= 0x1;
+               break;
+       default:
+               fp = 1;
+               bp = 4;
+               goto invalid_fld;
+       }
+
+       return 0;
+
+invalid_fld:
+       ata_scsi_set_invalid_field(dev, scmd, fp, bp);
+       return 1;
+}
+
 /**
  *     ata_scsi_report_zones_complete - convert ATA output
  *     @qc: command structure returning the data
@@ -3869,6 +3926,9 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct 
ata_device *dev, u8 cmd)
        case WRITE_SAME_16:
                return ata_scsi_write_same_xlat;
 
+       case SANITIZE:
+               return ata_scsi_sanitize_xlat;
+
        case SYNCHRONIZE_CACHE:
                if (ata_try_flush_cache(dev))
                        return ata_scsi_flush_xlat;
diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
index d1defd1..20d6085 100644
--- a/include/scsi/scsi_proto.h
+++ b/include/scsi/scsi_proto.h
@@ -72,6 +72,7 @@
 #define UNMAP                0x42
 #define READ_TOC              0x43
 #define READ_HEADER           0x44
+#define SANITIZE              0x48
 #define GET_EVENT_STATUS_NOTIFICATION 0x4a
 #define LOG_SELECT            0x4c
 #define LOG_SENSE             0x4d
-- 
2.9.0

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to