From patchwork Sun Sep 30 05:45:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avri Altman X-Patchwork-Id: 10621161 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 6E586112B for ; Sun, 30 Sep 2018 05:47:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C16929AEE for ; Sun, 30 Sep 2018 05:47:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E95429AF2; Sun, 30 Sep 2018 05:47:15 +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 D419A29AEE for ; Sun, 30 Sep 2018 05:47:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727852AbeI3MSt (ORCPT ); Sun, 30 Sep 2018 08:18:49 -0400 Received: from esa1.hgst.iphmx.com ([68.232.141.245]:40750 "EHLO esa1.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726334AbeI3MSs (ORCPT ); Sun, 30 Sep 2018 08:18:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1538286434; x=1569822434; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=u9eGgH/yqXr1XHQ0mGphKezCKJUxXJWT6ED5wuqVDDg=; b=PADGoejqm5S2sGZkwvUm8Zzml0aUi9yL8MTi6hdwQA4XqSrs0T7PVNOf TXxfTPLSrq2wiGd1yx4I3NL6eA0tIJXQSD7IoGPcvdFoQgoq5rDmgslXC z8omWOkLUr5JzlmoQg2Qt9MtyjubakIXfkNAXFBP/0KnCgpcmMIJ41zW6 9pXC1KoAkMr6vYohuneOCdBa+prPceGmxCbPC1ShtCF+kxtxXD2T7je+h R81HETJ904pYqYcMTCTpgOi+/s8/4Fnvnw8Pss7jN3rd/wz3SfTv+soa6 gPYfu3REoNVtNDhxsJnsNe45PaRliR+fpvp1EPWYmVBtiMzJjF3lRjSBK Q==; X-IronPort-AV: E=Sophos;i="5.54,322,1534780800"; d="scan'208";a="195160958" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 30 Sep 2018 13:47:13 +0800 Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep02.wdc.com with ESMTP; 29 Sep 2018 22:32:55 -0700 Received: from kfae422988.sdcorp.global.sandisk.com ([10.0.231.37]) by uls-op-cesaip01.wdc.com with ESMTP; 29 Sep 2018 22:47:11 -0700 From: Avri Altman To: Christoph Hellwig , Johannes Thumshirn , Hannes Reinecke , Bart Van Assche , "James E.J. Bottomley" , "Martin K. Petersen" , linux-scsi@vger.kernel.org Cc: Stanislav Nijnikov , Avi Shchislowski , Alex Lemberg , Subhash Jadavani , Vinayak Holikatti , Avri Altman Subject: [PATCH v7 7/8] scsi: ufs-bsg: Add support for raw upiu in ufs_bsg_request() Date: Sun, 30 Sep 2018 08:45:59 +0300 Message-Id: <1538286360-7319-8-git-send-email-avri.altman@wdc.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1538286360-7319-1-git-send-email-avri.altman@wdc.com> References: <1538286360-7319-1-git-send-email-avri.altman@wdc.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 Do that for the currently supported UPIUs: query, nop out, and task management. We do not support UPIU of type scsi command yet, while we are using the job's request and reply pointers to hold the payload. We will look into it in later patches. We might need to elaborate the raw upiu api for that. We also still not supporting uic commands: For first phase, we plan to use the existing api, and send only uic commands that are already supported. Anyway, all that will come in the next patch. Signed-off-by: Avri Altman Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche --- drivers/scsi/ufs/ufs_bsg.c | 114 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index 1036c52..306e5f1 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -6,19 +6,125 @@ */ #include "ufs_bsg.h" +static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len, + struct utp_upiu_query *qr) +{ + int desc_size = be16_to_cpu(qr->length); + int desc_id = qr->idn; + int ret; + + if (desc_size <= 0) + return -EINVAL; + + ret = ufshcd_map_desc_id_to_length(hba, desc_id, desc_len); + if (ret || !*desc_len) + return -EINVAL; + + *desc_len = min_t(int, *desc_len, desc_size); + + return 0; +} + +static int ufs_bsg_verify_query_size(struct ufs_hba *hba, + unsigned int request_len, + unsigned int reply_len, + int desc_len, enum query_opcode desc_op) +{ + int min_req_len = sizeof(struct ufs_bsg_request); + int min_rsp_len = sizeof(struct ufs_bsg_reply); + + if (desc_op == UPIU_QUERY_OPCODE_WRITE_DESC) + min_req_len += desc_len; + + if (min_req_len > request_len || min_rsp_len > reply_len) { + dev_err(hba->dev, "not enough space assigned\n"); + return -EINVAL; + } + + return 0; +} + +static int ufs_bsg_verify_query_params(struct ufs_hba *hba, + struct ufs_bsg_request *bsg_request, + unsigned int request_len, + unsigned int reply_len, + uint8_t *desc_buff, int *desc_len, + enum query_opcode desc_op) +{ + struct utp_upiu_query *qr; + + if (desc_op == UPIU_QUERY_OPCODE_READ_DESC) { + dev_err(hba->dev, "unsupported opcode %d\n", desc_op); + return -ENOTSUPP; + } + + if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC) + goto out; + + qr = &bsg_request->upiu_req.qr; + if (ufs_bsg_get_query_desc_size(hba, desc_len, qr)) { + dev_err(hba->dev, "Illegal desc size\n"); + return -EINVAL; + } + + if (ufs_bsg_verify_query_size(hba, request_len, reply_len, *desc_len, + desc_op)) + return -EINVAL; + + desc_buff = (uint8_t *)(bsg_request + 1); + +out: + return 0; +} static int ufs_bsg_request(struct bsg_job *job) { struct ufs_bsg_request *bsg_request = job->request; struct ufs_bsg_reply *bsg_reply = job->reply; - int ret = -ENOTSUPP; + struct ufs_hba *hba = shost_priv(dev_to_shost(job->dev->parent)); + unsigned int req_len = job->request_len; + unsigned int reply_len = job->reply_len; + int msgcode; + uint8_t *desc_buff = NULL; + int desc_len = 0; + enum query_opcode desc_op = UPIU_QUERY_OPCODE_NOP; + int ret; + + ret = ufs_bsg_verify_query_size(hba, req_len, reply_len, 0, desc_op); + if (ret) + goto out; bsg_reply->reply_payload_rcv_len = 0; - /* Do Nothing for now */ - dev_err(job->dev, "unsupported message_code 0x%x\n", - bsg_request->msgcode); + msgcode = bsg_request->msgcode; + switch (msgcode) { + case UPIU_TRANSACTION_QUERY_REQ: + desc_op = bsg_request->upiu_req.qr.opcode; + ret = ufs_bsg_verify_query_params(hba, bsg_request, req_len, + reply_len, desc_buff, + &desc_len, desc_op); + if (ret) + goto out; + + /* fall through */ + case UPIU_TRANSACTION_NOP_OUT: + case UPIU_TRANSACTION_TASK_REQ: + ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req, + &bsg_reply->upiu_rsp, msgcode, + desc_buff, &desc_len, desc_op); + if (ret) + dev_err(hba->dev, + "exe raw upiu: error code %d\n", ret); + + break; + default: + ret = -ENOTSUPP; + dev_err(hba->dev, "unsupported msgcode 0x%x\n", msgcode); + + break; + } +out: bsg_reply->result = ret; job->reply_len = sizeof(struct ufs_bsg_reply) + bsg_reply->reply_payload_rcv_len;