• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  IBM eServer eHCA Infiniband device driver for Linux on POWER
3  *
4  *  Firmware Infiniband Interface code for POWER
5  *
6  *  Authors: Christoph Raisch <raisch@de.ibm.com>
7  *           Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8  *           Joachim Fenkes <fenkes@de.ibm.com>
9  *           Gerd Bayer <gerd.bayer@de.ibm.com>
10  *           Waleri Fomin <fomin@de.ibm.com>
11  *
12  *  Copyright (c) 2005 IBM Corporation
13  *
14  *  All rights reserved.
15  *
16  *  This source code is distributed under a dual license of GPL v2.0 and OpenIB
17  *  BSD.
18  *
19  * OpenIB BSD License
20  *
21  * Redistribution and use in source and binary forms, with or without
22  * modification, are permitted provided that the following conditions are met:
23  *
24  * Redistributions of source code must retain the above copyright notice, this
25  * list of conditions and the following disclaimer.
26  *
27  * Redistributions in binary form must reproduce the above copyright notice,
28  * this list of conditions and the following disclaimer in the documentation
29  * and/or other materials
30  * provided with the distribution.
31  *
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
36  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
40  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGE.
43  */
44 
45 #include <asm/hvcall.h>
46 #include "ehca_tools.h"
47 #include "hcp_if.h"
48 #include "hcp_phyp.h"
49 #include "hipz_fns.h"
50 #include "ipz_pt_fn.h"
51 
52 #define H_ALL_RES_QP_ENHANCED_OPS       EHCA_BMASK_IBM(9, 11)
53 #define H_ALL_RES_QP_PTE_PIN            EHCA_BMASK_IBM(12, 12)
54 #define H_ALL_RES_QP_SERVICE_TYPE       EHCA_BMASK_IBM(13, 15)
55 #define H_ALL_RES_QP_STORAGE            EHCA_BMASK_IBM(16, 17)
56 #define H_ALL_RES_QP_LL_RQ_CQE_POSTING  EHCA_BMASK_IBM(18, 18)
57 #define H_ALL_RES_QP_LL_SQ_CQE_POSTING  EHCA_BMASK_IBM(19, 21)
58 #define H_ALL_RES_QP_SIGNALING_TYPE     EHCA_BMASK_IBM(22, 23)
59 #define H_ALL_RES_QP_UD_AV_LKEY_CTRL    EHCA_BMASK_IBM(31, 31)
60 #define H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE EHCA_BMASK_IBM(32, 35)
61 #define H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE EHCA_BMASK_IBM(36, 39)
62 #define H_ALL_RES_QP_RESOURCE_TYPE      EHCA_BMASK_IBM(56, 63)
63 
64 #define H_ALL_RES_QP_MAX_OUTST_SEND_WR  EHCA_BMASK_IBM(0, 15)
65 #define H_ALL_RES_QP_MAX_OUTST_RECV_WR  EHCA_BMASK_IBM(16, 31)
66 #define H_ALL_RES_QP_MAX_SEND_SGE       EHCA_BMASK_IBM(32, 39)
67 #define H_ALL_RES_QP_MAX_RECV_SGE       EHCA_BMASK_IBM(40, 47)
68 
69 #define H_ALL_RES_QP_UD_AV_LKEY         EHCA_BMASK_IBM(32, 63)
70 #define H_ALL_RES_QP_SRQ_QP_TOKEN       EHCA_BMASK_IBM(0, 31)
71 #define H_ALL_RES_QP_SRQ_QP_HANDLE      EHCA_BMASK_IBM(0, 64)
72 #define H_ALL_RES_QP_SRQ_LIMIT          EHCA_BMASK_IBM(48, 63)
73 #define H_ALL_RES_QP_SRQ_QPN            EHCA_BMASK_IBM(40, 63)
74 
75 #define H_ALL_RES_QP_ACT_OUTST_SEND_WR  EHCA_BMASK_IBM(16, 31)
76 #define H_ALL_RES_QP_ACT_OUTST_RECV_WR  EHCA_BMASK_IBM(48, 63)
77 #define H_ALL_RES_QP_ACT_SEND_SGE       EHCA_BMASK_IBM(8, 15)
78 #define H_ALL_RES_QP_ACT_RECV_SGE       EHCA_BMASK_IBM(24, 31)
79 
80 #define H_ALL_RES_QP_SQUEUE_SIZE_PAGES  EHCA_BMASK_IBM(0, 31)
81 #define H_ALL_RES_QP_RQUEUE_SIZE_PAGES  EHCA_BMASK_IBM(32, 63)
82 
83 #define H_MP_INIT_TYPE                  EHCA_BMASK_IBM(44, 47)
84 #define H_MP_SHUTDOWN                   EHCA_BMASK_IBM(48, 48)
85 #define H_MP_RESET_QKEY_CTR             EHCA_BMASK_IBM(49, 49)
86 
87 #define HCALL4_REGS_FORMAT "r4=%lx r5=%lx r6=%lx r7=%lx"
88 #define HCALL7_REGS_FORMAT HCALL4_REGS_FORMAT " r8=%lx r9=%lx r10=%lx"
89 #define HCALL9_REGS_FORMAT HCALL7_REGS_FORMAT " r11=%lx r12=%lx"
90 
91 static DEFINE_SPINLOCK(hcall_lock);
92 
ehca_plpar_hcall_norets(unsigned long opcode,unsigned long arg1,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5,unsigned long arg6,unsigned long arg7)93 static long ehca_plpar_hcall_norets(unsigned long opcode,
94 				    unsigned long arg1,
95 				    unsigned long arg2,
96 				    unsigned long arg3,
97 				    unsigned long arg4,
98 				    unsigned long arg5,
99 				    unsigned long arg6,
100 				    unsigned long arg7)
101 {
102 	long ret;
103 	int i, sleep_msecs;
104 	unsigned long flags = 0;
105 
106 	if (unlikely(ehca_debug_level >= 2))
107 		ehca_gen_dbg("opcode=%lx " HCALL7_REGS_FORMAT,
108 			     opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
109 
110 	for (i = 0; i < 5; i++) {
111 		/* serialize hCalls to work around firmware issue */
112 		if (ehca_lock_hcalls)
113 			spin_lock_irqsave(&hcall_lock, flags);
114 
115 		ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
116 					 arg5, arg6, arg7);
117 
118 		if (ehca_lock_hcalls)
119 			spin_unlock_irqrestore(&hcall_lock, flags);
120 
121 		if (H_IS_LONG_BUSY(ret)) {
122 			sleep_msecs = get_longbusy_msecs(ret);
123 			msleep_interruptible(sleep_msecs);
124 			continue;
125 		}
126 
127 		if (ret < H_SUCCESS)
128 			ehca_gen_err("opcode=%lx ret=%li " HCALL7_REGS_FORMAT,
129 				     opcode, ret, arg1, arg2, arg3,
130 				     arg4, arg5, arg6, arg7);
131 		else
132 			if (unlikely(ehca_debug_level >= 2))
133 				ehca_gen_dbg("opcode=%lx ret=%li", opcode, ret);
134 
135 		return ret;
136 	}
137 
138 	return H_BUSY;
139 }
140 
ehca_plpar_hcall9(unsigned long opcode,unsigned long * outs,unsigned long arg1,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5,unsigned long arg6,unsigned long arg7,unsigned long arg8,unsigned long arg9)141 static long ehca_plpar_hcall9(unsigned long opcode,
142 			      unsigned long *outs, /* array of 9 outputs */
143 			      unsigned long arg1,
144 			      unsigned long arg2,
145 			      unsigned long arg3,
146 			      unsigned long arg4,
147 			      unsigned long arg5,
148 			      unsigned long arg6,
149 			      unsigned long arg7,
150 			      unsigned long arg8,
151 			      unsigned long arg9)
152 {
153 	long ret;
154 	int i, sleep_msecs;
155 	unsigned long flags = 0;
156 
157 	if (unlikely(ehca_debug_level >= 2))
158 		ehca_gen_dbg("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT, opcode,
159 			     arg1, arg2, arg3, arg4, arg5,
160 			     arg6, arg7, arg8, arg9);
161 
162 	for (i = 0; i < 5; i++) {
163 		/* serialize hCalls to work around firmware issue */
164 		if (ehca_lock_hcalls)
165 			spin_lock_irqsave(&hcall_lock, flags);
166 
167 		ret = plpar_hcall9(opcode, outs,
168 				   arg1, arg2, arg3, arg4, arg5,
169 				   arg6, arg7, arg8, arg9);
170 
171 		if (ehca_lock_hcalls)
172 			spin_unlock_irqrestore(&hcall_lock, flags);
173 
174 		if (H_IS_LONG_BUSY(ret)) {
175 			sleep_msecs = get_longbusy_msecs(ret);
176 			msleep_interruptible(sleep_msecs);
177 			continue;
178 		}
179 
180 		if (ret < H_SUCCESS) {
181 			ehca_gen_err("INPUT -- opcode=%lx " HCALL9_REGS_FORMAT,
182 				     opcode, arg1, arg2, arg3, arg4, arg5,
183 				     arg6, arg7, arg8, arg9);
184 			ehca_gen_err("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT,
185 				     ret, outs[0], outs[1], outs[2], outs[3],
186 				     outs[4], outs[5], outs[6], outs[7],
187 				     outs[8]);
188 		} else if (unlikely(ehca_debug_level >= 2))
189 			ehca_gen_dbg("OUTPUT -- ret=%li " HCALL9_REGS_FORMAT,
190 				     ret, outs[0], outs[1], outs[2], outs[3],
191 				     outs[4], outs[5], outs[6], outs[7],
192 				     outs[8]);
193 		return ret;
194 	}
195 
196 	return H_BUSY;
197 }
198 
hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,struct ehca_pfeq * pfeq,const u32 neq_control,const u32 number_of_entries,struct ipz_eq_handle * eq_handle,u32 * act_nr_of_entries,u32 * act_pages,u32 * eq_ist)199 u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
200 			     struct ehca_pfeq *pfeq,
201 			     const u32 neq_control,
202 			     const u32 number_of_entries,
203 			     struct ipz_eq_handle *eq_handle,
204 			     u32 *act_nr_of_entries,
205 			     u32 *act_pages,
206 			     u32 *eq_ist)
207 {
208 	u64 ret;
209 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
210 	u64 allocate_controls;
211 
212 	/* resource type */
213 	allocate_controls = 3ULL;
214 
215 	/* ISN is associated */
216 	if (neq_control != 1)
217 		allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
218 	else /* notification event queue */
219 		allocate_controls = (1ULL << 63) | allocate_controls;
220 
221 	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
222 				adapter_handle.handle,  /* r4 */
223 				allocate_controls,      /* r5 */
224 				number_of_entries,      /* r6 */
225 				0, 0, 0, 0, 0, 0);
226 	eq_handle->handle = outs[0];
227 	*act_nr_of_entries = (u32)outs[3];
228 	*act_pages = (u32)outs[4];
229 	*eq_ist = (u32)outs[5];
230 
231 	if (ret == H_NOT_ENOUGH_RESOURCES)
232 		ehca_gen_err("Not enough resource - ret=%lli ", ret);
233 
234 	return ret;
235 }
236 
hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,struct ipz_eq_handle eq_handle,const u64 event_mask)237 u64 hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,
238 		       struct ipz_eq_handle eq_handle,
239 		       const u64 event_mask)
240 {
241 	return ehca_plpar_hcall_norets(H_RESET_EVENTS,
242 				       adapter_handle.handle, /* r4 */
243 				       eq_handle.handle,      /* r5 */
244 				       event_mask,	      /* r6 */
245 				       0, 0, 0, 0);
246 }
247 
hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,struct ehca_cq * cq,struct ehca_alloc_cq_parms * param)248 u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
249 			     struct ehca_cq *cq,
250 			     struct ehca_alloc_cq_parms *param)
251 {
252 	int rc;
253 	u64 ret;
254 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
255 
256 	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
257 				adapter_handle.handle,   /* r4  */
258 				2,	                 /* r5  */
259 				param->eq_handle.handle, /* r6  */
260 				cq->token,	         /* r7  */
261 				param->nr_cqe,           /* r8  */
262 				0, 0, 0, 0);
263 	cq->ipz_cq_handle.handle = outs[0];
264 	param->act_nr_of_entries = (u32)outs[3];
265 	param->act_pages = (u32)outs[4];
266 
267 	if (ret == H_SUCCESS) {
268 		rc = hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
269 		if (rc) {
270 			ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
271 				     rc, outs[5]);
272 
273 			ehca_plpar_hcall_norets(H_FREE_RESOURCE,
274 						adapter_handle.handle,     /* r4 */
275 						cq->ipz_cq_handle.handle,  /* r5 */
276 						0, 0, 0, 0, 0);
277 			ret = H_NO_MEM;
278 		}
279 	}
280 
281 	if (ret == H_NOT_ENOUGH_RESOURCES)
282 		ehca_gen_err("Not enough resources. ret=%lli", ret);
283 
284 	return ret;
285 }
286 
hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,struct ehca_alloc_qp_parms * parms,int is_user)287 u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
288 			     struct ehca_alloc_qp_parms *parms, int is_user)
289 {
290 	int rc;
291 	u64 ret;
292 	u64 allocate_controls, max_r10_reg, r11, r12;
293 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
294 
295 	allocate_controls =
296 		EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS, parms->ext_type)
297 		| EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
298 		| EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
299 		| EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
300 		| EHCA_BMASK_SET(H_ALL_RES_QP_STORAGE, parms->qp_storage)
301 		| EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_SQ_PAGE_SIZE,
302 				 parms->squeue.page_size)
303 		| EHCA_BMASK_SET(H_ALL_RES_QP_SMALL_RQ_PAGE_SIZE,
304 				 parms->rqueue.page_size)
305 		| EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
306 				 !!(parms->ll_comp_flags & LLQP_RECV_COMP))
307 		| EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
308 				 !!(parms->ll_comp_flags & LLQP_SEND_COMP))
309 		| EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
310 				 parms->ud_av_l_key_ctl)
311 		| EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
312 
313 	max_r10_reg =
314 		EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
315 			       parms->squeue.max_wr + 1)
316 		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
317 				 parms->rqueue.max_wr + 1)
318 		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
319 				 parms->squeue.max_sge)
320 		| EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
321 				 parms->rqueue.max_sge);
322 
323 	r11 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QP_TOKEN, parms->srq_token);
324 
325 	if (parms->ext_type == EQPT_SRQ)
326 		r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_LIMIT, parms->srq_limit);
327 	else
328 		r12 = EHCA_BMASK_SET(H_ALL_RES_QP_SRQ_QPN, parms->srq_qpn);
329 
330 	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
331 				adapter_handle.handle,	           /* r4  */
332 				allocate_controls,	           /* r5  */
333 				parms->send_cq_handle.handle,
334 				parms->recv_cq_handle.handle,
335 				parms->eq_handle.handle,
336 				((u64)parms->token << 32) | parms->pd.value,
337 				max_r10_reg, r11, r12);
338 
339 	parms->qp_handle.handle = outs[0];
340 	parms->real_qp_num = (u32)outs[1];
341 	parms->squeue.act_nr_wqes =
342 		(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
343 	parms->rqueue.act_nr_wqes =
344 		(u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
345 	parms->squeue.act_nr_sges =
346 		(u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
347 	parms->rqueue.act_nr_sges =
348 		(u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
349 	parms->squeue.queue_size =
350 		(u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
351 	parms->rqueue.queue_size =
352 		(u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
353 
354 	if (ret == H_SUCCESS) {
355 		rc = hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
356 		if (rc) {
357 			ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
358 				     rc, outs[6]);
359 
360 			ehca_plpar_hcall_norets(H_FREE_RESOURCE,
361 						adapter_handle.handle,     /* r4 */
362 						parms->qp_handle.handle,  /* r5 */
363 						0, 0, 0, 0, 0);
364 			ret = H_NO_MEM;
365 		}
366 	}
367 
368 	if (ret == H_NOT_ENOUGH_RESOURCES)
369 		ehca_gen_err("Not enough resources. ret=%lli", ret);
370 
371 	return ret;
372 }
373 
hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,const u8 port_id,struct hipz_query_port * query_port_response_block)374 u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
375 		      const u8 port_id,
376 		      struct hipz_query_port *query_port_response_block)
377 {
378 	u64 ret;
379 	u64 r_cb = __pa(query_port_response_block);
380 
381 	if (r_cb & (EHCA_PAGESIZE-1)) {
382 		ehca_gen_err("response block not page aligned");
383 		return H_PARAMETER;
384 	}
385 
386 	ret = ehca_plpar_hcall_norets(H_QUERY_PORT,
387 				      adapter_handle.handle, /* r4 */
388 				      port_id,	             /* r5 */
389 				      r_cb,	             /* r6 */
390 				      0, 0, 0, 0);
391 
392 	if (ehca_debug_level >= 2)
393 		ehca_dmp(query_port_response_block, 64, "response_block");
394 
395 	return ret;
396 }
397 
hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,const u8 port_id,const u32 port_cap,const u8 init_type,const int modify_mask)398 u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
399 		       const u8 port_id, const u32 port_cap,
400 		       const u8 init_type, const int modify_mask)
401 {
402 	u64 port_attributes = port_cap;
403 
404 	if (modify_mask & IB_PORT_SHUTDOWN)
405 		port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1);
406 	if (modify_mask & IB_PORT_INIT_TYPE)
407 		port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type);
408 	if (modify_mask & IB_PORT_RESET_QKEY_CNTR)
409 		port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1);
410 
411 	return ehca_plpar_hcall_norets(H_MODIFY_PORT,
412 				       adapter_handle.handle, /* r4 */
413 				       port_id,               /* r5 */
414 				       port_attributes,       /* r6 */
415 				       0, 0, 0, 0);
416 }
417 
hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,struct hipz_query_hca * query_hca_rblock)418 u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
419 		     struct hipz_query_hca *query_hca_rblock)
420 {
421 	u64 r_cb = __pa(query_hca_rblock);
422 
423 	if (r_cb & (EHCA_PAGESIZE-1)) {
424 		ehca_gen_err("response_block=%p not page aligned",
425 			     query_hca_rblock);
426 		return H_PARAMETER;
427 	}
428 
429 	return ehca_plpar_hcall_norets(H_QUERY_HCA,
430 				       adapter_handle.handle, /* r4 */
431 				       r_cb,                  /* r5 */
432 				       0, 0, 0, 0, 0);
433 }
434 
hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,const u8 pagesize,const u8 queue_type,const u64 resource_handle,const u64 logical_address_of_page,u64 count)435 u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
436 			  const u8 pagesize,
437 			  const u8 queue_type,
438 			  const u64 resource_handle,
439 			  const u64 logical_address_of_page,
440 			  u64 count)
441 {
442 	return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
443 				       adapter_handle.handle,      /* r4  */
444 				       (u64)queue_type | ((u64)pagesize) << 8,
445 				       /* r5  */
446 				       resource_handle,	           /* r6  */
447 				       logical_address_of_page,    /* r7  */
448 				       count,	                   /* r8  */
449 				       0, 0);
450 }
451 
hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,const struct ipz_eq_handle eq_handle,struct ehca_pfeq * pfeq,const u8 pagesize,const u8 queue_type,const u64 logical_address_of_page,const u64 count)452 u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
453 			     const struct ipz_eq_handle eq_handle,
454 			     struct ehca_pfeq *pfeq,
455 			     const u8 pagesize,
456 			     const u8 queue_type,
457 			     const u64 logical_address_of_page,
458 			     const u64 count)
459 {
460 	if (count != 1) {
461 		ehca_gen_err("Ppage counter=%llx", count);
462 		return H_PARAMETER;
463 	}
464 	return hipz_h_register_rpage(adapter_handle,
465 				     pagesize,
466 				     queue_type,
467 				     eq_handle.handle,
468 				     logical_address_of_page, count);
469 }
470 
hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,u32 ist)471 u64 hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,
472 			   u32 ist)
473 {
474 	u64 ret;
475 	ret = ehca_plpar_hcall_norets(H_QUERY_INT_STATE,
476 				      adapter_handle.handle, /* r4 */
477 				      ist,                   /* r5 */
478 				      0, 0, 0, 0, 0);
479 
480 	if (ret != H_SUCCESS && ret != H_BUSY)
481 		ehca_gen_err("Could not query interrupt state.");
482 
483 	return ret;
484 }
485 
hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,const struct ipz_cq_handle cq_handle,struct ehca_pfcq * pfcq,const u8 pagesize,const u8 queue_type,const u64 logical_address_of_page,const u64 count,const struct h_galpa gal)486 u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
487 			     const struct ipz_cq_handle cq_handle,
488 			     struct ehca_pfcq *pfcq,
489 			     const u8 pagesize,
490 			     const u8 queue_type,
491 			     const u64 logical_address_of_page,
492 			     const u64 count,
493 			     const struct h_galpa gal)
494 {
495 	if (count != 1) {
496 		ehca_gen_err("Page counter=%llx", count);
497 		return H_PARAMETER;
498 	}
499 
500 	return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
501 				     cq_handle.handle, logical_address_of_page,
502 				     count);
503 }
504 
hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct ehca_pfqp * pfqp,const u8 pagesize,const u8 queue_type,const u64 logical_address_of_page,const u64 count,const struct h_galpa galpa)505 u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
506 			     const struct ipz_qp_handle qp_handle,
507 			     struct ehca_pfqp *pfqp,
508 			     const u8 pagesize,
509 			     const u8 queue_type,
510 			     const u64 logical_address_of_page,
511 			     const u64 count,
512 			     const struct h_galpa galpa)
513 {
514 	if (count > 1) {
515 		ehca_gen_err("Page counter=%llx", count);
516 		return H_PARAMETER;
517 	}
518 
519 	return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
520 				     qp_handle.handle, logical_address_of_page,
521 				     count);
522 }
523 
hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct ehca_pfqp * pfqp,void ** log_addr_next_sq_wqe2processed,void ** log_addr_next_rq_wqe2processed,int dis_and_get_function_code)524 u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
525 			       const struct ipz_qp_handle qp_handle,
526 			       struct ehca_pfqp *pfqp,
527 			       void **log_addr_next_sq_wqe2processed,
528 			       void **log_addr_next_rq_wqe2processed,
529 			       int dis_and_get_function_code)
530 {
531 	u64 ret;
532 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
533 
534 	ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
535 				adapter_handle.handle,     /* r4 */
536 				dis_and_get_function_code, /* r5 */
537 				qp_handle.handle,	   /* r6 */
538 				0, 0, 0, 0, 0, 0);
539 	if (log_addr_next_sq_wqe2processed)
540 		*log_addr_next_sq_wqe2processed = (void *)outs[0];
541 	if (log_addr_next_rq_wqe2processed)
542 		*log_addr_next_rq_wqe2processed = (void *)outs[1];
543 
544 	return ret;
545 }
546 
hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct ehca_pfqp * pfqp,const u64 update_mask,struct hcp_modify_qp_control_block * mqpcb,struct h_galpa gal)547 u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
548 		     const struct ipz_qp_handle qp_handle,
549 		     struct ehca_pfqp *pfqp,
550 		     const u64 update_mask,
551 		     struct hcp_modify_qp_control_block *mqpcb,
552 		     struct h_galpa gal)
553 {
554 	u64 ret;
555 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
556 	ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
557 				adapter_handle.handle, /* r4 */
558 				qp_handle.handle,      /* r5 */
559 				update_mask,	       /* r6 */
560 				__pa(mqpcb),	       /* r7 */
561 				0, 0, 0, 0, 0);
562 
563 	if (ret == H_NOT_ENOUGH_RESOURCES)
564 		ehca_gen_err("Insufficient resources ret=%lli", ret);
565 
566 	return ret;
567 }
568 
hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct ehca_pfqp * pfqp,struct hcp_modify_qp_control_block * qqpcb,struct h_galpa gal)569 u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
570 		    const struct ipz_qp_handle qp_handle,
571 		    struct ehca_pfqp *pfqp,
572 		    struct hcp_modify_qp_control_block *qqpcb,
573 		    struct h_galpa gal)
574 {
575 	return ehca_plpar_hcall_norets(H_QUERY_QP,
576 				       adapter_handle.handle, /* r4 */
577 				       qp_handle.handle,      /* r5 */
578 				       __pa(qqpcb),	      /* r6 */
579 				       0, 0, 0, 0);
580 }
581 
hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,struct ehca_qp * qp)582 u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
583 		      struct ehca_qp *qp)
584 {
585 	u64 ret;
586 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
587 
588 	ret = hcp_galpas_dtor(&qp->galpas);
589 	if (ret) {
590 		ehca_gen_err("Could not destruct qp->galpas");
591 		return H_RESOURCE;
592 	}
593 	ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
594 				adapter_handle.handle,     /* r4 */
595 				/* function code */
596 				1,	                   /* r5 */
597 				qp->ipz_qp_handle.handle,  /* r6 */
598 				0, 0, 0, 0, 0, 0);
599 	if (ret == H_HARDWARE)
600 		ehca_gen_err("HCA not operational. ret=%lli", ret);
601 
602 	ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
603 				      adapter_handle.handle,     /* r4 */
604 				      qp->ipz_qp_handle.handle,  /* r5 */
605 				      0, 0, 0, 0, 0);
606 
607 	if (ret == H_RESOURCE)
608 		ehca_gen_err("Resource still in use. ret=%lli", ret);
609 
610 	return ret;
611 }
612 
hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct h_galpa gal,u32 port)613 u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
614 		       const struct ipz_qp_handle qp_handle,
615 		       struct h_galpa gal,
616 		       u32 port)
617 {
618 	return ehca_plpar_hcall_norets(H_DEFINE_AQP0,
619 				       adapter_handle.handle, /* r4 */
620 				       qp_handle.handle,      /* r5 */
621 				       port,                  /* r6 */
622 				       0, 0, 0, 0);
623 }
624 
hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct h_galpa gal,u32 port,u32 * pma_qp_nr,u32 * bma_qp_nr)625 u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
626 		       const struct ipz_qp_handle qp_handle,
627 		       struct h_galpa gal,
628 		       u32 port, u32 * pma_qp_nr,
629 		       u32 * bma_qp_nr)
630 {
631 	u64 ret;
632 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
633 
634 	ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
635 				adapter_handle.handle, /* r4 */
636 				qp_handle.handle,      /* r5 */
637 				port,	               /* r6 */
638 				0, 0, 0, 0, 0, 0);
639 	*pma_qp_nr = (u32)outs[0];
640 	*bma_qp_nr = (u32)outs[1];
641 
642 	if (ret == H_ALIAS_EXIST)
643 		ehca_gen_err("AQP1 already exists. ret=%lli", ret);
644 
645 	return ret;
646 }
647 
hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct h_galpa gal,u16 mcg_dlid,u64 subnet_prefix,u64 interface_id)648 u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
649 		       const struct ipz_qp_handle qp_handle,
650 		       struct h_galpa gal,
651 		       u16 mcg_dlid,
652 		       u64 subnet_prefix, u64 interface_id)
653 {
654 	u64 ret;
655 
656 	ret = ehca_plpar_hcall_norets(H_ATTACH_MCQP,
657 				      adapter_handle.handle,  /* r4 */
658 				      qp_handle.handle,       /* r5 */
659 				      mcg_dlid,               /* r6 */
660 				      interface_id,           /* r7 */
661 				      subnet_prefix,          /* r8 */
662 				      0, 0);
663 
664 	if (ret == H_NOT_ENOUGH_RESOURCES)
665 		ehca_gen_err("Not enough resources. ret=%lli", ret);
666 
667 	return ret;
668 }
669 
hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,const struct ipz_qp_handle qp_handle,struct h_galpa gal,u16 mcg_dlid,u64 subnet_prefix,u64 interface_id)670 u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
671 		       const struct ipz_qp_handle qp_handle,
672 		       struct h_galpa gal,
673 		       u16 mcg_dlid,
674 		       u64 subnet_prefix, u64 interface_id)
675 {
676 	return ehca_plpar_hcall_norets(H_DETACH_MCQP,
677 				       adapter_handle.handle, /* r4 */
678 				       qp_handle.handle,      /* r5 */
679 				       mcg_dlid,              /* r6 */
680 				       interface_id,          /* r7 */
681 				       subnet_prefix,         /* r8 */
682 				       0, 0);
683 }
684 
hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,struct ehca_cq * cq,u8 force_flag)685 u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
686 		      struct ehca_cq *cq,
687 		      u8 force_flag)
688 {
689 	u64 ret;
690 
691 	ret = hcp_galpas_dtor(&cq->galpas);
692 	if (ret) {
693 		ehca_gen_err("Could not destruct cp->galpas");
694 		return H_RESOURCE;
695 	}
696 
697 	ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
698 				      adapter_handle.handle,     /* r4 */
699 				      cq->ipz_cq_handle.handle,  /* r5 */
700 				      force_flag != 0 ? 1L : 0L, /* r6 */
701 				      0, 0, 0, 0);
702 
703 	if (ret == H_RESOURCE)
704 		ehca_gen_err("H_FREE_RESOURCE failed ret=%lli ", ret);
705 
706 	return ret;
707 }
708 
hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,struct ehca_eq * eq)709 u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
710 		      struct ehca_eq *eq)
711 {
712 	u64 ret;
713 
714 	ret = hcp_galpas_dtor(&eq->galpas);
715 	if (ret) {
716 		ehca_gen_err("Could not destruct eq->galpas");
717 		return H_RESOURCE;
718 	}
719 
720 	ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
721 				      adapter_handle.handle,     /* r4 */
722 				      eq->ipz_eq_handle.handle,  /* r5 */
723 				      0, 0, 0, 0, 0);
724 
725 	if (ret == H_RESOURCE)
726 		ehca_gen_err("Resource in use. ret=%lli ", ret);
727 
728 	return ret;
729 }
730 
hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,const struct ehca_mr * mr,const u64 vaddr,const u64 length,const u32 access_ctrl,const struct ipz_pd pd,struct ehca_mr_hipzout_parms * outparms)731 u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
732 			     const struct ehca_mr *mr,
733 			     const u64 vaddr,
734 			     const u64 length,
735 			     const u32 access_ctrl,
736 			     const struct ipz_pd pd,
737 			     struct ehca_mr_hipzout_parms *outparms)
738 {
739 	u64 ret;
740 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
741 
742 	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
743 				adapter_handle.handle,            /* r4 */
744 				5,                                /* r5 */
745 				vaddr,                            /* r6 */
746 				length,                           /* r7 */
747 				(((u64)access_ctrl) << 32ULL),    /* r8 */
748 				pd.value,                         /* r9 */
749 				0, 0, 0);
750 	outparms->handle.handle = outs[0];
751 	outparms->lkey = (u32)outs[2];
752 	outparms->rkey = (u32)outs[3];
753 
754 	return ret;
755 }
756 
hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,const struct ehca_mr * mr,const u8 pagesize,const u8 queue_type,const u64 logical_address_of_page,const u64 count)757 u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
758 			     const struct ehca_mr *mr,
759 			     const u8 pagesize,
760 			     const u8 queue_type,
761 			     const u64 logical_address_of_page,
762 			     const u64 count)
763 {
764 	u64 ret;
765 
766 	if (unlikely(ehca_debug_level >= 3)) {
767 		if (count > 1) {
768 			u64 *kpage;
769 			int i;
770 			kpage = __va(logical_address_of_page);
771 			for (i = 0; i < count; i++)
772 				ehca_gen_dbg("kpage[%d]=%p",
773 					     i, (void *)kpage[i]);
774 		} else
775 			ehca_gen_dbg("kpage=%p",
776 				     (void *)logical_address_of_page);
777 	}
778 
779 	if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
780 		ehca_gen_err("logical_address_of_page not on a 4k boundary "
781 			     "adapter_handle=%llx mr=%p mr_handle=%llx "
782 			     "pagesize=%x queue_type=%x "
783 			     "logical_address_of_page=%llx count=%llx",
784 			     adapter_handle.handle, mr,
785 			     mr->ipz_mr_handle.handle, pagesize, queue_type,
786 			     logical_address_of_page, count);
787 		ret = H_PARAMETER;
788 	} else
789 		ret = hipz_h_register_rpage(adapter_handle, pagesize,
790 					    queue_type,
791 					    mr->ipz_mr_handle.handle,
792 					    logical_address_of_page, count);
793 	return ret;
794 }
795 
hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,const struct ehca_mr * mr,struct ehca_mr_hipzout_parms * outparms)796 u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
797 		    const struct ehca_mr *mr,
798 		    struct ehca_mr_hipzout_parms *outparms)
799 {
800 	u64 ret;
801 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
802 
803 	ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
804 				adapter_handle.handle,     /* r4 */
805 				mr->ipz_mr_handle.handle,  /* r5 */
806 				0, 0, 0, 0, 0, 0, 0);
807 	outparms->len = outs[0];
808 	outparms->vaddr = outs[1];
809 	outparms->acl  = outs[4] >> 32;
810 	outparms->lkey = (u32)(outs[5] >> 32);
811 	outparms->rkey = (u32)(outs[5] & (0xffffffff));
812 
813 	return ret;
814 }
815 
hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,const struct ehca_mr * mr)816 u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
817 			    const struct ehca_mr *mr)
818 {
819 	return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
820 				       adapter_handle.handle,    /* r4 */
821 				       mr->ipz_mr_handle.handle, /* r5 */
822 				       0, 0, 0, 0, 0);
823 }
824 
hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,const struct ehca_mr * mr,const u64 vaddr_in,const u64 length,const u32 access_ctrl,const struct ipz_pd pd,const u64 mr_addr_cb,struct ehca_mr_hipzout_parms * outparms)825 u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
826 			  const struct ehca_mr *mr,
827 			  const u64 vaddr_in,
828 			  const u64 length,
829 			  const u32 access_ctrl,
830 			  const struct ipz_pd pd,
831 			  const u64 mr_addr_cb,
832 			  struct ehca_mr_hipzout_parms *outparms)
833 {
834 	u64 ret;
835 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
836 
837 	ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
838 				adapter_handle.handle,    /* r4 */
839 				mr->ipz_mr_handle.handle, /* r5 */
840 				vaddr_in,	          /* r6 */
841 				length,                   /* r7 */
842 				/* r8 */
843 				((((u64)access_ctrl) << 32ULL) | pd.value),
844 				mr_addr_cb,               /* r9 */
845 				0, 0, 0);
846 	outparms->vaddr = outs[1];
847 	outparms->lkey = (u32)outs[2];
848 	outparms->rkey = (u32)outs[3];
849 
850 	return ret;
851 }
852 
hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,const struct ehca_mr * mr,const struct ehca_mr * orig_mr,const u64 vaddr_in,const u32 access_ctrl,const struct ipz_pd pd,struct ehca_mr_hipzout_parms * outparms)853 u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
854 			const struct ehca_mr *mr,
855 			const struct ehca_mr *orig_mr,
856 			const u64 vaddr_in,
857 			const u32 access_ctrl,
858 			const struct ipz_pd pd,
859 			struct ehca_mr_hipzout_parms *outparms)
860 {
861 	u64 ret;
862 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
863 
864 	ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
865 				adapter_handle.handle,            /* r4 */
866 				orig_mr->ipz_mr_handle.handle,    /* r5 */
867 				vaddr_in,                         /* r6 */
868 				(((u64)access_ctrl) << 32ULL),    /* r7 */
869 				pd.value,                         /* r8 */
870 				0, 0, 0, 0);
871 	outparms->handle.handle = outs[0];
872 	outparms->lkey = (u32)outs[2];
873 	outparms->rkey = (u32)outs[3];
874 
875 	return ret;
876 }
877 
hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,const struct ehca_mw * mw,const struct ipz_pd pd,struct ehca_mw_hipzout_parms * outparms)878 u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
879 			     const struct ehca_mw *mw,
880 			     const struct ipz_pd pd,
881 			     struct ehca_mw_hipzout_parms *outparms)
882 {
883 	u64 ret;
884 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
885 
886 	ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
887 				adapter_handle.handle,      /* r4 */
888 				6,                          /* r5 */
889 				pd.value,                   /* r6 */
890 				0, 0, 0, 0, 0, 0);
891 	outparms->handle.handle = outs[0];
892 	outparms->rkey = (u32)outs[3];
893 
894 	return ret;
895 }
896 
hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,const struct ehca_mw * mw,struct ehca_mw_hipzout_parms * outparms)897 u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
898 		    const struct ehca_mw *mw,
899 		    struct ehca_mw_hipzout_parms *outparms)
900 {
901 	u64 ret;
902 	unsigned long outs[PLPAR_HCALL9_BUFSIZE];
903 
904 	ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
905 				adapter_handle.handle,    /* r4 */
906 				mw->ipz_mw_handle.handle, /* r5 */
907 				0, 0, 0, 0, 0, 0, 0);
908 	outparms->rkey = (u32)outs[3];
909 
910 	return ret;
911 }
912 
hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,const struct ehca_mw * mw)913 u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
914 			    const struct ehca_mw *mw)
915 {
916 	return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
917 				       adapter_handle.handle,    /* r4 */
918 				       mw->ipz_mw_handle.handle, /* r5 */
919 				       0, 0, 0, 0, 0);
920 }
921 
hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,const u64 ressource_handle,void * rblock,unsigned long * byte_count)922 u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
923 		      const u64 ressource_handle,
924 		      void *rblock,
925 		      unsigned long *byte_count)
926 {
927 	u64 r_cb = __pa(rblock);
928 
929 	if (r_cb & (EHCA_PAGESIZE-1)) {
930 		ehca_gen_err("rblock not page aligned.");
931 		return H_PARAMETER;
932 	}
933 
934 	return ehca_plpar_hcall_norets(H_ERROR_DATA,
935 				       adapter_handle.handle,
936 				       ressource_handle,
937 				       r_cb,
938 				       0, 0, 0, 0);
939 }
940 
hipz_h_eoi(int irq)941 u64 hipz_h_eoi(int irq)
942 {
943 	unsigned long xirr;
944 
945 	iosync();
946 	xirr = (0xffULL << 24) | irq;
947 
948 	return plpar_hcall_norets(H_EOI, xirr);
949 }
950