ehca_main.c revision f4fd0b224d60044d2da5ca02f8f2b5150c1d8731
1fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick/*
2fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  IBM eServer eHCA Infiniband device driver for Linux on POWER
3fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
4fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  module start stop, hca detection
5fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
6fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  Authors: Heiko J Schick <schickhj@de.ibm.com>
7fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *           Joachim Fenkes <fenkes@de.ibm.com>
9fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
10fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  Copyright (c) 2005 IBM Corporation
11fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
12fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  All rights reserved.
13fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
14fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
15fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *  BSD.
16fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
17fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * OpenIB BSD License
18fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
19fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistribution and use in source and binary forms, with or without
20fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * modification, are permitted provided that the following conditions are met:
21fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
22fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions of source code must retain the above copyright notice, this
23fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * list of conditions and the following disclaimer.
24fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
25fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * Redistributions in binary form must reproduce the above copyright notice,
26fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * this list of conditions and the following disclaimer in the documentation
27fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * and/or other materials
28fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * provided with the distribution.
29fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick *
30fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
34fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
35fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
36fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
38fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
40fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick * POSSIBILITY OF SUCH DAMAGE.
41fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick */
42fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
437e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
447e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#include <linux/slab.h>
457e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
46fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_classes.h"
47fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_iverbs.h"
48fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_mrmw.h"
49fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "ehca_tools.h"
50fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#include "hcp_if.h"
51fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
52fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_LICENSE("Dual BSD/GPL");
53fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
54fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
5531726798bd8fbef6244b28cf962f4a4c45793deaHoang-Nam NguyenMODULE_VERSION("SVNEHCA_0022");
56fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
57fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_open_aqp1     = 0;
58fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_debug_level   = 0;
59fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_hw_level      = 0;
60fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_nr_ports      = 2;
61fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_use_hp_mr     = 0;
62fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_port_act_time = 30;
63fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_poll_all_eqs  = 1;
64fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_static_rate   = -1;
654fd3006032446be2b331dd482e34c6a9e644a5b8Hoang-Nam Nguyenint ehca_scaling_code  = 1;
66fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
67fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(open_aqp1,     ehca_open_aqp1,     int, 0);
68fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(debug_level,   ehca_debug_level,   int, 0);
69fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(hw_level,      ehca_hw_level,      int, 0);
70fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(nr_ports,      ehca_nr_ports,      int, 0);
71fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(use_hp_mr,     ehca_use_hp_mr,     int, 0);
72fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(port_act_time, ehca_port_act_time, int, 0);
73fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(poll_all_eqs,  ehca_poll_all_eqs,  int, 0);
74fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_param_named(static_rate,   ehca_static_rate,   int, 0);
754fd3006032446be2b331dd482e34c6a9e644a5b8Hoang-Nam Nguyenmodule_param_named(scaling_code,   ehca_scaling_code,   int, 0);
76fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
77fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(open_aqp1,
78fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "AQP1 on startup (0: no (default), 1: yes)");
79fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(debug_level,
80fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "debug level"
81fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 " (0: no debug traces (default), 1: with debug traces)");
82fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(hw_level,
83fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "hardware level"
84fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 " (0: autosensing (default), 1: v. 0.20, 2: v. 0.21)");
85fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(nr_ports,
86fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "number of connected ports (default: 2)");
87fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(use_hp_mr,
88fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "high performance MRs (0: no (default), 1: yes)");
89fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(port_act_time,
90fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "time to wait for port activation (default: 30 sec)");
91fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(poll_all_eqs,
92fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "polls all event queues periodically"
93fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 " (0: no, 1: yes (default))");
94fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickMODULE_PARM_DESC(static_rate,
95fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		 "set permanent static rate (default: disabled)");
964fd3006032446be2b331dd482e34c6a9e644a5b8Hoang-Nam NguyenMODULE_PARM_DESC(scaling_code,
974fd3006032446be2b331dd482e34c6a9e644a5b8Hoang-Nam Nguyen		 "set scaling code (0: disabled, 1: enabled/default)");
98fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
99fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickspinlock_t ehca_qp_idr_lock;
100fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickspinlock_t ehca_cq_idr_lock;
101fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickDEFINE_IDR(ehca_qp_idr);
102fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickDEFINE_IDR(ehca_cq_idr);
103fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1047e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
105fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct list_head shca_list; /* list of all registered ehcas */
106fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic spinlock_t shca_list_lock;
107fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
108fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct timer_list poll_eqs_timer;
109fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1107e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
1117e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyenstatic struct kmem_cache *ctblk_cache = NULL;
1127e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
113f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyenvoid *ehca_alloc_fw_ctrlblock(gfp_t flags)
1147e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen{
115f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	void *ret = kmem_cache_zalloc(ctblk_cache, flags);
1167e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (!ret)
1177e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_gen_err("Out of memory for ctblk");
1187e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	return ret;
1197e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen}
1207e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
1217e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyenvoid ehca_free_fw_ctrlblock(void *ptr)
1227e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen{
1237e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (ptr)
1247e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		kmem_cache_free(ctblk_cache, ptr);
1257e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
1267e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen}
1277e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
1287e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen
129fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int ehca_create_slab_caches(void)
130fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
131fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
132fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
133fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_pd_cache();
134fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
135fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create PD SLAB cache.");
136fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
137fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
138fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
139fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_cq_cache();
140fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
141fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create CQ SLAB cache.");
142fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches2;
143fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
144fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
145fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_qp_cache();
146fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
147fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create QP SLAB cache.");
148fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches3;
149fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
150fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
151fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_av_cache();
152fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
153fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create AV SLAB cache.");
154fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches4;
155fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
156fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
157fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_init_mrmw_cache();
158fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
159fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create MR&MW SLAB cache.");
160fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_slab_caches5;
161fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
162fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
1637e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
1647e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ctblk_cache = kmem_cache_create("ehca_cache_ctblk",
1657e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen					EHCA_PAGESIZE, H_CB_ALIGNMENT,
1667e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen					SLAB_HWCACHE_ALIGN,
1677e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen					NULL, NULL);
1687e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (!ctblk_cache) {
1697e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_gen_err("Cannot create ctblk SLAB cache.");
1707e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_cleanup_mrmw_cache();
1717e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		goto create_slab_caches5;
1727e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	}
1737e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
174fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
175fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
176fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches5:
177fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_av_cache();
178fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
179fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches4:
180fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_qp_cache();
181fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
182fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches3:
183fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_cq_cache();
184fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
185fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_slab_caches2:
186fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_pd_cache();
187fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
188fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
189fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
190fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
191fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic void ehca_destroy_slab_caches(void)
192fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
193fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_mrmw_cache();
194fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_av_cache();
195fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_qp_cache();
196fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_cq_cache();
197fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_cleanup_pd_cache();
1987e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#ifdef CONFIG_PPC_64K_PAGES
1997e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	if (ctblk_cache)
2007e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		kmem_cache_destroy(ctblk_cache);
2017e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen#endif
202fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
203fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
204fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#define EHCA_HCAAVER  EHCA_BMASK_IBM(32,39)
205fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#define EHCA_REVID    EHCA_BMASK_IBM(40,63)
206fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
207fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint ehca_sense_attributes(struct ehca_shca *shca)
208fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
209fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret = 0;
210fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	u64 h_ret;
211fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct hipz_query_hca *rblock;
212fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
213f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
214fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!rblock) {
215fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot allocate rblock memory.");
216fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENOMEM;
217fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
218fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
219fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	h_ret = hipz_h_query_hca(shca->ipz_hca_handle, rblock);
220fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (h_ret != H_SUCCESS) {
221fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot query device properties. h_ret=%lx",
222fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			     h_ret);
223fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EPERM;
224fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto num_ports1;
225fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
226fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
227fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_nr_ports == 1)
228fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->num_ports = 1;
229fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	else
230fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->num_ports = (u8)rblock->num_ports;
231fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
232fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_gen_dbg(" ... found %x ports", rblock->num_ports);
233fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
234fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_hw_level == 0) {
235fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		u32 hcaaver;
236fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		u32 revid;
237fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
238fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		hcaaver = EHCA_BMASK_GET(EHCA_HCAAVER, rblock->hw_ver);
239fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		revid   = EHCA_BMASK_GET(EHCA_REVID, rblock->hw_ver);
240fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
241fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_dbg(" ... hardware version=%x:%x", hcaaver, revid);
242fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
243fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		if ((hcaaver == 1) && (revid == 0))
244fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			shca->hw_level = 0;
245fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		else if ((hcaaver == 1) && (revid == 1))
246fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			shca->hw_level = 1;
247fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		else if ((hcaaver == 1) && (revid == 2))
248fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			shca->hw_level = 2;
249fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
250fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_gen_dbg(" ... hardware level=%x", shca->hw_level);
251fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
252fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->sport[0].rate = IB_RATE_30_GBPS;
253fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->sport[1].rate = IB_RATE_30_GBPS;
254fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
255fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schicknum_ports1:
2567e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ehca_free_fw_ctrlblock(rblock);
257fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
258fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
259fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
260fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int init_node_guid(struct ehca_shca *shca)
261fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
262fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret = 0;
263fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct hipz_query_hca *rblock;
264fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
265f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);
266fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!rblock) {
267fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
268fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENOMEM;
269fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
270fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
271fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) {
272fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Can't query device properties");
273fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EINVAL;
274fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto init_node_guid1;
275fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
276fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
277fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	memcpy(&shca->ib_device.node_guid, &rblock->node_guid, sizeof(u64));
278fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
279fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickinit_node_guid1:
2807e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ehca_free_fw_ctrlblock(rblock);
281fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
282fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
283fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
2840f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyenint ehca_init_device(struct ehca_shca *shca)
285fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
286fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
287fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
288fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = init_node_guid(shca);
289fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
290fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
291fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
292fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	strlcpy(shca->ib_device.name, "ehca%d", IB_DEVICE_NAME_MAX);
293fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.owner               = THIS_MODULE;
294fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
2954c34bdf58c0a3b305ebd9b5e74011ca1fd6d964dHoang-Nam Nguyen	shca->ib_device.uverbs_abi_ver	    = 6;
296fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.uverbs_cmd_mask	    =
297fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_GET_CONTEXT)		|
298fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_QUERY_DEVICE)	|
299fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_QUERY_PORT)		|
300fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_ALLOC_PD)		|
301fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DEALLOC_PD)		|
302fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_REG_MR)		|
303fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DEREG_MR)		|
304fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL)	|
305fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_CREATE_CQ)		|
306fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DESTROY_CQ)		|
307fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_CREATE_QP)		|
308fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_MODIFY_QP)		|
309fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_QUERY_QP)		|
310fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DESTROY_QP)		|
311fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_ATTACH_MCAST)	|
312fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		(1ull << IB_USER_VERBS_CMD_DETACH_MCAST);
313fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
31407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	shca->ib_device.node_type           = RDMA_NODE_IB_CA;
315fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.phys_port_cnt       = shca->num_ports;
316f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin	shca->ib_device.num_comp_vectors    = 1;
317fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dma_device          = &shca->ibmebus_dev->ofdev.dev;
318fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_device        = ehca_query_device;
319fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_port          = ehca_query_port;
320fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_gid           = ehca_query_gid;
321fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_pkey          = ehca_query_pkey;
322fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->in_device.modify_device    = ehca_modify_device    */
323fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.modify_port         = ehca_modify_port;
324fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_ucontext      = ehca_alloc_ucontext;
325fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_ucontext    = ehca_dealloc_ucontext;
326fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_pd            = ehca_alloc_pd;
327fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_pd          = ehca_dealloc_pd;
328fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.create_ah	    = ehca_create_ah;
329fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.modify_ah	    = ehca_modify_ah;	    */
330fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_ah	    = ehca_query_ah;
331fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.destroy_ah	    = ehca_destroy_ah;
332fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.create_qp	    = ehca_create_qp;
333fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.modify_qp	    = ehca_modify_qp;
334fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_qp	    = ehca_query_qp;
335fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.destroy_qp	    = ehca_destroy_qp;
336fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.post_send	    = ehca_post_send;
337fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.post_recv	    = ehca_post_recv;
338fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.create_cq	    = ehca_create_cq;
339fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.destroy_cq	    = ehca_destroy_cq;
340fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.resize_cq	    = ehca_resize_cq;
341fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.poll_cq		    = ehca_poll_cq;
342fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.peek_cq	    = ehca_peek_cq;	    */
343fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.req_notify_cq	    = ehca_req_notify_cq;
344fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.req_ncomp_notif  = ehca_req_ncomp_notif; */
345fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.get_dma_mr	    = ehca_get_dma_mr;
346fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.reg_phys_mr	    = ehca_reg_phys_mr;
347fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.reg_user_mr	    = ehca_reg_user_mr;
348fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.query_mr	    = ehca_query_mr;
349fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dereg_mr	    = ehca_dereg_mr;
350fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.rereg_phys_mr	    = ehca_rereg_phys_mr;
351fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_mw	    = ehca_alloc_mw;
352fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.bind_mw		    = ehca_bind_mw;
353fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_mw	    = ehca_dealloc_mw;
354fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.alloc_fmr	    = ehca_alloc_fmr;
355fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.map_phys_fmr	    = ehca_map_phys_fmr;
356fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.unmap_fmr	    = ehca_unmap_fmr;
357fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.dealloc_fmr	    = ehca_dealloc_fmr;
358fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.attach_mcast	    = ehca_attach_mcast;
359fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.detach_mcast	    = ehca_detach_mcast;
360fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* shca->ib_device.process_mad	    = ehca_process_mad;	    */
361fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ib_device.mmap		    = ehca_mmap;
362fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
363fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
364fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
365fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
366fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int ehca_create_aqp1(struct ehca_shca *shca, u32 port)
367fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
368fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_sport *sport = &shca->sport[port - 1];
369fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_cq *ibcq;
370fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_qp *ibqp;
371fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_qp_init_attr qp_init_attr;
372fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
373fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
374fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (sport->ibcq_aqp1) {
375fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "AQP1 CQ is already created.");
376fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -EPERM;
377fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
378fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
379f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin	ibcq = ib_create_cq(&shca->ib_device, NULL, NULL, (void*)(-1), 10, 0);
380fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (IS_ERR(ibcq)) {
381fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create AQP1 CQ.");
382fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return PTR_ERR(ibcq);
383fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
384fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	sport->ibcq_aqp1 = ibcq;
385fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
386fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (sport->ibqp_aqp1) {
387fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "AQP1 QP is already created.");
388fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EPERM;
389fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_aqp1;
390fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
391fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
392fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	memset(&qp_init_attr, 0, sizeof(struct ib_qp_init_attr));
393fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.send_cq          = ibcq;
394fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.recv_cq          = ibcq;
395fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.sq_sig_type      = IB_SIGNAL_ALL_WR;
396fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_send_wr  = 100;
397fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_recv_wr  = 100;
398fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_send_sge = 2;
399fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.cap.max_recv_sge = 1;
400fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.qp_type          = IB_QPT_GSI;
401fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.port_num         = port;
402fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.qp_context       = NULL;
403fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.event_handler    = NULL;
404fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	qp_init_attr.srq              = NULL;
405fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
406fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ibqp = ib_create_qp(&shca->pd->ib_pd, &qp_init_attr);
407fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (IS_ERR(ibqp)) {
408fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create AQP1 QP.");
409fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = PTR_ERR(ibqp);
410fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto create_aqp1;
411fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
412fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	sport->ibqp_aqp1 = ibqp;
413fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
414fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
415fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
416fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickcreate_aqp1:
417fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_destroy_cq(sport->ibcq_aqp1);
418fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
419fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
420fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
421fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int ehca_destroy_aqp1(struct ehca_sport *sport)
422fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
423fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
424fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
425fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ib_destroy_qp(sport->ibqp_aqp1);
426fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
427fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot destroy AQP1 QP. ret=%x", ret);
428fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
429fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
430fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
431fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ib_destroy_cq(sport->ibcq_aqp1);
432fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
433fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot destroy AQP1 CQ. ret=%x", ret);
434fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
435fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
436fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
437fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
438fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf)
439fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
44078d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen	return snprintf(buf, PAGE_SIZE, "%d\n",
44178d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			ehca_debug_level);
442fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
443fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
444fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t ehca_store_debug_level(struct device_driver *ddp,
445fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				      const char *buf, size_t count)
446fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
447fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int value = (*buf) - '0';
448fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (value >= 0 && value <= 9)
449fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_debug_level = value;
450fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 1;
451fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
452fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
453fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickDRIVER_ATTR(debug_level, S_IRUSR | S_IWUSR,
454fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	    ehca_show_debug_level, ehca_store_debug_level);
455fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
456fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_create_driver_sysfs(struct ibmebus_driver *drv)
457fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
458fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	driver_create_file(&drv->driver, &driver_attr_debug_level);
459fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
460fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
461fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_remove_driver_sysfs(struct ibmebus_driver *drv)
462fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
463fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	driver_remove_file(&drv->driver, &driver_attr_debug_level);
464fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
465fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
466fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick#define EHCA_RESOURCE_ATTR(name)                                           \
467fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t  ehca_show_##name(struct device *dev,                       \
468fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 struct device_attribute *attr,            \
469fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 char *buf)                                \
470fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{									   \
471fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca;						   \
472fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct hipz_query_hca *rblock;				           \
473fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int data;                                                          \
474fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
475fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca = dev->driver_data;					   \
476fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
477f2d9136133de257abbd97fec6f624d3a73d1e1fdHoang-Nam Nguyen	rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL);			   \
478fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!rblock) {						           \
479fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		dev_err(dev, "Can't allocate rblock memory.");		   \
480fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return 0;						   \
481fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}								   \
482fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
483fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \
484fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		dev_err(dev, "Can't query device properties");	   	   \
4857e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen		ehca_free_fw_ctrlblock(rblock);			   	   \
486fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return 0;					   	   \
487fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}								   \
488fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
489fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	data = rblock->name;                                               \
4907e28db5d8ff63b1cabc221c5cb84a5f45752f1c2Hoang-Nam Nguyen	ehca_free_fw_ctrlblock(rblock);                                    \
491fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
492fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((strcmp(#name, "num_ports") == 0) && (ehca_nr_ports == 1))	   \
493fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return snprintf(buf, 256, "1\n");			   \
494fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	else								   \
495fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return snprintf(buf, 256, "%d\n", data);		   \
496fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick									   \
497fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}									   \
498fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic DEVICE_ATTR(name, S_IRUGO, ehca_show_##name, NULL);
499fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
500fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(num_ports);
501fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(hw_ver);
502fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_eq);
503fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_eq);
504fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_cq);
505fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_cq);
506fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_qp);
507fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_qp);
508fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_mr);
509fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_mr);
510fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_mw);
511fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(cur_mw);
512fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_pd);
513fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J SchickEHCA_RESOURCE_ATTR(max_ah);
514fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
515fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic ssize_t ehca_show_adapter_handle(struct device *dev,
516fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					struct device_attribute *attr,
517fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					char *buf)
518fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
519fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca = dev->driver_data;
520fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
521fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return sprintf(buf, "%lx\n", shca->ipz_hca_handle.handle);
522fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
523fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
524fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic DEVICE_ATTR(adapter_handle, S_IRUGO, ehca_show_adapter_handle, NULL);
525fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
526fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
527fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_create_device_sysfs(struct ibmebus_dev *dev)
528fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
529fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_adapter_handle);
530fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_num_ports);
531fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_hw_ver);
532fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_eq);
533fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_cur_eq);
534fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_cq);
535fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_cur_cq);
536fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_qp);
537fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_cur_qp);
538fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_mr);
539fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_cur_mr);
540fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_mw);
541fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_cur_mw);
542fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_pd);
543fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_create_file(&dev->ofdev.dev, &dev_attr_max_ah);
544fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
545fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
546fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_remove_device_sysfs(struct ibmebus_dev *dev)
547fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
548fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_adapter_handle);
549fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_num_ports);
550fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_hw_ver);
551fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_eq);
552fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_cur_eq);
553fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_cq);
554fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_cur_cq);
555fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_qp);
556fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_cur_qp);
557fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_mr);
558fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mr);
559fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_mw);
560fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_cur_mw);
561fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_pd);
562fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	device_remove_file(&dev->ofdev.dev, &dev_attr_max_ah);
563fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
564fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
565fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int __devinit ehca_probe(struct ibmebus_dev *dev,
566fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				const struct of_device_id *id)
567fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
568fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca;
569fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	u64 *handle;
570fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ib_pd *ibpd;
571fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
572fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
573fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	handle = (u64 *)get_property(dev->ofdev.node, "ibm,hca-handle", NULL);
574fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!handle) {
575fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot get eHCA handle for adapter: %s.",
576fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			     dev->ofdev.node->full_name);
577fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENODEV;
578fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
579fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
580fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!(*handle)) {
581fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Wrong eHCA handle for adapter: %s.",
582fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			     dev->ofdev.node->full_name);
583fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENODEV;
584fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
585fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
586fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca = (struct ehca_shca *)ib_alloc_device(sizeof(*shca));
587fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (!shca) {
588fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot allocate shca memory.");
589fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return -ENOMEM;
590fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
591c4ed790dfd4b2182c76e0fcd79d4aa85ab02eccfJoachim Fenkes	mutex_init(&shca->modify_mutex);
592fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
593fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ibmebus_dev = dev;
594fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->ipz_hca_handle.handle = *handle;
595fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	dev->ofdev.dev.driver_data = shca;
596fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
597fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_sense_attributes(shca);
598fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret < 0) {
599fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot sense eHCA attributes.");
600fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe1;
601fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
602fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
6030f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	ret = ehca_init_device(shca);
604fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
6050f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		ehca_gen_err("Cannot init ehca  device struct");
606fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe1;
607fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
608fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
609fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create event queues */
610fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
611fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
612fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create EQ.");
6130f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		goto probe1;
614fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
615fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
616fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
617fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
618fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create NEQ.");
619fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe3;
620fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
621fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
622fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create internal protection domain */
623fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ibpd = ehca_alloc_pd(&shca->ib_device, (void*)(-1), NULL);
624fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (IS_ERR(ibpd)) {
625fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create internal PD.");
626fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = PTR_ERR(ibpd);
627fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe4;
628fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
629fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
630fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->pd = container_of(ibpd, struct ehca_pd, ib_pd);
631fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	shca->pd->ib_pd.device = &shca->ib_device;
632fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
633fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create internal max MR */
634fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_reg_internal_maxmr(shca, shca->pd, &shca->maxmr);
635fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
636fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret) {
637fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot create internal MR ret=%x",
638fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 ret);
639fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto probe5;
640fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
641fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
6420f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	ret = ib_register_device(&shca->ib_device);
6430f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	if (ret) {
6440f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		ehca_err(&shca->ib_device,
6450f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen			 "ib_register_device() failed ret=%x", ret);
6460f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen		goto probe6;
6470f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	}
6480f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen
649fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create AQP1 for port 1 */
650fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_open_aqp1 == 1) {
651fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->sport[0].port_state = IB_PORT_DOWN;
652fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = ehca_create_aqp1(shca, 1);
653fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		if (ret) {
654fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			ehca_err(&shca->ib_device,
655fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 "Cannot create AQP1 for port 1.");
6560f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen			goto probe7;
657fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		}
658fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
659fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
660fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	/* create AQP1 for port 2 */
661fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((ehca_open_aqp1 == 1) && (shca->num_ports == 2)) {
662fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		shca->sport[1].port_state = IB_PORT_DOWN;
663fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = ehca_create_aqp1(shca, 2);
664fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		if (ret) {
665fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			ehca_err(&shca->ib_device,
666fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				 "Cannot create AQP1 for port 2.");
6670f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen			goto probe8;
668fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		}
669fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
670fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
671fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_create_device_sysfs(dev);
672fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
673fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock(&shca_list_lock);
674fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	list_add(&shca->shca_list, &shca_list);
675fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_unlock(&shca_list_lock);
676fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
677fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
678fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
6790f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyenprobe8:
680fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_aqp1(&shca->sport[0]);
681fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
682fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
683fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy AQP1 for port 1. ret=%x", ret);
684fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
6850f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyenprobe7:
6860f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen	ib_unregister_device(&shca->ib_device);
6870f248d9cde673a481eb3182909b54d07e9d58f72Hoang-Nam Nguyen
688fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe6:
689fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dereg_internal_maxmr(shca);
690fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
691fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
692fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy internal MR. ret=%x", ret);
693fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
694fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe5:
695fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dealloc_pd(&shca->pd->ib_pd);
696fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
697fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
698fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy internal PD. ret=%x", ret);
699fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
700fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe4:
701fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->neq);
702fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
703fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
704fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy NEQ. ret=%x", ret);
705fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
706fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe3:
707fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->eq);
708fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
709fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
710fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy EQ. ret=%x", ret);
711fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
712fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickprobe1:
713fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_dealloc_device(&shca->ib_device);
714fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
715fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return -EINVAL;
716fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
717fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
718fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic int __devexit ehca_remove(struct ibmebus_dev *dev)
719fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
720fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca = dev->ofdev.dev.driver_data;
721fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
722fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
723fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_remove_device_sysfs(dev);
724fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
725fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_open_aqp1 == 1) {
726fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		int i;
727fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		for (i = 0; i < shca->num_ports; i++) {
728fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			ret = ehca_destroy_aqp1(&shca->sport[i]);
729fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			if (ret)
730fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick				ehca_err(&shca->ib_device,
731fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					 "Cannot destroy AQP1 for port %x "
732fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick					 "ret=%x", ret, i);
733fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		}
734fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
735fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
736fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_unregister_device(&shca->ib_device);
737fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
738fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dereg_internal_maxmr(shca);
739fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
740fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
741fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy internal MR. ret=%x", ret);
742fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
743fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_dealloc_pd(&shca->pd->ib_pd);
744fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
745fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device,
746fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick			 "Cannot destroy internal PD. ret=%x", ret);
747fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
748fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->eq);
749fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
750fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Cannot destroy EQ. ret=%x", ret);
751fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
752fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ret = ehca_destroy_eq(shca, &shca->neq);
753fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ret)
754fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_err(&shca->ib_device, "Canot destroy NEQ. ret=%x", ret);
755fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
756fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ib_dealloc_device(&shca->ib_device);
757fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
758fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock(&shca_list_lock);
759fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	list_del(&shca->shca_list);
760fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_unlock(&shca_list_lock);
761fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
762fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
763fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
764fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
765fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct of_device_id ehca_device_table[] =
766fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
767fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	{
768fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		.name       = "lhca",
769fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		.compatible = "IBM,lhca",
770fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	},
771fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	{},
772fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
773fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
774fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickstatic struct ibmebus_driver ehca_driver = {
775fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	.name     = "ehca",
776fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	.id_table = ehca_device_table,
777fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	.probe    = ehca_probe,
778fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	.remove   = ehca_remove,
779fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
780fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
781fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid ehca_poll_eqs(unsigned long data)
782fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
783fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	struct ehca_shca *shca;
784fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
785fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock(&shca_list_lock);
786fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	list_for_each_entry(shca, &shca_list, shca_list) {
78778d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen		if (shca->eq.is_initialized) {
78878d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			/* call deadman proc only if eq ptr does not change */
78978d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			struct ehca_eq *eq = &shca->eq;
79078d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			int max = 3;
79178d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			volatile u64 q_ofs, q_ofs2;
79278d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			u64 flags;
79378d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			spin_lock_irqsave(&eq->spinlock, flags);
79478d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			q_ofs = eq->ipz_queue.current_q_offset;
79578d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			spin_unlock_irqrestore(&eq->spinlock, flags);
79678d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			do {
79778d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				spin_lock_irqsave(&eq->spinlock, flags);
79878d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				q_ofs2 = eq->ipz_queue.current_q_offset;
79978d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				spin_unlock_irqrestore(&eq->spinlock, flags);
80078d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				max--;
80178d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			} while (q_ofs == q_ofs2 && max > 0);
80278d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen			if (q_ofs == q_ofs2)
80378d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen				ehca_process_eq(shca, 0);
80478d8d5f9ef8d6179e92b94481cfdfc45d396992fHoang-Nam Nguyen		}
805fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
806fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	mod_timer(&poll_eqs_timer, jiffies + HZ);
807fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_unlock(&shca_list_lock);
808fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick}
809fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
810fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickint __init ehca_module_init(void)
811fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
812fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	int ret;
813fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
814fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	printk(KERN_INFO "eHCA Infiniband Device Driver "
81531726798bd8fbef6244b28cf962f4a4c45793deaHoang-Nam Nguyen	       "(Rel.: SVNEHCA_0022)\n");
816fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	idr_init(&ehca_qp_idr);
817fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	idr_init(&ehca_cq_idr);
818fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock_init(&ehca_qp_idr_lock);
819fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock_init(&ehca_cq_idr_lock);
820fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
821fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	INIT_LIST_HEAD(&shca_list);
822fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	spin_lock_init(&shca_list_lock);
823fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
824fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((ret = ehca_create_comp_pool())) {
825fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create comp pool.");
826fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		return ret;
827fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
828fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
829fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((ret = ehca_create_slab_caches())) {
830fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot create SLAB caches");
831fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -ENOMEM;
832fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto module_init1;
833fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
834fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
835fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if ((ret = ibmebus_register_driver(&ehca_driver))) {
836fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("Cannot register eHCA device driver");
837fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ret = -EINVAL;
838fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		goto module_init2;
839fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
840fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
841fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_create_driver_sysfs(&ehca_driver);
842fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
843fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_poll_all_eqs != 1) {
844fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("WARNING!!!");
845fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		ehca_gen_err("It is possible to lose interrupts.");
846fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	} else {
847fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		init_timer(&poll_eqs_timer);
848fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		poll_eqs_timer.function = ehca_poll_eqs;
849fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		poll_eqs_timer.expires = jiffies + HZ;
850fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		add_timer(&poll_eqs_timer);
851fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	}
852fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
853fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return 0;
854fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
855fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_init2:
856fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_slab_caches();
857fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
858fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_init1:
859fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_comp_pool();
860fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	return ret;
861fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
862fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
863fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickvoid __exit ehca_module_exit(void)
864fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick{
865fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	if (ehca_poll_all_eqs == 1)
866fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick		del_timer_sync(&poll_eqs_timer);
867fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
868fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_remove_driver_sysfs(&ehca_driver);
869fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ibmebus_unregister_driver(&ehca_driver);
870fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
871fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_slab_caches();
872fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
873fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	ehca_destroy_comp_pool();
874fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
875fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	idr_destroy(&ehca_cq_idr);
876fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick	idr_destroy(&ehca_qp_idr);
877fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick};
878fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schick
879fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_init(ehca_module_init);
880fab97220c9e409a98b1956ba677ddd2dd43b0b95Heiko J Schickmodule_exit(ehca_module_exit);
881