From patchwork Fri Jan 11 00:08:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 10757071 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F1CB41390 for ; Fri, 11 Jan 2019 00:09:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFED929D45 for ; Fri, 11 Jan 2019 00:09:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D3CD129D5D; Fri, 11 Jan 2019 00:09:48 +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=-7.7 required=2.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,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 275B529D45 for ; Fri, 11 Jan 2019 00:09:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730755AbfAKAJm (ORCPT ); Thu, 10 Jan 2019 19:09:42 -0500 Received: from out002.mailprotect.be ([83.217.72.86]:59741 "EHLO out002.mailprotect.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730754AbfAKAJl (ORCPT ); Thu, 10 Jan 2019 19:09:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mailprotect.be; s=mail; h=Content-Transfer-Encoding:MIME-Version:References :In-Reply-To:Message-Id:Date:Subject:Cc:To:From:reply-to:sender:bcc: content-type; bh=IIhY/3g3+6C0vj8e/ChtzJUg/eKG2BuNXCxmvUpvk4U=; b=JFIwXi0BO0pK Kab8WpNAn6SeqbzJHxtJcBVkl/b7nu8FhrKQ3nOudbfteO++j8NFP8eiRopYjMBhTl8ISG2tNi7RJ EFcJ87Gvr7EzUTXcy/RSCSyR1S4TWRUlJoeS6HGvPX6kjbPORDXp9nN2VKFhQP3Dey/uYMWODUc0F 5fgj0IYfvp2oKkQnh5NKuS4yG+jULm+ksqjVrIjnMAkHFkzVLvEF2V0BZ9I28KeVYCJk4lE4IzbD2 MChoOOBZSBbAwyoE1ycq9etRKVxoGx9Hhezothnr/WaUxq5HmWRmTS4LUrsqDM6nlVuapSavl4gAa vAIbpx4Sc8xNMPK9aXcLdQ==; Received: from smtp-auth.mailprotect.be ([178.208.39.155]) by com-mpt-out002.mailprotect.be with esmtp (Exim 4.89) (envelope-from ) id 1ghkOH-000De2-55; Fri, 11 Jan 2019 01:09:37 +0100 Received: from desktop-bart.svl.corp.google.com (unknown [104.133.8.89]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp-auth.mailprotect.be (Postfix) with ESMTPSA id 801DBC0D61; Fri, 11 Jan 2019 01:09:22 +0100 (CET) From: Bart Van Assche To: "Martin K . Petersen" , "James E . J . Bottomley" Cc: linux-scsi@vger.kernel.org, Bart Van Assche Subject: [PATCH 6/8] sd: Create helper functions for read/write commands Date: Thu, 10 Jan 2019 16:08:56 -0800 Message-Id: <20190111000858.76261-7-bvanassche@acm.org> X-Mailer: git-send-email 2.20.1.97.g81188d93c3-goog In-Reply-To: <20190111000858.76261-1-bvanassche@acm.org> References: <20190111000858.76261-1-bvanassche@acm.org> MIME-Version: 1.0 X-Originating-IP: 178.208.39.155 X-SpamExperts-Domain: mailprotect.be X-SpamExperts-Username: 178.208.39.128/27 Authentication-Results: mailprotect.be; auth=pass smtp.auth=178.208.39.128/27@mailprotect.be X-SpamExperts-Outgoing-Class: ham X-SpamExperts-Outgoing-Evidence: SB/global_tokens (0.00380385169448) X-Recommended-Action: accept X-Filter-ID: EX5BVjFpneJeBchSMxfU5pKxzwcEbc9G8FTEw8LhCPd602E9L7XzfQH6nu9C/Fh9KJzpNe6xgvOx q3u0UDjvO1tLifGj39bI0bcPyaJsYTbBu5YFz4Jx0uq4149LpZwrkOR4/HajlzkVhakIw7Ig6RAJ lmpPd1BHwQ+kdrsiFH2cfUiCXtJytJdYVIlBCNoVDlGCgaqAfI9rupd8CZz+HVNiLZt/QXQnOBRD +jq1HsJAQnsLO8OlL77d3bdz3iqG02nIsRjNan5jEiQKJWbmTyP1HaH27Qjry/056DPMnxd+Swxv aRjzxpV3vJPKQXRYGRQP6aoq2j5ibghWGduoTjg3ZbOPxovcwpgDatF7VXVEbF4rUil7pUnOksxs 7aZaj3hJxCWpajY6LYvBNWgpuOnE6wHyAbSyVXutrqMjgFIlz7WWm/p16OPcLYPdHAK7vqrauYnQ lgTtl087RrjX0eEI2EoZ8+/7zzZhzgY6klGcBiHQNaIxsZV6P9u0dfcPCpDOcqQNioEzqLzLiIk4 HEcFBAvuf345Nnfstl8j+xb+3g9gkPulv+51ClEQ+Hg4gl/DsUQ1TVQibLlvhjffuqQBJ7TPMihJ UfmPOEFZaWMMYnXhfsZBupE3ropdJsWCES6o0yXgT60woyy/8De7jEVHEX0tIc2xkWXbaWtFGf8f SSeUyA5BNWn7HV+jYQ+bPPIKc+pi3RwDjjhJKjjVWllgjBusKL/lG7HvJzGm7bVpG9x2dnGeSM5z lYrnQPitMpHpGBDqxwz+gMmeGHJLGbB5qPrmLnSSifG4ucd7W6WiLdGNCnvgpopfSu7WpHHCvfcA DmA9UAv1v+rYdrKgZW/u3aItGPEPwBw7xatDmEFQvy23SZXSfMZ7RzHGH1l2j3GMtYjHvvB91g3T ziZ91gd/5+ZnhpSYcoe+EE6OOxFOL4nawG8z87Sn7OLOV4Lis3vxMFxvQI95yX1Uqc2NraLyHm3n 4a4AzXkeEvgQi2jtxOzzT/YWdmD8gywgB151tgZkcRkCnoMzps1w8ZlyWpuWa9TLRBg21otcGPr1 zYyDRfp0WSy7R6kupj1q3Dt9ZyCgxZHINA6A5+7T9o6by6TTlSa2Lh/bXHbr9KsH2f7CCey7HUjs wwJCoJUeO2iBpksPaDU3ZH1Nh3tobKAf6zEvuGslKTrRIXcXpFg5ivY= X-Report-Abuse-To: spam@com-mpt-mgt001.mailprotect.be 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 From: "Martin K. Petersen" Create a helper function for each of the 6, 10, 16 and 32-byte READ/WRITE variants and use those when setting up reads and writes. Signed-off-by: Martin K. Petersen [ bvanassche: ported this patch from kernel v4.11 to kernel v5.0 and made function names shorter. ] Signed-off-by: Bart Van Assche Reviewed-by: Hannes Reinecke --- drivers/scsi/sd.c | 167 +++++++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 75 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0b609a3a207a..039b0c7f178e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1073,6 +1073,83 @@ static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd) return BLK_STS_OK; } +static blk_status_t sd_setup_rw32_cmnd(struct scsi_cmnd *cmd, bool write, + sector_t lba, unsigned int nr_blocks, + unsigned char flags) +{ + cmd->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC); + if (unlikely(cmd->cmnd == NULL)) + return BLK_STS_RESOURCE; + + cmd->cmd_len = SD_EXT_CDB_SIZE; + memset(cmd->cmnd, 0, cmd->cmd_len); + + cmd->cmnd[0] = VARIABLE_LENGTH_CMD; + cmd->cmnd[7] = 0x18; /* Additional CDB len */ + cmd->cmnd[9] = write ? WRITE_32 : READ_32; + cmd->cmnd[10] = flags; + put_unaligned_be64(lba, &cmd->cmnd[12]); + put_unaligned_be32(lba, &cmd->cmnd[20]); /* Expected Indirect LBA */ + put_unaligned_be32(nr_blocks, &cmd->cmnd[28]); + + return BLK_STS_OK; +} + +static blk_status_t sd_setup_rw16_cmnd(struct scsi_cmnd *cmd, bool write, + sector_t lba, unsigned int nr_blocks, + unsigned char flags) +{ + cmd->cmd_len = 16; + cmd->cmnd[0] = write ? WRITE_16 : READ_16; + cmd->cmnd[1] = flags; + cmd->cmnd[14] = 0; + cmd->cmnd[15] = 0; + put_unaligned_be64(lba, &cmd->cmnd[2]); + put_unaligned_be32(nr_blocks, &cmd->cmnd[10]); + + return BLK_STS_OK; +} + +static blk_status_t sd_setup_rw10_cmnd(struct scsi_cmnd *cmd, bool write, + sector_t lba, unsigned int nr_blocks, + unsigned char flags) +{ + cmd->cmd_len = 10; + cmd->cmnd[0] = write ? WRITE_10 : READ_10; + cmd->cmnd[1] = flags; + cmd->cmnd[6] = 0; + cmd->cmnd[9] = 0; + put_unaligned_be32(lba, &cmd->cmnd[2]); + put_unaligned_be16(nr_blocks, &cmd->cmnd[7]); + + return BLK_STS_OK; +} + +static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write, + sector_t lba, unsigned int nr_blocks, + unsigned char flags) +{ + if (unlikely(flags & 0x8)) { + /* + * This happens only if this drive failed 10byte rw + * command with ILLEGAL_REQUEST during operation and + * thus turned off use_10_for_rw. + */ + scmd_printk(KERN_ERR, cmd, "FUA write on READ/WRITE(6) drive\n"); + return BLK_STS_IOERR; + } + + cmd->cmd_len = 6; + cmd->cmnd[0] = write ? WRITE_6 : READ_6; + cmd->cmnd[1] = (lba >> 16) & 0x1f; + cmd->cmnd[2] = (lba >> 8) & 0xff; + cmd->cmnd[3] = lba & 0xff; + cmd->cmnd[4] = nr_blocks; + cmd->cmnd[5] = 0; + + return BLK_STS_OK; +} + static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) { struct request *rq = SCpnt->request; @@ -1084,7 +1161,8 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); unsigned int dif, dix; unsigned int mask = logical_to_sectors(sdp, 1) - 1; - unsigned char protect; + bool write = rq_data_dir(rq) == WRITE; + unsigned char protect, fua; blk_status_t ret; ret = scsi_init_io(SCpnt); @@ -1159,6 +1237,7 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) "writing" : "reading", nr_blocks, blk_rq_sectors(rq))); + fua = rq->cmd_flags & REQ_FUA ? 0x8 : 0; dix = scsi_prot_sg_count(SCpnt); dif = scsi_host_dif_capable(SCpnt->device->host, sdkp->protection_type); @@ -1168,86 +1247,24 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *SCpnt) protect = 0; if (protect && sdkp->protection_type == T10_PI_TYPE2_PROTECTION) { - SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC); - - if (unlikely(!SCpnt->cmnd)) - return BLK_STS_RESOURCE; - - SCpnt->cmd_len = SD_EXT_CDB_SIZE; - memset(SCpnt->cmnd, 0, SCpnt->cmd_len); - SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD; - SCpnt->cmnd[7] = 0x18; - SCpnt->cmnd[9] = (rq_data_dir(rq) == READ) ? READ_32 : WRITE_32; - SCpnt->cmnd[10] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); - - /* LBA */ - SCpnt->cmnd[12] = sizeof(lba) > 4 ? (unsigned char) (lba >> 56) & 0xff : 0; - SCpnt->cmnd[13] = sizeof(lba) > 4 ? (unsigned char) (lba >> 48) & 0xff : 0; - SCpnt->cmnd[14] = sizeof(lba) > 4 ? (unsigned char) (lba >> 40) & 0xff : 0; - SCpnt->cmnd[15] = sizeof(lba) > 4 ? (unsigned char) (lba >> 32) & 0xff : 0; - SCpnt->cmnd[16] = (unsigned char) (lba >> 24) & 0xff; - SCpnt->cmnd[17] = (unsigned char) (lba >> 16) & 0xff; - SCpnt->cmnd[18] = (unsigned char) (lba >> 8) & 0xff; - SCpnt->cmnd[19] = (unsigned char) lba & 0xff; - - /* Expected Indirect LBA */ - SCpnt->cmnd[20] = (unsigned char) (lba >> 24) & 0xff; - SCpnt->cmnd[21] = (unsigned char) (lba >> 16) & 0xff; - SCpnt->cmnd[22] = (unsigned char) (lba >> 8) & 0xff; - SCpnt->cmnd[23] = (unsigned char) lba & 0xff; - - /* Transfer length */ - SCpnt->cmnd[28] = (unsigned char) (nr_blocks >> 24) & 0xff; - SCpnt->cmnd[29] = (unsigned char) (nr_blocks >> 16) & 0xff; - SCpnt->cmnd[30] = (unsigned char) (nr_blocks >> 8) & 0xff; - SCpnt->cmnd[31] = (unsigned char) nr_blocks & 0xff; + ret = sd_setup_rw32_cmnd(SCpnt, write, lba, nr_blocks, + protect | fua); } else if (sdp->use_16_for_rw || (nr_blocks > 0xffff)) { - SCpnt->cmnd[0] += READ_16 - READ_6; - SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); - SCpnt->cmnd[2] = sizeof(lba) > 4 ? (unsigned char) (lba >> 56) & 0xff : 0; - SCpnt->cmnd[3] = sizeof(lba) > 4 ? (unsigned char) (lba >> 48) & 0xff : 0; - SCpnt->cmnd[4] = sizeof(lba) > 4 ? (unsigned char) (lba >> 40) & 0xff : 0; - SCpnt->cmnd[5] = sizeof(lba) > 4 ? (unsigned char) (lba >> 32) & 0xff : 0; - SCpnt->cmnd[6] = (unsigned char) (lba >> 24) & 0xff; - SCpnt->cmnd[7] = (unsigned char) (lba >> 16) & 0xff; - SCpnt->cmnd[8] = (unsigned char) (lba >> 8) & 0xff; - SCpnt->cmnd[9] = (unsigned char) lba & 0xff; - SCpnt->cmnd[10] = (unsigned char) (nr_blocks >> 24) & 0xff; - SCpnt->cmnd[11] = (unsigned char) (nr_blocks >> 16) & 0xff; - SCpnt->cmnd[12] = (unsigned char) (nr_blocks >> 8) & 0xff; - SCpnt->cmnd[13] = (unsigned char) nr_blocks & 0xff; - SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; + ret = sd_setup_rw16_cmnd(SCpnt, write, lba, nr_blocks, + protect | fua); } else if ((nr_blocks > 0xff) || (lba > 0x1fffff) || scsi_device_protection(SCpnt->device) || SCpnt->device->use_10_for_rw) { - SCpnt->cmnd[0] += READ_10 - READ_6; - SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); - SCpnt->cmnd[2] = (unsigned char) (lba >> 24) & 0xff; - SCpnt->cmnd[3] = (unsigned char) (lba >> 16) & 0xff; - SCpnt->cmnd[4] = (unsigned char) (lba >> 8) & 0xff; - SCpnt->cmnd[5] = (unsigned char) lba & 0xff; - SCpnt->cmnd[6] = SCpnt->cmnd[9] = 0; - SCpnt->cmnd[7] = (unsigned char) (nr_blocks >> 8) & 0xff; - SCpnt->cmnd[8] = (unsigned char) nr_blocks & 0xff; + ret = sd_setup_rw10_cmnd(SCpnt, write, lba, nr_blocks, + protect | fua); } else { - if (unlikely(rq->cmd_flags & REQ_FUA)) { - /* - * This happens only if this drive failed - * 10byte rw command with ILLEGAL_REQUEST - * during operation and thus turned off - * use_10_for_rw. - */ - scmd_printk(KERN_ERR, SCpnt, - "FUA write on READ/WRITE(6) drive\n"); - return BLK_STS_IOERR; - } - - SCpnt->cmnd[1] |= (unsigned char) ((lba >> 16) & 0x1f); - SCpnt->cmnd[2] = (unsigned char) ((lba >> 8) & 0xff); - SCpnt->cmnd[3] = (unsigned char) lba & 0xff; - SCpnt->cmnd[4] = (unsigned char) nr_blocks; - SCpnt->cmnd[5] = 0; + ret = sd_setup_rw6_cmnd(SCpnt, write, lba, nr_blocks, + protect | fua); } + + if (unlikely(ret != BLK_STS_OK)) + return ret; + SCpnt->sdb.length = nr_blocks * sdp->sector_size; /*