From patchwork Mon Apr 25 21:23:48 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: dykmanj@linux.vnet.ibm.com X-Patchwork-Id: 92808 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9A479B6F19 for ; Tue, 26 Apr 2011 07:25:58 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755693Ab1DYVZt (ORCPT ); Mon, 25 Apr 2011 17:25:49 -0400 Received: from e37.co.us.ibm.com ([32.97.110.158]:49113 "EHLO e37.co.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754095Ab1DYVYX (ORCPT ); Mon, 25 Apr 2011 17:24:23 -0400 Received: from d03relay05.boulder.ibm.com (d03relay05.boulder.ibm.com [9.17.195.107]) by e37.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p3PLLXOf010342 for ; Mon, 25 Apr 2011 15:21:33 -0600 Received: from d03av05.boulder.ibm.com (d03av05.boulder.ibm.com [9.17.195.85]) by d03relay05.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p3PLOJ01355772 for ; Mon, 25 Apr 2011 15:24:19 -0600 Received: from d03av05.boulder.ibm.com (loopback [127.0.0.1]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p3PLOJeh032378 for ; Mon, 25 Apr 2011 15:24:19 -0600 Received: from c250f05gpfs06.ppd.pok.ibm.com (c250f05gpfs06.ppd.pok.ibm.com [9.114.87.187]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p3PLOCfL032060; Mon, 25 Apr 2011 15:24:18 -0600 From: dykmanj@linux.vnet.ibm.com To: netdev@vger.kernel.org Cc: Jim Dykman , Piyush Chaudhary , Fu-Chung Chang , " William S. Cadden" , " Wen C. Chen" , Scot Sakolish , Jian Xiao , " Carol L. Soto" , " Sarah J. Sheppard" Subject: [PATCH v4 08/27] HFI: DD request framework and first HFI DD request Date: Mon, 25 Apr 2011 17:23:48 -0400 Message-Id: <1303766647-30156-9-git-send-email-dykmanj@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.3.5 In-Reply-To: <1303766647-30156-1-git-send-email-dykmanj@linux.vnet.ibm.com> References: <1303766647-30156-1-git-send-email-dykmanj@linux.vnet.ibm.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jim Dykman We use an ioctl-ish mechanism similar to the one found in the HEA driver. Some of our requests have very large parameter lists, this method allows us to get the parms into the DD quickly. Signed-off-by: Piyush Chaudhary Signed-off-by: Jim Dykman Signed-off-by: Fu-Chung Chang Signed-off-by: William S. Cadden Signed-off-by: Wen C. Chen Signed-off-by: Scot Sakolish Signed-off-by: Jian Xiao Signed-off-by: Carol L. Soto Signed-off-by: Sarah J. Sheppard --- drivers/net/hfi/core/hfidd_init.c | 94 +++++++++++++++++++++++++++++++++++- include/linux/hfi/Kbuild | 1 + include/linux/hfi/hfidd_client.h | 40 +++++++++++++++ include/linux/hfi/hfidd_internal.h | 22 +++++++- include/linux/hfi/hfidd_requests.h | 38 ++++++++++++++ 5 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 include/linux/hfi/hfidd_requests.h diff --git a/drivers/net/hfi/core/hfidd_init.c b/drivers/net/hfi/core/hfidd_init.c index 3dcaa8f..df79ae9 100644 --- a/drivers/net/hfi/core/hfidd_init.c +++ b/drivers/net/hfi/core/hfidd_init.c @@ -36,6 +36,7 @@ #include #include +#include #include "hfidd_proto.h" MODULE_VERSION("1.0"); @@ -59,11 +60,102 @@ static ssize_t hfidd_read(struct file *filep, char *buf, size_t count, return 0; } +/* Query firmare level and use abi version to users */ +static int hfidd_query_dd_info(struct hfidd_acs *p_acs, + struct hfi_query_dd_info *user_p) +{ + struct hfi_query_dd_info req; + int rc; + + req.fw_ec_level = p_acs->dds.fw_ec_level; + req.abi_version = HFIDD_USER_ABI_VERSION; + + rc = copy_to_user(user_p, &req, sizeof(struct hfi_query_dd_info)); + if (rc) + dev_printk(KERN_ERR, p_acs->hfidd_dev, + "hfidd_query_dd_info: copy_to_user failed\n"); + + return rc; +} + /* Entry point for user space to do driver requests. */ static ssize_t hfidd_cmd_write(struct file *filep, const char __user *buf, size_t count, loff_t *pos) { - return 0; + struct hfidd_acs *p_acs; + int ai; + int cnt = 0; + int rc = 0; + struct hfi_req_hdr cmd; + int is_userspace; + + ai = iminor(filep->f_path.dentry->d_inode); + if (ai >= MAX_HFIS) { + printk(KERN_ERR "%s: hfidd_cmd_write: wrong ai = %d\n", + HFIDD_DEV_NAME, ai); + return -ENODEV; + } + + p_acs = hfidd_global.p_acs[ai]; + if (p_acs == NULL) { + printk(KERN_ERR "%s: hfidd_cmd_write: p_acs is NULL\n", + HFIDD_DEV_NAME); + return -EINVAL; + } + + if (count < sizeof(cmd)) { + dev_printk(KERN_ERR, p_acs->hfidd_dev, + "hfidd_cmd_write: Invalid count: 0x%lx expected " + "count: 0x%lx\n", count, sizeof(cmd)); + return -EINVAL; + } + + is_userspace = 1; + if (segment_eq(get_fs(), KERNEL_DS)) + is_userspace = 0; + + if (copy_from_user(&cmd, buf, sizeof(cmd))) { + dev_printk(KERN_ERR, p_acs->hfidd_dev, + "hfidd_cmd_write: copy_from_user failed\n"); + return -EINVAL; + } + + if (cmd.abi_version != HFIDD_USER_ABI_VERSION) { + dev_printk(KERN_ERR, p_acs->hfidd_dev, + "hfidd_cmd_write: wrong abi_version %d, " + "should be %d for cmd 0x%x\n", + cmd.abi_version, HFIDD_USER_ABI_VERSION, cmd.req); + return -EINVAL; + } + + switch (cmd.req) { + case HFIDD_REQ_QUERY_DD_INFO: + if (cmd.req_len != sizeof(struct hfi_query_dd_info)) { + dev_printk(KERN_ERR, p_acs->hfidd_dev, + "hfidd_cmd_write: hdr.reqlen 0x%x expected " + "0x%x for cmd req 0x%x\n", + cmd.req_len, (unsigned int) + sizeof(struct hfi_query_dd_info), cmd.req); + return -EINVAL; + } + rc = hfidd_query_dd_info(p_acs, (struct hfi_query_dd_info *) + cmd.result.use.kptr); + break; + + default: + dev_printk(KERN_ERR, p_acs->hfidd_dev, + "hfidd_cmd_write: invalid cmd = 0x%x\n", cmd.req); + return -EINVAL; + } + + if (rc == 0) + cnt = count; + else + cnt = rc; + + dev_printk(KERN_INFO, p_acs->hfidd_dev, + "hfidd_cmd_write: Exit cmd = 0x%x rc = 0x%x\n", cmd.req, rc); + return cnt; } static const struct file_operations hfidd_fops = { diff --git a/include/linux/hfi/Kbuild b/include/linux/hfi/Kbuild index 3a742ce..6637c65 100644 --- a/include/linux/hfi/Kbuild +++ b/include/linux/hfi/Kbuild @@ -1 +1,2 @@ header-y += hfidd_client.h +header-y += hfidd_requests.h diff --git a/include/linux/hfi/hfidd_client.h b/include/linux/hfi/hfidd_client.h index 2714a27..b2ebd01 100644 --- a/include/linux/hfi/hfidd_client.h +++ b/include/linux/hfi/hfidd_client.h @@ -33,11 +33,51 @@ #ifndef _HFIDD_CLIENT_H_ #define _HFIDD_CLIENT_H_ + +#define HFIDD_USER_ABI_VERSION 1 + + +/* + * New ioctls are not allowed. We will use write() calls to pass + * in an ioctl-looking request, with struct hfi_req_hdr giving the + * information we used to get from the ioctl() parameter list. The + * write() call will copy out the request structure to the buffer pointed + * to by result, which is probably the original request. + */ + +struct hfi_64b { + union { + unsigned long long allu; /* APPLICATION Long long + Unsigned 64 bit address + container */ + void *kptr; /* KERNEL Pointer 64 bit + container */ + } use; +}; + +/* Request header: first structure in each of the HFI DD requests */ +struct hfi_req_hdr { + unsigned int req; /* HFIDD_REQ_* */ + unsigned int req_len; /* length of req, in bytes */ + unsigned int abi_version; /* ABI version */ + struct hfi_64b result; /* user eaddr for output */ +}; +#define HFIDD_REQ_HDR_SIZE sizeof(struct hfi_req_hdr) + #define MAX_TORRENTS 1 #define MAX_HFI_PER_TORRENT 2 #define MAX_HFIS (MAX_TORRENTS * MAX_HFI_PER_TORRENT) #define MAX_WIN_PER_HFI 256 +/* + * HFIDD_REQ_QUERY_DD_INFO + */ +struct hfi_query_dd_info { + struct hfi_req_hdr hdr; + unsigned long long fw_ec_level; /* Hardware Version */ + unsigned int abi_version; /* ABI Version */ +}; + #define HFI_DYN_WINS_DEFAULT 32 #define PAGE_SIZE_4K 0x1000 diff --git a/include/linux/hfi/hfidd_internal.h b/include/linux/hfi/hfidd_internal.h index c7c67ca..65b8dc2 100644 --- a/include/linux/hfi/hfidd_internal.h +++ b/include/linux/hfi/hfidd_internal.h @@ -36,12 +36,28 @@ #include #include #include +#include +#include #include #include +#include +#include +#include +#include +#include #include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include diff --git a/include/linux/hfi/hfidd_requests.h b/include/linux/hfi/hfidd_requests.h new file mode 100644 index 0000000..b6e255f --- /dev/null +++ b/include/linux/hfi/hfidd_requests.h @@ -0,0 +1,38 @@ +/* + * hfidd_requests.h + * + * HFI device driver for IBM System p + * + * Authors: + * Fu-Chung Chang + * William S. Cadden + * Wen C. Chen + * Scot Sakolish + * Jian Xiao + * Carol L. Soto + * Sarah J. Sheppard + * + * (C) Copyright IBM Corp. 2010 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _HFIDD_REQUESTS_H_ +#define _HFIDD_REQUESTS_H_ + +#define HFIDD_REQ_QUERY_DD_INFO 0x00001004 + +#endif /* _HFIDD_REQUESTS_H_ */