From patchwork Thu Jun 9 06:32:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shaun Tancheff X-Patchwork-Id: 9166329 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3237A604DB for ; Thu, 9 Jun 2016 06:33:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 24CD926490 for ; Thu, 9 Jun 2016 06:33:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 193062830C; Thu, 9 Jun 2016 06:33:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D6B026490 for ; Thu, 9 Jun 2016 06:33:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1423336AbcFIGdW (ORCPT ); Thu, 9 Jun 2016 02:33:22 -0400 Received: from smtp81.mediacombb.net ([68.66.77.81]:54161 "EHLO dsmdc-mail-smtp.mcomdc.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1423278AbcFIGdV (ORCPT ); Thu, 9 Jun 2016 02:33:21 -0400 Received: from helios ([173.23.250.243]) by njtocomv02.mcomdc.com with bizsmtp id 4WYy1t0085FqEsV01WYzCk; Thu, 09 Jun 2016 02:33:09 -0400 X-Outbound-Route: TO X-Authenticated-Sender: shaun@helios.aeonazure.com X-Authority-Analysis: v=2.1 cv=C/RnyG/+ c=1 sm=1 tr=0 a=OCiMecrhrNRzvyrd/uXHhg==:117 a=OCiMecrhrNRzvyrd/uXHhg==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=pD_ry4oyNxEA:10 a=3go8odswAAAA:8 a=XT681JKakgeI10C1adsA:9 a=WCphLhRDQySbTNkkd-8K:22 X-Authenticated-Sender: shaun@helios.aeonazure.com Received: from shaun by helios with local (Exim 4.87) (envelope-from ) id 1bAtWU-0002tX-Hk; Thu, 09 Jun 2016 01:32:58 -0500 From: Shaun Tancheff To: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org Cc: Shaun Tancheff , "James E . J . Bottomley" , "Martin K . Petersen" , Tejun Heo , Shaun Tancheff Subject: [PATCH v2] Add support for SCT Write Same Date: Thu, 9 Jun 2016 01:32:47 -0500 Message-Id: <1465453967-11085-2-git-send-email-shaun@tancheff.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1465453967-11085-1-git-send-email-shaun@tancheff.com> References: <1465453967-11085-1-git-send-email-shaun@tancheff.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP SATA drives may support write same via SCT. This is useful for setting the drive contents to a specific pattern (0's). Signed-off-by: Shaun Tancheff --- v2: - Remove fugly ata hacking from sd.c --- drivers/ata/libata-scsi.c | 34 ++++++++++++++++++++++++++++++++++ drivers/scsi/sd.c | 2 +- include/linux/ata.h | 43 +++++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi_device.h | 1 + 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index bfec66f..b73eace 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1204,6 +1204,9 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, if (!ata_id_has_unload(dev->id)) dev->flags |= ATA_DFLAG_NO_UNLOAD; + if (ata_id_sct_write_same(dev->id)) + sdev->sct_write_same = 1; + /* configure max sectors */ blk_queue_max_hw_sectors(q, dev->max_sectors); @@ -3305,6 +3308,37 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) goto invalid_param_len; buf = page_address(sg_page(scsi_sglist(scmd))); + + if (ata_id_sct_write_same(dev->id)) { + u16 *sctpg = buf; + + put_unaligned_le16(0x0002, &sctpg[0]); /* SCT_ACT_WRITE_SAME */ + put_unaligned_le16(0x0101, &sctpg[1]); /* WRITE PTRN FG */ + put_unaligned_le64(block, &sctpg[2]); + put_unaligned_le64(n_block, &sctpg[6]); + put_unaligned_le32(0u, &sctpg[10]); + + tf->hob_feature = 0; + tf->feature = 0; + tf->hob_nsect = 0; + tf->nsect = 1; + tf->lbah = 0; + tf->lbam = 0; + tf->lbal = ATA_CMD_STANDBYNOW1; + tf->hob_lbah = 0; + tf->hob_lbam = 0; + tf->hob_lbal = 0; + tf->device = ATA_CMD_STANDBYNOW1; + tf->protocol = ATA_PROT_DMA; + tf->command = ATA_CMD_WRITE_LOG_DMA_EXT; + tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | + ATA_TFLAG_LBA48 | ATA_TFLAG_WRITE; + + ata_qc_set_pc_nbytes(qc); + + return 0; + } + size = ata_set_lba_range_entries(buf, 512, block, n_block); if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index f459dff..b5ffcd3 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -794,7 +794,7 @@ static void sd_config_write_same(struct scsi_disk *sdkp) struct request_queue *q = sdkp->disk->queue; unsigned int logical_block_size = sdkp->device->sector_size; - if (sdkp->device->no_write_same) { + if (sdkp->device->no_write_same && !sdkp->device->sct_write_same) { sdkp->max_ws_blocks = 0; goto out; } diff --git a/include/linux/ata.h b/include/linux/ata.h index 99346be..4132de3 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -104,6 +104,7 @@ enum { ATA_ID_CFA_KEY_MGMT = 162, ATA_ID_CFA_MODES = 163, ATA_ID_DATA_SET_MGMT = 169, + ATA_ID_SCT_CMD_XPORT = 206, ATA_ID_ROT_SPEED = 217, ATA_ID_PIO4 = (1 << 1), @@ -778,6 +779,48 @@ static inline bool ata_id_sense_reporting_enabled(const u16 *id) } /** + * + * Word: 206 - SCT Command Transport + * 15:12 - Vendor Specific + * 11:6 - Reserved + * 5 - SCT Command Transport Data Tables supported + * 4 - SCT Command Transport Features Control supported + * 3 - SCT Command Transport Error Recovery Control supported + * 2 - SCT Command Transport Write Same supported + * 1 - SCT Command Transport Long Sector Access supported + * 0 - SCT Command Transport supported + */ +static inline bool ata_id_sct_data_tables(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 5) ? true : false; +} + +static inline bool ata_id_sct_features_ctrl(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 4) ? true : false; +} + +static inline bool ata_id_sct_error_recovery_ctrl(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 3) ? true : false; +} + +static inline bool ata_id_sct_write_same(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 2) ? true : false; +} + +static inline bool ata_id_sct_long_sector_access(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 1) ? true : false; +} + +static inline bool ata_id_sct_supported(const u16 *id) +{ + return id[ATA_ID_SCT_CMD_XPORT] & (1 << 0) ? true : false; +} + +/** * ata_id_major_version - get ATA level of drive * @id: Identify data * diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index a6c346d..66f5af7 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -157,6 +157,7 @@ struct scsi_device { unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */ unsigned no_report_opcodes:1; /* no REPORT SUPPORTED OPERATION CODES */ unsigned no_write_same:1; /* no WRITE SAME command */ + unsigned sct_write_same:1; /* Has WRITE SAME via SCT Command */ unsigned use_16_for_rw:1; /* Use read/write(16) over read/write(10) */ unsigned skip_ms_page_8:1; /* do not use MODE SENSE page 0x08 */ unsigned skip_ms_page_3f:1; /* do not use MODE SENSE page 0x3f */