From patchwork Wed Mar 2 21:09:54 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: 85144 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 3AD3E1007D6 for ; Thu, 3 Mar 2011 08:11:00 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757591Ab1CBVKg (ORCPT ); Wed, 2 Mar 2011 16:10:36 -0500 Received: from e7.ny.us.ibm.com ([32.97.182.137]:51907 "EHLO e7.ny.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757569Ab1CBVKa (ORCPT ); Wed, 2 Mar 2011 16:10:30 -0500 Received: from d01dlp02.pok.ibm.com (d01dlp02.pok.ibm.com [9.56.224.85]) by e7.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p22Ko1BE031673 for ; Wed, 2 Mar 2011 15:50:01 -0500 Received: from d01relay07.pok.ibm.com (d01relay07.pok.ibm.com [9.56.227.147]) by d01dlp02.pok.ibm.com (Postfix) with ESMTP id 4A1BD6E8036 for ; Wed, 2 Mar 2011 16:10:29 -0500 (EST) Received: from d01av04.pok.ibm.com (d01av04.pok.ibm.com [9.56.224.64]) by d01relay07.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p22LAOb92797730 for ; Wed, 2 Mar 2011 16:10:24 -0500 Received: from d01av04.pok.ibm.com (loopback [127.0.0.1]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p22LANwi031999 for ; Wed, 2 Mar 2011 16:10:23 -0500 Received: from c250f05gpfs06.ppd.pok.ibm.com (c250f05gpfs06.ppd.pok.ibm.com [9.114.87.187]) by d01av04.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p22LAMtI031892; Wed, 2 Mar 2011 16:10:23 -0500 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 08/27] HFI: DD request framework and first HFI DD request Date: Wed, 2 Mar 2011 16:09:54 -0500 Message-Id: <1299100213-8770-8-git-send-email-dykmanj@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.3.5 In-Reply-To: <1299100213-8770-1-git-send-email-dykmanj@linux.vnet.ibm.com> References: <1299100213-8770-1-git-send-email-dykmanj@linux.vnet.ibm.com> To: netdev@vger.kernel.org X-Content-Scanned: Fidelis XPS MAILER 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 | 23 ++++++++- include/linux/hfi/hfidd_requests.h | 38 ++++++++++++++ 5 files changed, 192 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 448349d..a57f247 100644 --- a/drivers/net/hfi/core/hfidd_init.c +++ b/drivers/net/hfi/core/hfidd_init.c @@ -37,6 +37,7 @@ #include #include +#include #include "hfidd_proto.h" MODULE_VERSION("1.0"); @@ -60,11 +61,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 8fe313d..311f906 100644 --- a/include/linux/hfi/hfidd_internal.h +++ b/include/linux/hfi/hfidd_internal.h @@ -36,12 +36,29 @@ #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 #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_ */