From patchwork Mon Sep 17 16:08:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avri Altman X-Patchwork-Id: 10603003 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 AD7B5157B for ; Mon, 17 Sep 2018 16:10:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9BAE829FCC for ; Mon, 17 Sep 2018 16:10:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8DADA29FF4; Mon, 17 Sep 2018 16:10:34 +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 0E0C629FCE for ; Mon, 17 Sep 2018 16:10:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728432AbeIQVie (ORCPT ); Mon, 17 Sep 2018 17:38:34 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:47062 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727193AbeIQVie (ORCPT ); Mon, 17 Sep 2018 17:38:34 -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=1537200633; x=1568736633; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=XEXTxdn/W5qQEt1uhbguzyVZ7B1z+nbVcQNJ+SZ0XjI=; b=XA1oa/S7o44cmR0WDCjEvTpRRSVoptacFktJc183Ajb/h7BR/TwcIqCx qf041qb+gs0GqqUtIShMd45k7+9CVAdNM4NrrDFnPpifidFm/bnVL5FFb kG5mqjYah8sBmrWLI1IZ/dJhvgnDFHwrO8lODFUJaZaTiKqOq1l6lT3q5 nI1zWndALSF9zlYxFksUqC93yVXx2RaniARl61mocM6wDQsL3/JuNkMnP ob2VrWeuoRjXrGBikohyQyXGocLf9VPeWJXBc1rONkZnIQ7yJqwloEnSf VFgKyq7vXXi3837fiMesy6aRHhsGrhrrqB+e/w4syFm8+8UT5jM7M36oA g==; X-IronPort-AV: E=Sophos;i="5.53,386,1531756800"; d="scan'208";a="94399759" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 18 Sep 2018 00:10:33 +0800 Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP; 17 Sep 2018 08:56:54 -0700 Received: from kfae422988.sdcorp.global.sandisk.com ([10.0.231.37]) by uls-op-cesaip01.wdc.com with ESMTP; 17 Sep 2018 09:10:30 -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 v5 5/6] scsi: ufs-bsg: Add support for raw upiu in ufs_bsg_request() Date: Mon, 17 Sep 2018 19:08:55 +0300 Message-Id: <1537200536-8817-6-git-send-email-avri.altman@wdc.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1537200536-8817-1-git-send-email-avri.altman@wdc.com> References: <1537200536-8817-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 | 121 +++++++++++++++++++++++++++++++++++++++++++-- drivers/scsi/ufs/ufs_bsg.h | 1 + 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index bc01d5d..adeb83a 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -7,18 +7,131 @@ #include "ufs_bsg.h" +static inline struct ufs_hba *dev_to_ufs_hba(struct device *d) +{ + struct Scsi_Host *shost = dev_to_shost(d->parent); + + return shost_priv(shost); +} + +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 = dev_to_ufs_hba(job->dev); + unsigned int request_len = job->request_len; + unsigned int reply_len = job->reply_len; + struct utp_upiu_query *qr; + struct utp_upiu_req *req_upiu = NULL; + struct utp_upiu_req *rsp_upiu = NULL; + 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->tsf.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) + + sizeof(struct ufs_bsg_request); + } + +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; + } + } + + req_upiu = (struct utp_upiu_req *)&bsg_request->header; + rsp_upiu = (struct utp_upiu_req *)&bsg_reply->header; + ret = ufshcd_exec_raw_upiu_cmd(hba, req_upiu, rsp_upiu, + msgcode, desc_buff, &desc_len, + rw); + + 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 f8fe286..ec236b2 100644 --- a/drivers/scsi/ufs/ufs_bsg.h +++ b/drivers/scsi/ufs/ufs_bsg.h @@ -12,6 +12,7 @@ #include "ufshcd.h" #include "ufs.h" +#define UFS_BSG_NOP (-1) #define UPIU_TRANSACTION_UIC_CMD 0x1F enum {