From patchwork Thu May 11 14:01:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Potomski, MichalX" X-Patchwork-Id: 9722443 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B0B86031B for ; Thu, 11 May 2017 16:25:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 00710286AD for ; Thu, 11 May 2017 16:25:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E980E286B8; Thu, 11 May 2017 16:25:52 +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=-6.9 required=2.0 tests=BAYES_00,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 12E3D286B6 for ; Thu, 11 May 2017 16:25:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933473AbdEKOCu (ORCPT ); Thu, 11 May 2017 10:02:50 -0400 Received: from mga03.intel.com ([134.134.136.65]:44248 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933462AbdEKOBs (ORCPT ); Thu, 11 May 2017 10:01:48 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 11 May 2017 07:01:47 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,324,1491289200"; d="scan'208";a="1146633522" Received: from mpotom-tieto.ir.intel.com ([10.103.116.163]) by fmsmga001.fm.intel.com with ESMTP; 11 May 2017 07:01:43 -0700 From: Michal Potomski To: linux-scsi@vger.kernel.org Cc: vinholikatti@gmail.com, martin.petersen@oracle.com, jejb@linux.vnet.ibm.com, subhashj@codeaurora.org, Szymon Mielczarek , =?UTF-8?q?Micha=C5=82=20Potomski?= Subject: [PATCH v1 4/4] scsi: ufs: add ioctl interface to read UIC attributes Date: Thu, 11 May 2017 16:01:49 +0200 Message-Id: <1494511309-32256-5-git-send-email-michalx.potomski@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1494511309-32256-1-git-send-email-michalx.potomski@intel.com> References: <1494511309-32256-1-git-send-email-michalx.potomski@intel.com> MIME-Version: 1.0 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: Szymon Mielczarek The interface allows to read both local (Host side) and peer (Device side) UIC attributes using either DME_GET or DME_PEER_GET primitives. The Attribute can be used to determine the current state or the capabilities of the UFS InterConnect Layer (UIC - UniPro & M-PHY). Signed-off-by: Szymon Mielczarek Signed-off-by: MichaƂ Potomski --- Documentation/scsi/ufs.txt | 36 +++++++++++++++++++++++++ drivers/scsi/ufs/ufshcd-ioctl.c | 58 +++++++++++++++++++++++++++++++++++++++++ include/scsi/scsi.h | 2 +- include/uapi/scsi/ufs/ioctl.h | 22 ++++++++++++++++ include/uapi/scsi/ufs/ufs.h | 2 ++ 5 files changed, 119 insertions(+), 1 deletion(-) diff --git a/Documentation/scsi/ufs.txt b/Documentation/scsi/ufs.txt index ed5768d..b8a4790 100644 --- a/Documentation/scsi/ufs.txt +++ b/Documentation/scsi/ufs.txt @@ -19,6 +19,7 @@ Contents 4.1 UFS Query IOCTL 4.2 UFS Auto-Hibern8 IOCTL 4.3 UFS Task Management IOCTL + 4.4 UFS DME Read IOCTL 1. Overview @@ -256,6 +257,41 @@ host and device using IOCTL interface. This one should be used with extreme care as it's more of a testing/vaidation interface. +4.4 UFS DME Read IOCTL + + This interface enables user to check link state of UFS Device. It's meant + mainly for test and troubleshooting purposes. You can use following + snippet to comunicate with this interface: + + #include + #include + #include + + static int handleDME(int fd, uint16_t attr_id, bool local_link, + uint32_t *response) + { + ufs_ioctl_dme_get_data dme_data; + int error; + + /* Attribute ID (max. 0x7fff) */ + dme_data.attr_id = attr_id; + + /* Local or Device part of link? */ + dme_data.peer = !local_link; + + /* [fd] used here shall be opened UFS device */ + error = ioctl(fd, UFS_IOCTL_DME, &dme_data); + + if (!error) + /* This will return DME specific response */ + *response = dme_data.response; + + return error; + } + + This is read-only interface, since we don't want to work-around driver + as these are link-level values and configurations managed strictly in driver. + UFS Specifications can be found at, UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf diff --git a/drivers/scsi/ufs/ufshcd-ioctl.c b/drivers/scsi/ufs/ufshcd-ioctl.c index afcb099..750ff9d 100644 --- a/drivers/scsi/ufs/ufshcd-ioctl.c +++ b/drivers/scsi/ufs/ufshcd-ioctl.c @@ -376,6 +376,58 @@ static int ufshcd_task_mgmt_ioctl(struct ufs_hba *hba, u8 lun, } /** + * ufshcd_dme_get_ioctl - provide read access to all UniPro and M-PHY attributes + * on the both local and peer side of the Link + * @hba: per-adapter instance + * @buffer: user space buffer for ufs_ioctl_dme_get_data structure + * + * Returns 0 for success or negative error code otherwise + * + * It will send the UIC DME_GET or DME_PEER_GET command to read the value of + * specified attribute and put the value in the response field. + */ +static int ufshcd_dme_get_ioctl(struct ufs_hba *hba, void __user *buffer) +{ + struct ufs_ioctl_dme_get_data *ioctl_data; + int err = 0; + + if (!buffer) + return -EINVAL; + + ioctl_data = kzalloc(sizeof(struct ufs_ioctl_dme_get_data), GFP_KERNEL); + if (!ioctl_data) { + err = -ENOMEM; + goto out; + } + + /* Extract params from user buffer */ + if (copy_from_user(ioctl_data, buffer, sizeof(*ioctl_data))) { + err = -EFAULT; + goto out_release_mem; + } + + err = ufshcd_dme_get_attr(hba, + UIC_ARG_MIB_SEL(ioctl_data->attr_id, ioctl_data->selector), + &ioctl_data->response, ioctl_data->peer); + + if (err) + goto out_release_mem; + + /* Copy response to user */ + if (copy_to_user(buffer, ioctl_data, sizeof(*ioctl_data))) + err = -EFAULT; + +out_release_mem: + kfree(ioctl_data); +out: + if (err) + dev_err(hba->dev, "User DME_GET request failed (error: %d)", + err); + + return err; +} + +/** * ufshcd_ioctl - ufs ioctl callback registered in scsi_host * @dev: scsi device required for per LUN queries * @cmd: command opcode @@ -385,6 +437,7 @@ static int ufshcd_task_mgmt_ioctl(struct ufs_hba *hba, u8 lun, * UFS_IOCTL_QUERY * UFS_IOCTL_AUTO_HIBERN8 * UFS_IOCTL_TASK_MANAGEMENT + * UFS_IOCTL_DME */ int ufshcd_ioctl(struct scsi_device *dev, int cmd, void __user *buffer) { @@ -411,6 +464,11 @@ int ufshcd_ioctl(struct scsi_device *dev, int cmd, void __user *buffer) ufshcd_scsi_to_upiu_lun(dev->lun), buffer); pm_runtime_put_sync(hba->dev); break; + case UFS_IOCTL_DME: + pm_runtime_get_sync(hba->dev); + err = ufshcd_dme_get_ioctl(hba, buffer); + pm_runtime_put_sync(hba->dev); + break; default: err = -EOPNOTSUPP; break; diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index b8e1006..74bdf3c 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -255,7 +255,7 @@ static inline int scsi_is_wlun(u64 lun) * Here are some scsi specific ioctl commands which are sometimes useful. * * Note that include/linux/cdrom.h also defines IOCTL 0x5300 - 0x5395 - * include/uapi/scsi/ufs/ioctl.h defines 0x53A0 - 0x53A2 + * include/uapi/scsi/ufs/ioctl.h defines 0x53A0 - 0x53A3 */ /* Used to obtain PUN and LUN info. Conflicts with CDROMAUDIOBUFSIZ */ diff --git a/include/uapi/scsi/ufs/ioctl.h b/include/uapi/scsi/ufs/ioctl.h index 6b7e876..2118c21 100644 --- a/include/uapi/scsi/ufs/ioctl.h +++ b/include/uapi/scsi/ufs/ioctl.h @@ -10,6 +10,7 @@ #define UFS_IOCTL_QUERY 0x53A0 #define UFS_IOCTL_AUTO_HIBERN8 0x53A1 #define UFS_IOCTL_TASK_MANAGEMENT 0x53A2 +#define UFS_IOCTL_DME 0x53A3 /** * struct ufs_ioctl_query_data - used to transfer data to and from user via @@ -107,4 +108,25 @@ struct ufs_ioctl_task_mgmt_data { __u8 response; }; +/** + * struct ufs_ioctl_dme_get_data - used to request information from a specific + * UniPro or M-PHY attribute + * + * @attr_id: attribute identifier (valid range: 0x0000 to 0x7FFF) + * @selector: selector on attribute ( shall be != 0 only for some attribiutes; + * please reffer UniPro documentation for details) + * @peer: indicate whether peer or local UniPro Link + * @response: variable where the kernel will put the attribute value read from + * the local or peer UniPro Link + * + * Submitted: attr_id, peer + * Received: response + */ +struct ufs_ioctl_dme_get_data { + __u16 attr_id; + __u16 selector; + bool peer; + __u32 response; +}; + #endif /* UAPI_UFS_IOCTL_H_ */ diff --git a/include/uapi/scsi/ufs/ufs.h b/include/uapi/scsi/ufs/ufs.h index 9f93c9a..dc17b65 100644 --- a/include/uapi/scsi/ufs/ufs.h +++ b/include/uapi/scsi/ufs/ufs.h @@ -76,4 +76,6 @@ enum { UFS_QUERY_TASK_SET = 0x81, }; +#define UFS_DME_MAX_ATTRIBUTE 0x7FFF + #endif /* UAPI_UFS_H_ */