2 * IBM eServer eHCA Infiniband device driver for Linux on POWER
4 * Firmware Infiniband Interface code for POWER
6 * Authors: Christoph Raisch <raisch@de.ibm.com>
7 * Hoang-Nam Nguyen <hnguyen@de.ibm.com>
8 * Gerd Bayer <gerd.bayer@de.ibm.com>
9 * Waleri Fomin <fomin@de.ibm.com>
11 * Copyright (c) 2005 IBM Corporation
13 * All rights reserved.
15 * This source code is distributed under a dual license of GPL v2.0 and OpenIB
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
23 * Redistributions of source code must retain the above copyright notice, this
24 * list of conditions and the following disclaimer.
26 * Redistributions in binary form must reproduce the above copyright notice,
27 * this list of conditions and the following disclaimer in the documentation
28 * and/or other materials
29 * provided with the distribution.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
36 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
39 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGE.
44 #include <asm/hvcall.h>
45 #include "ehca_tools.h"
49 #include "ipz_pt_fn.h"
51 #define H_ALL_RES_QP_ENHANCED_OPS EHCA_BMASK_IBM(9, 11)
52 #define H_ALL_RES_QP_PTE_PIN EHCA_BMASK_IBM(12, 12)
53 #define H_ALL_RES_QP_SERVICE_TYPE EHCA_BMASK_IBM(13, 15)
54 #define H_ALL_RES_QP_LL_RQ_CQE_POSTING EHCA_BMASK_IBM(18, 18)
55 #define H_ALL_RES_QP_LL_SQ_CQE_POSTING EHCA_BMASK_IBM(19, 21)
56 #define H_ALL_RES_QP_SIGNALING_TYPE EHCA_BMASK_IBM(22, 23)
57 #define H_ALL_RES_QP_UD_AV_LKEY_CTRL EHCA_BMASK_IBM(31, 31)
58 #define H_ALL_RES_QP_RESOURCE_TYPE EHCA_BMASK_IBM(56, 63)
60 #define H_ALL_RES_QP_MAX_OUTST_SEND_WR EHCA_BMASK_IBM(0, 15)
61 #define H_ALL_RES_QP_MAX_OUTST_RECV_WR EHCA_BMASK_IBM(16, 31)
62 #define H_ALL_RES_QP_MAX_SEND_SGE EHCA_BMASK_IBM(32, 39)
63 #define H_ALL_RES_QP_MAX_RECV_SGE EHCA_BMASK_IBM(40, 47)
65 #define H_ALL_RES_QP_ACT_OUTST_SEND_WR EHCA_BMASK_IBM(16, 31)
66 #define H_ALL_RES_QP_ACT_OUTST_RECV_WR EHCA_BMASK_IBM(48, 63)
67 #define H_ALL_RES_QP_ACT_SEND_SGE EHCA_BMASK_IBM(8, 15)
68 #define H_ALL_RES_QP_ACT_RECV_SGE EHCA_BMASK_IBM(24, 31)
70 #define H_ALL_RES_QP_SQUEUE_SIZE_PAGES EHCA_BMASK_IBM(0, 31)
71 #define H_ALL_RES_QP_RQUEUE_SIZE_PAGES EHCA_BMASK_IBM(32, 63)
73 #define H_MP_INIT_TYPE EHCA_BMASK_IBM(44, 47)
74 #define H_MP_SHUTDOWN EHCA_BMASK_IBM(48, 48)
75 #define H_MP_RESET_QKEY_CTR EHCA_BMASK_IBM(49, 49)
77 /* direct access qp controls */
78 #define DAQP_CTRL_ENABLE 0x01
79 #define DAQP_CTRL_SEND_COMP 0x20
80 #define DAQP_CTRL_RECV_COMP 0x40
82 static u32 get_longbusy_msecs(int longbusy_rc)
84 switch (longbusy_rc) {
85 case H_LONG_BUSY_ORDER_1_MSEC:
87 case H_LONG_BUSY_ORDER_10_MSEC:
89 case H_LONG_BUSY_ORDER_100_MSEC:
91 case H_LONG_BUSY_ORDER_1_SEC:
93 case H_LONG_BUSY_ORDER_10_SEC:
95 case H_LONG_BUSY_ORDER_100_SEC:
102 static long ehca_plpar_hcall_norets(unsigned long opcode,
114 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
115 "arg5=%lx arg6=%lx arg7=%lx",
116 opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
118 for (i = 0; i < 5; i++) {
119 ret = plpar_hcall_norets(opcode, arg1, arg2, arg3, arg4,
122 if (H_IS_LONG_BUSY(ret)) {
123 sleep_msecs = get_longbusy_msecs(ret);
124 msleep_interruptible(sleep_msecs);
129 ehca_gen_err("opcode=%lx ret=%lx"
130 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
131 " arg5=%lx arg6=%lx arg7=%lx ",
133 arg1, arg2, arg3, arg4, arg5,
136 ehca_gen_dbg("opcode=%lx ret=%lx", opcode, ret);
144 static long ehca_plpar_hcall9(unsigned long opcode,
145 unsigned long *outs, /* array of 9 outputs */
157 int i, sleep_msecs, lock_is_set = 0;
160 ehca_gen_dbg("opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
161 "arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
162 opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
165 for (i = 0; i < 5; i++) {
166 if ((opcode == H_ALLOC_RESOURCE) && (arg2 == 5)) {
167 spin_lock_irqsave(&hcall_lock, flags);
171 ret = plpar_hcall9(opcode, outs,
172 arg1, arg2, arg3, arg4, arg5,
173 arg6, arg7, arg8, arg9);
176 spin_unlock_irqrestore(&hcall_lock, flags);
178 if (H_IS_LONG_BUSY(ret)) {
179 sleep_msecs = get_longbusy_msecs(ret);
180 msleep_interruptible(sleep_msecs);
185 ehca_gen_err("opcode=%lx ret=%lx"
186 " arg1=%lx arg2=%lx arg3=%lx arg4=%lx"
187 " arg5=%lx arg6=%lx arg7=%lx arg8=%lx"
189 " out1=%lx out2=%lx out3=%lx out4=%lx"
190 " out5=%lx out6=%lx out7=%lx out8=%lx"
193 arg1, arg2, arg3, arg4, arg5,
194 arg6, arg7, arg8, arg9,
195 outs[0], outs[1], outs[2], outs[3],
196 outs[4], outs[5], outs[6], outs[7],
199 ehca_gen_dbg("opcode=%lx ret=%lx out1=%lx out2=%lx out3=%lx "
200 "out4=%lx out5=%lx out6=%lx out7=%lx out8=%lx "
202 opcode, ret, outs[0], outs[1], outs[2], outs[3],
203 outs[4], outs[5], outs[6], outs[7], outs[8]);
210 u64 hipz_h_alloc_resource_eq(const struct ipz_adapter_handle adapter_handle,
211 struct ehca_pfeq *pfeq,
212 const u32 neq_control,
213 const u32 number_of_entries,
214 struct ipz_eq_handle *eq_handle,
215 u32 *act_nr_of_entries,
220 u64 outs[PLPAR_HCALL9_BUFSIZE];
221 u64 allocate_controls;
224 allocate_controls = 3ULL;
226 /* ISN is associated */
227 if (neq_control != 1)
228 allocate_controls = (1ULL << (63 - 7)) | allocate_controls;
229 else /* notification event queue */
230 allocate_controls = (1ULL << 63) | allocate_controls;
232 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
233 adapter_handle.handle, /* r4 */
234 allocate_controls, /* r5 */
235 number_of_entries, /* r6 */
237 eq_handle->handle = outs[0];
238 *act_nr_of_entries = (u32)outs[3];
239 *act_pages = (u32)outs[4];
240 *eq_ist = (u32)outs[5];
242 if (ret == H_NOT_ENOUGH_RESOURCES)
243 ehca_gen_err("Not enough resource - ret=%lx ", ret);
248 u64 hipz_h_reset_event(const struct ipz_adapter_handle adapter_handle,
249 struct ipz_eq_handle eq_handle,
250 const u64 event_mask)
252 return ehca_plpar_hcall_norets(H_RESET_EVENTS,
253 adapter_handle.handle, /* r4 */
254 eq_handle.handle, /* r5 */
259 u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
261 struct ehca_alloc_cq_parms *param)
264 u64 outs[PLPAR_HCALL9_BUFSIZE];
266 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
267 adapter_handle.handle, /* r4 */
269 param->eq_handle.handle, /* r6 */
271 param->nr_cqe, /* r8 */
273 cq->ipz_cq_handle.handle = outs[0];
274 param->act_nr_of_entries = (u32)outs[3];
275 param->act_pages = (u32)outs[4];
277 if (ret == H_SUCCESS)
278 hcp_galpas_ctor(&cq->galpas, outs[5], outs[6]);
280 if (ret == H_NOT_ENOUGH_RESOURCES)
281 ehca_gen_err("Not enough resources. ret=%lx", ret);
286 u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
288 struct ehca_alloc_qp_parms *parms)
291 u64 allocate_controls;
293 u64 outs[PLPAR_HCALL9_BUFSIZE];
294 u16 max_nr_receive_wqes = qp->init_attr.cap.max_recv_wr + 1;
295 u16 max_nr_send_wqes = qp->init_attr.cap.max_send_wr + 1;
296 int daqp_ctrl = parms->daqp_ctrl;
299 EHCA_BMASK_SET(H_ALL_RES_QP_ENHANCED_OPS,
300 (daqp_ctrl & DAQP_CTRL_ENABLE) ? 1 : 0)
301 | EHCA_BMASK_SET(H_ALL_RES_QP_PTE_PIN, 0)
302 | EHCA_BMASK_SET(H_ALL_RES_QP_SERVICE_TYPE, parms->servicetype)
303 | EHCA_BMASK_SET(H_ALL_RES_QP_SIGNALING_TYPE, parms->sigtype)
304 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_RQ_CQE_POSTING,
305 (daqp_ctrl & DAQP_CTRL_RECV_COMP) ? 1 : 0)
306 | EHCA_BMASK_SET(H_ALL_RES_QP_LL_SQ_CQE_POSTING,
307 (daqp_ctrl & DAQP_CTRL_SEND_COMP) ? 1 : 0)
308 | EHCA_BMASK_SET(H_ALL_RES_QP_UD_AV_LKEY_CTRL,
309 parms->ud_av_l_key_ctl)
310 | EHCA_BMASK_SET(H_ALL_RES_QP_RESOURCE_TYPE, 1);
313 EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_SEND_WR,
315 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_OUTST_RECV_WR,
317 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_SEND_SGE,
319 | EHCA_BMASK_SET(H_ALL_RES_QP_MAX_RECV_SGE,
320 parms->max_recv_sge);
322 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
323 adapter_handle.handle, /* r4 */
324 allocate_controls, /* r5 */
325 qp->send_cq->ipz_cq_handle.handle,
326 qp->recv_cq->ipz_cq_handle.handle,
327 parms->ipz_eq_handle.handle,
328 ((u64)qp->token << 32) | parms->pd.value,
329 max_r10_reg, /* r10 */
330 parms->ud_av_l_key_ctl, /* r11 */
332 qp->ipz_qp_handle.handle = outs[0];
333 qp->real_qp_num = (u32)outs[1];
334 parms->act_nr_send_wqes =
335 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_SEND_WR, outs[2]);
336 parms->act_nr_recv_wqes =
337 (u16)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_OUTST_RECV_WR, outs[2]);
338 parms->act_nr_send_sges =
339 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_SEND_SGE, outs[3]);
340 parms->act_nr_recv_sges =
341 (u8)EHCA_BMASK_GET(H_ALL_RES_QP_ACT_RECV_SGE, outs[3]);
343 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_SQUEUE_SIZE_PAGES, outs[4]);
345 (u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
347 if (ret == H_SUCCESS)
348 hcp_galpas_ctor(&qp->galpas, outs[6], outs[6]);
350 if (ret == H_NOT_ENOUGH_RESOURCES)
351 ehca_gen_err("Not enough resources. ret=%lx", ret);
356 u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle,
358 struct hipz_query_port *query_port_response_block)
361 u64 r_cb = virt_to_abs(query_port_response_block);
363 if (r_cb & (EHCA_PAGESIZE-1)) {
364 ehca_gen_err("response block not page aligned");
368 ret = ehca_plpar_hcall_norets(H_QUERY_PORT,
369 adapter_handle.handle, /* r4 */
374 if (ehca_debug_level)
375 ehca_dmp(query_port_response_block, 64, "response_block");
380 u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle,
381 const u8 port_id, const u32 port_cap,
382 const u8 init_type, const int modify_mask)
384 u64 port_attributes = port_cap;
386 if (modify_mask & IB_PORT_SHUTDOWN)
387 port_attributes |= EHCA_BMASK_SET(H_MP_SHUTDOWN, 1);
388 if (modify_mask & IB_PORT_INIT_TYPE)
389 port_attributes |= EHCA_BMASK_SET(H_MP_INIT_TYPE, init_type);
390 if (modify_mask & IB_PORT_RESET_QKEY_CNTR)
391 port_attributes |= EHCA_BMASK_SET(H_MP_RESET_QKEY_CTR, 1);
393 return ehca_plpar_hcall_norets(H_MODIFY_PORT,
394 adapter_handle.handle, /* r4 */
396 port_attributes, /* r6 */
400 u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle,
401 struct hipz_query_hca *query_hca_rblock)
403 u64 r_cb = virt_to_abs(query_hca_rblock);
405 if (r_cb & (EHCA_PAGESIZE-1)) {
406 ehca_gen_err("response_block=%p not page aligned",
411 return ehca_plpar_hcall_norets(H_QUERY_HCA,
412 adapter_handle.handle, /* r4 */
417 u64 hipz_h_register_rpage(const struct ipz_adapter_handle adapter_handle,
420 const u64 resource_handle,
421 const u64 logical_address_of_page,
424 return ehca_plpar_hcall_norets(H_REGISTER_RPAGES,
425 adapter_handle.handle, /* r4 */
426 queue_type | pagesize << 8, /* r5 */
427 resource_handle, /* r6 */
428 logical_address_of_page, /* r7 */
433 u64 hipz_h_register_rpage_eq(const struct ipz_adapter_handle adapter_handle,
434 const struct ipz_eq_handle eq_handle,
435 struct ehca_pfeq *pfeq,
438 const u64 logical_address_of_page,
442 ehca_gen_err("Ppage counter=%lx", count);
445 return hipz_h_register_rpage(adapter_handle,
449 logical_address_of_page, count);
452 u64 hipz_h_query_int_state(const struct ipz_adapter_handle adapter_handle,
456 ret = ehca_plpar_hcall_norets(H_QUERY_INT_STATE,
457 adapter_handle.handle, /* r4 */
461 if (ret != H_SUCCESS && ret != H_BUSY)
462 ehca_gen_err("Could not query interrupt state.");
467 u64 hipz_h_register_rpage_cq(const struct ipz_adapter_handle adapter_handle,
468 const struct ipz_cq_handle cq_handle,
469 struct ehca_pfcq *pfcq,
472 const u64 logical_address_of_page,
474 const struct h_galpa gal)
477 ehca_gen_err("Page counter=%lx", count);
481 return hipz_h_register_rpage(adapter_handle, pagesize, queue_type,
482 cq_handle.handle, logical_address_of_page,
486 u64 hipz_h_register_rpage_qp(const struct ipz_adapter_handle adapter_handle,
487 const struct ipz_qp_handle qp_handle,
488 struct ehca_pfqp *pfqp,
491 const u64 logical_address_of_page,
493 const struct h_galpa galpa)
496 ehca_gen_err("Page counter=%lx", count);
500 return hipz_h_register_rpage(adapter_handle,pagesize,queue_type,
501 qp_handle.handle,logical_address_of_page,
505 u64 hipz_h_disable_and_get_wqe(const struct ipz_adapter_handle adapter_handle,
506 const struct ipz_qp_handle qp_handle,
507 struct ehca_pfqp *pfqp,
508 void **log_addr_next_sq_wqe2processed,
509 void **log_addr_next_rq_wqe2processed,
510 int dis_and_get_function_code)
513 u64 outs[PLPAR_HCALL9_BUFSIZE];
515 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
516 adapter_handle.handle, /* r4 */
517 dis_and_get_function_code, /* r5 */
518 qp_handle.handle, /* r6 */
520 if (log_addr_next_sq_wqe2processed)
521 *log_addr_next_sq_wqe2processed = (void*)outs[0];
522 if (log_addr_next_rq_wqe2processed)
523 *log_addr_next_rq_wqe2processed = (void*)outs[1];
528 u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle,
529 const struct ipz_qp_handle qp_handle,
530 struct ehca_pfqp *pfqp,
531 const u64 update_mask,
532 struct hcp_modify_qp_control_block *mqpcb,
536 u64 outs[PLPAR_HCALL9_BUFSIZE];
537 ret = ehca_plpar_hcall9(H_MODIFY_QP, outs,
538 adapter_handle.handle, /* r4 */
539 qp_handle.handle, /* r5 */
540 update_mask, /* r6 */
541 virt_to_abs(mqpcb), /* r7 */
544 if (ret == H_NOT_ENOUGH_RESOURCES)
545 ehca_gen_err("Insufficient resources ret=%lx", ret);
550 u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle,
551 const struct ipz_qp_handle qp_handle,
552 struct ehca_pfqp *pfqp,
553 struct hcp_modify_qp_control_block *qqpcb,
556 return ehca_plpar_hcall_norets(H_QUERY_QP,
557 adapter_handle.handle, /* r4 */
558 qp_handle.handle, /* r5 */
559 virt_to_abs(qqpcb), /* r6 */
563 u64 hipz_h_destroy_qp(const struct ipz_adapter_handle adapter_handle,
567 u64 outs[PLPAR_HCALL9_BUFSIZE];
569 ret = hcp_galpas_dtor(&qp->galpas);
571 ehca_gen_err("Could not destruct qp->galpas");
574 ret = ehca_plpar_hcall9(H_DISABLE_AND_GETC, outs,
575 adapter_handle.handle, /* r4 */
578 qp->ipz_qp_handle.handle, /* r6 */
580 if (ret == H_HARDWARE)
581 ehca_gen_err("HCA not operational. ret=%lx", ret);
583 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
584 adapter_handle.handle, /* r4 */
585 qp->ipz_qp_handle.handle, /* r5 */
588 if (ret == H_RESOURCE)
589 ehca_gen_err("Resource still in use. ret=%lx", ret);
594 u64 hipz_h_define_aqp0(const struct ipz_adapter_handle adapter_handle,
595 const struct ipz_qp_handle qp_handle,
599 return ehca_plpar_hcall_norets(H_DEFINE_AQP0,
600 adapter_handle.handle, /* r4 */
601 qp_handle.handle, /* r5 */
606 u64 hipz_h_define_aqp1(const struct ipz_adapter_handle adapter_handle,
607 const struct ipz_qp_handle qp_handle,
609 u32 port, u32 * pma_qp_nr,
613 u64 outs[PLPAR_HCALL9_BUFSIZE];
615 ret = ehca_plpar_hcall9(H_DEFINE_AQP1, outs,
616 adapter_handle.handle, /* r4 */
617 qp_handle.handle, /* r5 */
620 *pma_qp_nr = (u32)outs[0];
621 *bma_qp_nr = (u32)outs[1];
623 if (ret == H_ALIAS_EXIST)
624 ehca_gen_err("AQP1 already exists. ret=%lx", ret);
629 u64 hipz_h_attach_mcqp(const struct ipz_adapter_handle adapter_handle,
630 const struct ipz_qp_handle qp_handle,
633 u64 subnet_prefix, u64 interface_id)
637 ret = ehca_plpar_hcall_norets(H_ATTACH_MCQP,
638 adapter_handle.handle, /* r4 */
639 qp_handle.handle, /* r5 */
641 interface_id, /* r7 */
642 subnet_prefix, /* r8 */
645 if (ret == H_NOT_ENOUGH_RESOURCES)
646 ehca_gen_err("Not enough resources. ret=%lx", ret);
651 u64 hipz_h_detach_mcqp(const struct ipz_adapter_handle adapter_handle,
652 const struct ipz_qp_handle qp_handle,
655 u64 subnet_prefix, u64 interface_id)
657 return ehca_plpar_hcall_norets(H_DETACH_MCQP,
658 adapter_handle.handle, /* r4 */
659 qp_handle.handle, /* r5 */
661 interface_id, /* r7 */
662 subnet_prefix, /* r8 */
666 u64 hipz_h_destroy_cq(const struct ipz_adapter_handle adapter_handle,
672 ret = hcp_galpas_dtor(&cq->galpas);
674 ehca_gen_err("Could not destruct cp->galpas");
678 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
679 adapter_handle.handle, /* r4 */
680 cq->ipz_cq_handle.handle, /* r5 */
681 force_flag != 0 ? 1L : 0L, /* r6 */
684 if (ret == H_RESOURCE)
685 ehca_gen_err("H_FREE_RESOURCE failed ret=%lx ", ret);
690 u64 hipz_h_destroy_eq(const struct ipz_adapter_handle adapter_handle,
695 ret = hcp_galpas_dtor(&eq->galpas);
697 ehca_gen_err("Could not destruct eq->galpas");
701 ret = ehca_plpar_hcall_norets(H_FREE_RESOURCE,
702 adapter_handle.handle, /* r4 */
703 eq->ipz_eq_handle.handle, /* r5 */
706 if (ret == H_RESOURCE)
707 ehca_gen_err("Resource in use. ret=%lx ", ret);
712 u64 hipz_h_alloc_resource_mr(const struct ipz_adapter_handle adapter_handle,
713 const struct ehca_mr *mr,
716 const u32 access_ctrl,
717 const struct ipz_pd pd,
718 struct ehca_mr_hipzout_parms *outparms)
721 u64 outs[PLPAR_HCALL9_BUFSIZE];
723 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
724 adapter_handle.handle, /* r4 */
728 (((u64)access_ctrl) << 32ULL), /* r8 */
731 outparms->handle.handle = outs[0];
732 outparms->lkey = (u32)outs[2];
733 outparms->rkey = (u32)outs[3];
738 u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle,
739 const struct ehca_mr *mr,
742 const u64 logical_address_of_page,
747 if ((count > 1) && (logical_address_of_page & (EHCA_PAGESIZE-1))) {
748 ehca_gen_err("logical_address_of_page not on a 4k boundary "
749 "adapter_handle=%lx mr=%p mr_handle=%lx "
750 "pagesize=%x queue_type=%x "
751 "logical_address_of_page=%lx count=%lx",
752 adapter_handle.handle, mr,
753 mr->ipz_mr_handle.handle, pagesize, queue_type,
754 logical_address_of_page, count);
757 ret = hipz_h_register_rpage(adapter_handle, pagesize,
759 mr->ipz_mr_handle.handle,
760 logical_address_of_page, count);
764 u64 hipz_h_query_mr(const struct ipz_adapter_handle adapter_handle,
765 const struct ehca_mr *mr,
766 struct ehca_mr_hipzout_parms *outparms)
769 u64 outs[PLPAR_HCALL9_BUFSIZE];
771 ret = ehca_plpar_hcall9(H_QUERY_MR, outs,
772 adapter_handle.handle, /* r4 */
773 mr->ipz_mr_handle.handle, /* r5 */
774 0, 0, 0, 0, 0, 0, 0);
775 outparms->len = outs[0];
776 outparms->vaddr = outs[1];
777 outparms->acl = outs[4] >> 32;
778 outparms->lkey = (u32)(outs[5] >> 32);
779 outparms->rkey = (u32)(outs[5] & (0xffffffff));
784 u64 hipz_h_free_resource_mr(const struct ipz_adapter_handle adapter_handle,
785 const struct ehca_mr *mr)
787 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
788 adapter_handle.handle, /* r4 */
789 mr->ipz_mr_handle.handle, /* r5 */
793 u64 hipz_h_reregister_pmr(const struct ipz_adapter_handle adapter_handle,
794 const struct ehca_mr *mr,
797 const u32 access_ctrl,
798 const struct ipz_pd pd,
799 const u64 mr_addr_cb,
800 struct ehca_mr_hipzout_parms *outparms)
803 u64 outs[PLPAR_HCALL9_BUFSIZE];
805 ret = ehca_plpar_hcall9(H_REREGISTER_PMR, outs,
806 adapter_handle.handle, /* r4 */
807 mr->ipz_mr_handle.handle, /* r5 */
811 ((((u64)access_ctrl) << 32ULL) | pd.value),
814 outparms->vaddr = outs[1];
815 outparms->lkey = (u32)outs[2];
816 outparms->rkey = (u32)outs[3];
821 u64 hipz_h_register_smr(const struct ipz_adapter_handle adapter_handle,
822 const struct ehca_mr *mr,
823 const struct ehca_mr *orig_mr,
825 const u32 access_ctrl,
826 const struct ipz_pd pd,
827 struct ehca_mr_hipzout_parms *outparms)
830 u64 outs[PLPAR_HCALL9_BUFSIZE];
832 ret = ehca_plpar_hcall9(H_REGISTER_SMR, outs,
833 adapter_handle.handle, /* r4 */
834 orig_mr->ipz_mr_handle.handle, /* r5 */
836 (((u64)access_ctrl) << 32ULL), /* r7 */
839 outparms->handle.handle = outs[0];
840 outparms->lkey = (u32)outs[2];
841 outparms->rkey = (u32)outs[3];
846 u64 hipz_h_alloc_resource_mw(const struct ipz_adapter_handle adapter_handle,
847 const struct ehca_mw *mw,
848 const struct ipz_pd pd,
849 struct ehca_mw_hipzout_parms *outparms)
852 u64 outs[PLPAR_HCALL9_BUFSIZE];
854 ret = ehca_plpar_hcall9(H_ALLOC_RESOURCE, outs,
855 adapter_handle.handle, /* r4 */
859 outparms->handle.handle = outs[0];
860 outparms->rkey = (u32)outs[3];
865 u64 hipz_h_query_mw(const struct ipz_adapter_handle adapter_handle,
866 const struct ehca_mw *mw,
867 struct ehca_mw_hipzout_parms *outparms)
870 u64 outs[PLPAR_HCALL9_BUFSIZE];
872 ret = ehca_plpar_hcall9(H_QUERY_MW, outs,
873 adapter_handle.handle, /* r4 */
874 mw->ipz_mw_handle.handle, /* r5 */
875 0, 0, 0, 0, 0, 0, 0);
876 outparms->rkey = (u32)outs[3];
881 u64 hipz_h_free_resource_mw(const struct ipz_adapter_handle adapter_handle,
882 const struct ehca_mw *mw)
884 return ehca_plpar_hcall_norets(H_FREE_RESOURCE,
885 adapter_handle.handle, /* r4 */
886 mw->ipz_mw_handle.handle, /* r5 */
890 u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle,
891 const u64 ressource_handle,
893 unsigned long *byte_count)
895 u64 r_cb = virt_to_abs(rblock);
897 if (r_cb & (EHCA_PAGESIZE-1)) {
898 ehca_gen_err("rblock not page aligned.");
902 return ehca_plpar_hcall_norets(H_ERROR_DATA,
903 adapter_handle.handle,