From patchwork Fri Sep 21 09:44:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avri Altman X-Patchwork-Id: 10609465 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 B742F6CB for ; Fri, 21 Sep 2018 09:45:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A64822DB87 for ; Fri, 21 Sep 2018 09:45:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 99EDB2DB94; Fri, 21 Sep 2018 09:45:49 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 23A662DB87 for ; Fri, 21 Sep 2018 09:45:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389470AbeIUPdu (ORCPT ); Fri, 21 Sep 2018 11:33:50 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:21394 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389217AbeIUPdu (ORCPT ); Fri, 21 Sep 2018 11:33:50 -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=1537523148; x=1569059148; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=a889d6tULdf7OJ6TVgJcE/Uz4aa5kcVC/kaEvAc9Rh4=; b=GsPiHAGoEPBtya5TT06eonxuvyfTHX6Ha57gMI/unQnpBIgtFLEOjlZN 3Nr2BjWhNu+RZUE/9b5+gNeC/cyag6ON5gIuhE3fYQuDsW3lNPUEg/erE DtA3WaTUmcwRj2YJZPHrLtaQFQ97Y+A7zmDWrv7dSsi54sY9qZUjhR0N8 LsRTls2JFSOETPFvNGRiQK2oQkyWfUuimVJ6NsNaIncrMotqlx+C6rtda 6Lsrpm7LYoYnZSDYpTzRYUa1yotNQAafUEEjOt26wGFTLvdpSmPFGIuJD xcmKe1WLtTr41TDOT79368Hv7lRtxEs2z9QbfvjS3lTK2o9d2Nv1NEhhd w==; X-IronPort-AV: E=Sophos;i="5.54,284,1534780800"; d="scan'208";a="90275943" Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 21 Sep 2018 17:45:47 +0800 Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep02.wdc.com with ESMTP; 21 Sep 2018 02:31:52 -0700 Received: from kfae422988.sdcorp.global.sandisk.com ([10.0.231.37]) by uls-op-cesaip01.wdc.com with ESMTP; 21 Sep 2018 02:45:44 -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 v6 6/7] scsi: ufs-bsg: Add support for raw upiu in ufs_bsg_request() Date: Fri, 21 Sep 2018 12:44:23 +0300 Message-Id: <1537523064-13478-7-git-send-email-avri.altman@wdc.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1537523064-13478-1-git-send-email-avri.altman@wdc.com> References: <1537523064-13478-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 --- drivers/scsi/ufs/ufs_bsg.c | 112 +++++++++++++++++++++++++++++++++++++++++++-- drivers/scsi/ufs/ufs_bsg.h | 3 ++ 2 files changed, 111 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index 1036c52..c1797e2 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -7,18 +7,122 @@ #include "ufs_bsg.h" +static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, + struct utp_upiu_query *qr, + int *desc_len) +{ + int desc_size = be16_to_cpu(qr->length); + int desc_id = qr->idn; + int ret = 0; + + if (qr->opcode != UPIU_QUERY_OPCODE_WRITE_DESC || 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 ret; +} + +static int ufs_bsg_verify_query_size(unsigned int request_len, + unsigned int reply_len, + int rw, int desc_len) +{ + int min_req_len = sizeof(struct ufs_bsg_request); + int min_rsp_len = sizeof(struct ufs_bsg_reply); + + if (rw == WRITE) + min_req_len += desc_len; + + if (min_req_len > request_len) + return -EINVAL; + + if (min_rsp_len > reply_len) + return -EINVAL; + + 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 request_len = job->request_len; + unsigned int reply_len = job->reply_len; + struct utp_upiu_query *qr; + int msgcode; + uint8_t *desc_buff = NULL; + int desc_len = 0; + int rw = UFS_BSG_NOP; + int ret; + ret = ufs_bsg_verify_query_size(request_len, reply_len, rw, desc_len); + if (ret) { + dev_err(job->dev, "not enough space assigned\n"); + 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: + qr = &bsg_request->upiu_req.qr; + if (qr->opcode == UPIU_QUERY_OPCODE_READ_DESC) + goto not_supported; + + if (ufs_bsg_get_query_desc_size(hba, qr, &desc_len)) + goto null_desc_buff; + + if (qr->opcode == UPIU_QUERY_OPCODE_WRITE_DESC) { + rw = WRITE; + desc_buff = (uint8_t *)(bsg_request + 1); + } + +null_desc_buff: + /* fall through */ + case UPIU_TRANSACTION_NOP_OUT: + case UPIU_TRANSACTION_TASK_REQ: + /* Now that we know if its a read or write, verify again */ + if (rw != UFS_BSG_NOP || desc_len) { + ret = ufs_bsg_verify_query_size(request_len, reply_len, + rw, desc_len); + if (ret) { + dev_err(job->dev, + "not enough space assigned\n"); + goto out; + } + } + + ret = ufshcd_exec_raw_upiu_cmd(hba, &bsg_request->upiu_req, + &bsg_reply->upiu_rsp, msgcode, + desc_buff, &desc_len, rw); + if (ret) + dev_dbg(hba->dev, + "exe raw upiu: error code %d\n", ret); + + break; + case UPIU_TRANSACTION_UIC_CMD: + /* later */ + case UPIU_TRANSACTION_COMMAND: + case UPIU_TRANSACTION_DATA_OUT: +not_supported: + /* for the time being, we do not support data transfer upiu */ + ret = -ENOTSUPP; + dev_err(job->dev, "unsupported msgcode 0x%x\n", msgcode); + + break; + default: + ret = -EINVAL; + + break; + } +out: bsg_reply->result = ret; job->reply_len = sizeof(struct ufs_bsg_reply) + bsg_reply->reply_payload_rcv_len; diff --git a/drivers/scsi/ufs/ufs_bsg.h b/drivers/scsi/ufs/ufs_bsg.h index d099187..b628583 100644 --- a/drivers/scsi/ufs/ufs_bsg.h +++ b/drivers/scsi/ufs/ufs_bsg.h @@ -12,6 +12,9 @@ #include "ufshcd.h" #include "ufs.h" + +#define UFS_BSG_NOP (-1) + #ifdef CONFIG_SCSI_UFS_BSG void ufs_bsg_remove(struct ufs_hba *hba); int ufs_bsg_probe(struct ufs_hba *hba);