From patchwork Wed Aug 1 08:04:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avri Altman X-Patchwork-Id: 10551823 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 1C54D157D for ; Wed, 1 Aug 2018 08:07:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0E2522AC3D for ; Wed, 1 Aug 2018 08:07:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 01A202ADEA; Wed, 1 Aug 2018 08:07:07 +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 7622F2AC3D for ; Wed, 1 Aug 2018 08:07:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387695AbeHAJvd (ORCPT ); Wed, 1 Aug 2018 05:51:33 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:27468 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1733173AbeHAJvd (ORCPT ); Wed, 1 Aug 2018 05:51:33 -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=1533110826; x=1564646826; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=ZrCAGyLsJa5ghhNMPPCMlYgQQbG4WlWT+IZ0MFHYvII=; b=ieA/lA+WdX0zM/VzXnBn9zR0oYeJDJcCV/yqljR4Ws5Vjeb1luEMTzc7 JKaG+4h6aSoLLF+t2GRUFM1Gekh7MuTvlXRrJk4Yhoy5Mx9+elnfbp5D3 hk/q2CqCisRHarz5jpTQaPf1nDU76qOQy+zKnEzuRYGGo3tI0dB0viR1p uQZ1YA86MI7bipU2zENhyhGvUbBQN5AuFho6gzRyuntwJvKYI2tYpwP+0 6W3EUxvysxmigJIIvt6Y+gZY15EzpdB/45h1FCJj9zJzTep7XpdqYf31q erBD3ACs69lDkt+K+zqe1VGNUf4ySz/k4VDzA/o42dIWXpZSMp2etIk41 g==; X-IronPort-AV: E=Sophos;i="5.51,431,1526313600"; d="scan'208";a="89335955" 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; 01 Aug 2018 16:07:05 +0800 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP; 01 Aug 2018 00:54:55 -0700 Received: from kfae422988.sdcorp.global.sandisk.com ([10.0.231.37]) by uls-op-cesaip02.wdc.com with ESMTP; 01 Aug 2018 01:07:02 -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 5/6] scsi: ufs-bsg: Add support for raw upiu in ufs_bsg_request() Date: Wed, 1 Aug 2018 11:04:31 +0300 Message-Id: <1533110672-12785-6-git-send-email-avri.altman@wdc.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1533110672-12785-1-git-send-email-avri.altman@wdc.com> References: <1533110672-12785-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 | 119 +++++++++++++++++++++++++++++++++++++++++++-- drivers/scsi/ufs/ufs_bsg.h | 1 + 2 files changed, 116 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index 71826ba..d077e42 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -19,18 +19,129 @@ struct ufs_bsg { .bsg_request = ufs_bsg_request, }; +static int ufs_bsg_get_query_desc_size(struct utp_upiu_query *qr, + int *buff_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(bsg_host->hba, desc_id, buff_len); + + if (ret || !buff_len) + return -EINVAL; + + *buff_len = min_t(int, *buff_len, desc_size); + + return ret; +} + +static int ufs_bsg_verify_query_size(unsigned int request_len, + unsigned int reply_len, + int rw, int buff_len) +{ + int min_req_len = sizeof(struct ufs_bsg_request); + int min_rsp_len = sizeof(struct ufs_bsg_reply); + + if (rw == UFS_BSG_NOP) + goto null_buff; + + if (rw == WRITE) + min_req_len += buff_len; + +null_buff: + 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; + unsigned int request_len = job->request_len; + unsigned int reply_len = job->reply_len; + struct utp_upiu_query *qr; + __be32 *req_upiu = NULL; + __be32 *rsp_upiu = NULL; + int msgcode; + uint8_t *desc_buff = NULL; + int buff_len = 0; + int rw = UFS_BSG_NOP; + int ret; + ret = ufs_bsg_verify_query_size(request_len, reply_len, rw, buff_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(qr, &buff_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 || buff_len) { + ret = ufs_bsg_verify_query_size(request_len, reply_len, + rw, buff_len); + if (ret) { + dev_err(job->dev, + "not enough space assigned\n"); + goto out; + } + } + + req_upiu = (__be32 *)&bsg_request->header; + rsp_upiu = (__be32 *)&bsg_reply->header; + ret = ufshcd_exec_raw_upiu_cmd(bsg_host->hba, + req_upiu, rsp_upiu, msgcode, + desc_buff, &buff_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; + } + + bsg_reply->reply_payload_rcv_len = buff_len; +out: bsg_reply->result = ret; if (ret) job->reply_len = sizeof(uint32_t); diff --git a/drivers/scsi/ufs/ufs_bsg.h b/drivers/scsi/ufs/ufs_bsg.h index de5511f..0fd2859 100644 --- a/drivers/scsi/ufs/ufs_bsg.h +++ b/drivers/scsi/ufs/ufs_bsg.h @@ -13,6 +13,7 @@ #include "ufshcd.h" #include "ufs.h" +#define UFS_BSG_NOP (-1) #define UPIU_TRANSACTION_UIC_CMD 0x1F enum {