1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * 33 * HEADER: dapl.h 34 * 35 * PURPOSE: defines common data structures for the DAPL reference implemenation 36 * 37 * Description: This file describes the working data structures used within 38 * DAPL RI. 39 * 40 */ 41 42 #ifndef _DAPL_H_ 43 #define _DAPL_H_ 44 45 #ifdef __cplusplus 46 extern "C" { 47 #endif 48 49 #include <sys/types.h> 50 #include <sys/byteorder.h> 51 52 #include <dat/udat.h> 53 #include <dat/dat_registry.h> 54 #include "dapl_osd.h" 55 #include "dapl_debug.h" 56 #include "dapl_tavor_ibtf.h" 57 58 59 /* 60 * The HTOBE_xx() macro converts data from host order to big endian 61 * order and hence uses the BE_xx macros to do the byte swapping. 62 * 63 * The BETOH_xx() macro converts data from big endian order to host 64 * order. This is used when data is read from CQs or QPs. Due to the 65 * self-inversing nature of byte swapping routines BE_xx macros have 66 * the effect of converting big endian to host byte order which can 67 * be big endian or little endian. 68 * eg. On i386 BE_64(val64_be) = val64_le 69 * On sparc BE_64(val64_be) = val64_be. 70 * 71 * Tavor is a big endian device, all the buffer manipulation for 72 * QPs, CQs and the doorbell page needs to be aware of this. 73 * 74 */ 75 #if defined(__amd64) || defined(__i386) 76 /* use inline code to get performance of bswap* instructions */ 77 78 #if !defined(__lint) && defined(__GNUC__) 79 /* use GNU inline */ 80 /* works for both i386 and amd64 */ 81 extern __inline__ uint32_t dapls_byteswap32(uint32_t value) 82 { 83 __asm__("bswap %0" : "+r" (value)); 84 return (value); 85 } 86 87 #if defined(__amd64) 88 89 extern __inline__ uint64_t dapls_byteswap64(uint64_t value) 90 { 91 __asm__("bswapq %0" : "+r" (value)); 92 return (value); 93 } 94 95 #else /* defined(__i386) */ 96 97 extern __inline__ uint64_t dapls_byteswap64(uint64_t value) 98 { 99 union { 100 struct { uint32_t a, b; } s; 101 uint64_t u; 102 } v; 103 v.u = value; 104 __asm__("bswap %0 ; bswap %1 ; xchgl %0,%1" 105 : "=r" (v.s.a), "=r" (v.s.b) 106 : "0" (v.s.a), "1" (v.s.b)); 107 return (v.u); 108 } 109 #endif 110 111 #else /* !defined(__lint) && defined(__GNUC__) */ 112 /* use SUN inline with .il files */ 113 uint64_t dapls_byteswap64(uint64_t); 114 uint32_t dapls_byteswap32(uint32_t); 115 116 #endif /* !defined(__lint) && defined(__GNUC__) */ 117 118 #define HTOBE_64(x) dapls_byteswap64(x) 119 #define HTOBE_32(x) dapls_byteswap32(x) 120 #define BETOH_64(x) dapls_byteswap64(x) 121 #define BETOH_32(x) dapls_byteswap32(x) 122 123 #else /* defined(__amd64) || defined(__i386) */ 124 125 /* These are identity (do nothing) on big-endian machines. */ 126 127 #define HTOBE_64(x) BE_64((x)) 128 #define HTOBE_32(x) BE_32((x)) 129 #define BETOH_64(x) BE_64((x)) 130 #define BETOH_32(x) BE_32((x)) 131 132 #endif /* defined(__amd64) || defined(__i386) */ 133 134 /* 135 * 136 * Enumerations 137 * 138 */ 139 140 typedef enum dapl_magic { 141 /* magic number values for verification & debug */ 142 DAPL_MAGIC_IA = 0x1afeF00d, 143 DAPL_MAGIC_EVD = 0x2eedFace, 144 DAPL_MAGIC_EP = 0x3eadBabe, 145 DAPL_MAGIC_LMR = 0x4eefCafe, 146 DAPL_MAGIC_RMR = 0x5BadCafe, 147 DAPL_MAGIC_PZ = 0x6eafBeef, 148 DAPL_MAGIC_PSP = 0x7eadeD0c, 149 DAPL_MAGIC_RSP = 0x1ab4Feed, 150 DAPL_MAGIC_CR = 0x2e12Cee1, 151 DAPL_MAGIC_CR_DESTROYED = 0x312bDead, 152 DAPL_MAGIC_CNO = 0x4eadF00d, 153 DAPL_MAGIC_EP_EXIT = 0x5abeDead, 154 DAPL_MAGIC_SRQ = 0x5eedFace, 155 DAPL_MAGIC_INVALID = 0x6FFFFFFF 156 } DAPL_MAGIC; 157 158 typedef enum dapl_evd_state { 159 DAPL_EVD_STATE_TERMINAL, 160 DAPL_EVD_STATE_INITIAL, 161 DAPL_EVD_STATE_OPEN, 162 DAPL_EVD_STATE_WAITED, 163 DAPL_EVD_STATE_DEAD = 0xDEAD 164 } DAPL_EVD_STATE; 165 166 typedef enum dapl_evd_completion { 167 DAPL_EVD_STATE_INIT, 168 DAPL_EVD_STATE_SOLICITED_WAIT, 169 DAPL_EVD_STATE_THRESHOLD, 170 DAPL_EVD_STATE_UNSIGNALLED 171 } DAPL_EVD_COMPLETION; 172 173 typedef enum dapl_cno_state { 174 DAPL_CNO_STATE_UNTRIGGERED, 175 DAPL_CNO_STATE_TRIGGERED, 176 DAPL_CNO_STATE_DEAD = 0x7eadFeed 177 } DAPL_CNO_STATE; 178 179 typedef enum dapl_qp_state { 180 DAPL_QP_STATE_UNCONNECTED, 181 DAPL_QP_STATE_RESERVED, 182 DAPL_QP_STATE_PASSIVE_CONNECTION_PENDING, 183 DAPL_QP_STATE_ACTIVE_CONNECTION_PENDING, 184 DAPL_QP_STATE_TENTATIVE_CONNECTION_PENDING, 185 DAPL_QP_STATE_CONNECTED, 186 DAPL_QP_STATE_DISCONNECT_PENDING, 187 DAPL_QP_STATE_ERROR, 188 DAPL_QP_STATE_NOT_REUSABLE, 189 DAPL_QP_STATE_FREE 190 } DAPL_QP_STATE; 191 192 193 /* 194 * 195 * Constants 196 * 197 */ 198 199 /* 200 * number of HCAs allowed 201 */ 202 #define DAPL_MAX_HCA_COUNT 4 203 204 /* 205 * Configures the RMR bind evd restriction 206 */ 207 #define DAPL_RMR_BIND_EVD_RESTRICTION DAT_RMR_EVD_SAME_AS_REQUEST_EVD 208 209 /* 210 * special qp_state indicating the EP does not have a QP attached yet 211 */ 212 #define DAPL_QP_STATE_UNATTACHED 0xFFF0 213 214 /* 215 * 216 * Macros 217 * 218 */ 219 220 /* 221 * Simple macro to verify a handle is bad. 222 * - pointer's magic number is wrong 223 * - both pointer is NULL and not word aligned checked by the registry 224 */ 225 #define DAPL_BAD_HANDLE(h, magicNum) ( \ 226 (((DAPL_HEADER *)(h))->magic != (magicNum))) 227 228 #define DAPL_MIN(a, b) (((a) < (b)) ? (a) : (b)) 229 #define DAPL_MAX(a, b) (((a) > (b)) ? (a) : (b)) 230 231 #define DAT_ERROR(Type, SubType) \ 232 ((DAT_RETURN)(DAT_CLASS_ERROR | (Type) | (SubType))) 233 234 /* 235 * 236 * Typedefs 237 * 238 */ 239 240 typedef struct dapl_llist_entry DAPL_LLIST_ENTRY; 241 typedef DAPL_LLIST_ENTRY *DAPL_LLIST_HEAD; 242 typedef struct dapl_ring_buffer DAPL_RING_BUFFER; 243 typedef struct dapl_cookie_buffer DAPL_COOKIE_BUFFER; 244 245 typedef struct dapl_hash_table DAPL_HASH_TABLE; 246 typedef struct dapl_hash_table *DAPL_HASH_TABLEP; 247 typedef DAT_UINT64 DAPL_HASH_KEY; 248 typedef void *DAPL_HASH_DATA; 249 250 typedef struct dapl_hca DAPL_HCA; 251 252 typedef struct dapl_header DAPL_HEADER; 253 254 typedef struct dapl_ia DAPL_IA; 255 typedef struct dapl_cno DAPL_CNO; 256 typedef struct dapl_evd DAPL_EVD; 257 typedef struct dapl_ep DAPL_EP; 258 typedef struct dapl_pz DAPL_PZ; 259 typedef struct dapl_lmr DAPL_LMR; 260 typedef struct dapl_rmr DAPL_RMR; 261 typedef struct dapl_sp DAPL_SP; 262 typedef struct dapl_cr DAPL_CR; 263 typedef struct dapl_srq DAPL_SRQ; 264 265 typedef struct dapl_cookie DAPL_COOKIE; 266 typedef struct dapl_dto_cookie DAPL_DTO_COOKIE; 267 typedef struct dapl_rmr_cookie DAPL_RMR_COOKIE; 268 269 typedef void (*DAPL_CONNECTION_STATE_HANDLER)(IN DAPL_EP *, 270 IN ib_cm_events_t, 271 IN const void *, 272 OUT DAT_EVENT *); 273 274 275 /* 276 * 277 * Structures 278 * 279 */ 280 281 struct dapl_llist_entry { 282 struct dapl_llist_entry *flink; 283 struct dapl_llist_entry *blink; 284 void *data; 285 DAPL_LLIST_HEAD *list_head; /* for consistency checking */ 286 }; 287 288 struct dapl_ring_buffer { 289 void **base; /* base of element array */ 290 DAT_COUNT lim; /* mask, number of entries - 1 */ 291 DAPL_ATOMIC head; /* head pointer index */ 292 DAPL_ATOMIC tail; /* tail pointer index */ 293 DAPL_OS_LOCK lock; /* lock */ 294 }; 295 296 struct dapl_cookie_buffer { 297 DAPL_COOKIE *pool; 298 DAT_COUNT pool_size; 299 DAPL_ATOMIC head; 300 DAPL_ATOMIC tail; 301 }; 302 303 typedef DAT_RETURN (*DAPL_POST_SEND)(DAPL_EP *, ibt_send_wr_t *, boolean_t); 304 typedef DAT_RETURN (*DAPL_POST_RECV)(DAPL_EP *, ibt_recv_wr_t *, boolean_t); 305 typedef DAT_RETURN (*DAPL_POST_SRQ)(DAPL_SRQ *, ibt_recv_wr_t *, boolean_t); 306 typedef void (*DAPL_CQ_PEEK)(ib_cq_handle_t, int *); 307 typedef DAT_RETURN 308 (*DAPL_CQ_POLL)(ib_cq_handle_t, ibt_wc_t *, uint_t, uint_t *); 309 typedef DAT_RETURN (*DAPL_CQ_POLL_ONE)(ib_cq_handle_t, ibt_wc_t *); 310 typedef DAT_RETURN (*DAPL_CQ_NOTIFY)(ib_cq_handle_t, int, uint32_t); 311 typedef void (*DAPL_SRQ_FLUSH)(ib_qp_handle_t); 312 typedef void (*DAPL_QP_INIT)(ib_qp_handle_t); 313 typedef void (*DAPL_CQ_INIT)(ib_cq_handle_t); 314 typedef void (*DAPL_SRQ_INIT)(ib_srq_handle_t); 315 316 struct dapl_hca { 317 DAPL_OS_LOCK lock; 318 DAPL_LLIST_HEAD ia_list_head; 319 DAPL_EVD *async_evd; 320 DAPL_EVD *async_error_evd; 321 DAT_SOCK_ADDR6 hca_address; /* local address of HCA */ 322 /* Values specific to IB OS API */ 323 IB_HCA_NAME name; 324 ib_hca_handle_t ib_hca_handle; 325 DAPL_ATOMIC handle_ref_count; /* count of ia_opens on handle */ 326 ib_uint32_t port_num; /* number of physical port */ 327 ib_uint32_t partition_max; 328 ib_uint32_t partition_key; 329 ib_uint32_t tavor_idx; 330 ib_uint32_t hca_ibd_inst; 331 ib_guid_t node_GUID; 332 ib_lid_t lid; 333 int max_inline_send; 334 /* CQ support thread */ 335 ib_cqd_handle_t ib_cqd_handle; /* cq domain handle */ 336 ib_cq_handle_t null_ib_cq_handle; /* CQ handle with 0 entries */ 337 /* Memory Subsystem Support */ 338 DAPL_HASH_TABLE *lmr_hash_table; 339 /* Limits & useful HCA attributes */ 340 DAT_IA_ATTR ia_attr; 341 struct dapl_hca *hca_next; 342 DAPL_POST_SEND post_send; 343 DAPL_POST_RECV post_recv; 344 DAPL_POST_SRQ post_srq; 345 DAPL_CQ_PEEK cq_peek; 346 DAPL_CQ_POLL cq_poll; 347 DAPL_CQ_POLL_ONE cq_poll_one; 348 DAPL_CQ_NOTIFY cq_notify; 349 DAPL_SRQ_FLUSH srq_flush; 350 DAPL_QP_INIT qp_init; 351 DAPL_CQ_INIT cq_init; 352 DAPL_SRQ_INIT srq_init; 353 int hermon_resize_cq; 354 }; 355 356 #define DAPL_SEND(x) (x->header.owner_ia->hca_ptr->post_send) 357 #define DAPL_RECV(x) (x->header.owner_ia->hca_ptr->post_recv) 358 #define DAPL_SRECV(x) (x->header.owner_ia->hca_ptr->post_srq) 359 #define DAPL_PEEK(x) (x->header.owner_ia->hca_ptr->cq_peek) 360 #define DAPL_POLL(x) (x->header.owner_ia->hca_ptr->cq_poll) 361 #define DAPL_POLL1(x) (x->header.owner_ia->hca_ptr->cq_poll_one) 362 #define DAPL_NOTIFY(x) (x->header.owner_ia->hca_ptr->cq_notify) 363 #define DAPL_FLUSH(x) (x->header.owner_ia->hca_ptr->srq_flush) 364 #define DAPL_INIT_QP(x) (x->hca_ptr->qp_init) 365 #define DAPL_INIT_CQ(x) (x->hca_ptr->cq_init) 366 #define DAPL_INIT_SRQ(x) (x->hca_ptr->srq_init) 367 368 extern void dapls_init_funcs_tavor(DAPL_HCA *); 369 extern void dapls_init_funcs_arbel(DAPL_HCA *); 370 extern void dapls_init_funcs_hermon(DAPL_HCA *); 371 372 /* DAPL Objects always have the following header */ 373 struct dapl_header { 374 DAT_PROVIDER *provider; /* required by DAT - must be first */ 375 DAPL_MAGIC magic; /* magic number for verification */ 376 DAT_HANDLE_TYPE handle_type; /* struct type */ 377 DAPL_IA *owner_ia; /* ia which owns this struct */ 378 DAPL_LLIST_ENTRY ia_list_entry; /* link entry on ia struct */ 379 DAT_CONTEXT user_context; /* user context - opaque to DAPL */ 380 DAPL_OS_LOCK lock; /* lock - in header for easier macros */ 381 }; 382 383 enum DAPL_IA_FLAGS { 384 DAPL_DISABLE_RO = 1 /* Disable relaxed ordering */ 385 }; 386 387 /* DAPL_IA maps to DAT_IA_HANDLE */ 388 struct dapl_ia { 389 DAPL_HEADER header; 390 DAPL_HCA *hca_ptr; 391 DAPL_EVD *async_error_evd; 392 DAT_BOOLEAN cleanup_async_error_evd; 393 394 DAPL_LLIST_ENTRY hca_ia_list_entry; /* HCAs list of IAs */ 395 DAPL_LLIST_HEAD ep_list_head; /* EP queue */ 396 DAPL_LLIST_HEAD lmr_list_head; /* LMR queue */ 397 DAPL_LLIST_HEAD rmr_list_head; /* RMR queue */ 398 DAPL_LLIST_HEAD pz_list_head; /* PZ queue */ 399 DAPL_LLIST_HEAD evd_list_head; /* EVD queue */ 400 DAPL_LLIST_HEAD cno_list_head; /* CNO queue */ 401 DAPL_LLIST_HEAD psp_list_head; /* PSP queue */ 402 DAPL_LLIST_HEAD rsp_list_head; /* RSP queue */ 403 DAPL_LLIST_HEAD srq_list_head; /* SRQ queue */ 404 405 enum DAPL_IA_FLAGS dapl_flags; /* state flags, see above */ 406 }; 407 408 /* DAPL_CNO maps to DAT_CNO_HANDLE */ 409 struct dapl_cno { 410 DAPL_HEADER header; 411 412 /* A CNO cannot be freed while it is referenced elsewhere. */ 413 DAPL_ATOMIC cno_ref_count; 414 DAPL_CNO_STATE cno_state; 415 416 DAT_COUNT cno_waiters; 417 DAPL_EVD *cno_evd_triggered; 418 DAT_OS_WAIT_PROXY_AGENT cno_wait_agent; 419 420 DAPL_OS_WAIT_OBJECT cno_wait_object; 421 DAPL_LLIST_HEAD evd_list_head; 422 ib_cno_handle_t ib_cno_handle; 423 }; 424 425 /* DAPL_EVD maps to DAT_EVD_HANDLE */ 426 struct dapl_evd { 427 DAPL_HEADER header; 428 429 DAPL_EVD_STATE evd_state; 430 DAT_EVD_FLAGS evd_flags; 431 DAT_BOOLEAN evd_enabled; /* For attached CNO. */ 432 DAT_BOOLEAN evd_waitable; /* EVD state. */ 433 434 /* Derived from evd_flags; see dapls_evd_internal_create. */ 435 DAT_BOOLEAN evd_producer_locking_needed; 436 437 /* Every EVD has a CQ unless it is a SOFTWARE_EVENT only EVD */ 438 ib_cq_handle_t ib_cq_handle; 439 440 /* 441 * Mellanox Specific completion handle for 442 * registration/de-registration 443 */ 444 ib_comp_handle_t ib_comp_handle; 445 446 /* 447 * An Event Dispatcher cannot be freed while 448 * it is referenced elsewhere. 449 */ 450 DAPL_ATOMIC evd_ref_count; 451 452 /* Set if there has been a catastrophic overflow */ 453 DAT_BOOLEAN catastrophic_overflow; 454 455 /* the actual events */ 456 DAT_COUNT qlen; 457 DAT_EVENT *events; 458 DAPL_RING_BUFFER free_event_queue; 459 DAPL_RING_BUFFER pending_event_queue; 460 461 /* 462 * CQ Completions are not placed into 'deferred_events' 463 * rather they are simply left on the Completion Queue 464 * and the fact that there was a notification is flagged. 465 */ 466 DAT_BOOLEAN cq_notified; 467 DAPL_OS_TICKS cq_notified_when; 468 469 DAT_COUNT cno_active_count; 470 DAPL_CNO *cno_ptr; 471 472 DAPL_OS_WAIT_OBJECT wait_object; 473 DAT_COUNT threshold; 474 DAPL_LLIST_ENTRY cno_list_entry; 475 DAPL_EVD_COMPLETION completion_type; 476 }; 477 478 /* DAPL_EP maps to DAT_EP_HANDLE */ 479 struct dapl_ep { 480 DAPL_HEADER header; 481 /* What the DAT Consumer asked for */ 482 DAT_EP_PARAM param; 483 484 /* The RC Queue Pair (IBM OS API) */ 485 ib_qp_handle_t qp_handle; 486 unsigned int qpn; /* qp number */ 487 ib_qp_state_t qp_state; 488 489 /* communications manager handle (IBM OS API) */ 490 ib_cm_handle_t cm_handle; 491 /* 492 * store the remote IA address here, reference from the param 493 * struct which only has a pointer, no storage 494 */ 495 DAT_SOCK_ADDR6 remote_ia_address; 496 497 /* For passive connections we maintain a back pointer to the CR */ 498 void *cr_ptr; 499 500 /* private data container */ 501 unsigned char private_data[DAPL_MAX_PRIVATE_DATA_SIZE]; 502 503 /* DTO data */ 504 DAPL_ATOMIC req_count; 505 DAPL_ATOMIC recv_count; 506 507 DAPL_COOKIE_BUFFER req_buffer; 508 DAPL_COOKIE_BUFFER recv_buffer; 509 510 DAT_BOOLEAN srq_attached; 511 }; 512 513 /* DAPL_PZ maps to DAT_PZ_HANDLE */ 514 struct dapl_pz { 515 DAPL_HEADER header; 516 ib_pd_handle_t pd_handle; 517 DAPL_ATOMIC pz_ref_count; 518 }; 519 520 /* DAPL_LMR maps to DAT_LMR_HANDLE */ 521 struct dapl_lmr { 522 DAPL_HEADER header; 523 DAT_LMR_PARAM param; 524 ib_mr_handle_t mr_handle; 525 DAPL_ATOMIC lmr_ref_count; 526 }; 527 528 /* DAPL_RMR maps to DAT_RMR_HANDLE */ 529 struct dapl_rmr { 530 DAPL_HEADER header; 531 DAT_RMR_PARAM param; 532 DAPL_EP *ep; 533 DAPL_PZ *pz; 534 DAPL_LMR *lmr; 535 ib_mw_handle_t mw_handle; 536 }; 537 538 /* SP types, indicating the state and queue */ 539 typedef enum dapl_sp_state { 540 DAPL_SP_STATE_FREE, 541 DAPL_SP_STATE_PSP_LISTENING, 542 DAPL_SP_STATE_PSP_PENDING, 543 DAPL_SP_STATE_RSP_LISTENING, 544 DAPL_SP_STATE_RSP_PENDING 545 } DAPL_SP_STATE; 546 547 /* DAPL_SP maps to DAT_PSP_HANDLE and DAT_RSP_HANDLE */ 548 struct dapl_sp { 549 DAPL_HEADER header; 550 DAPL_SP_STATE state; /* type and queue of the SP */ 551 552 /* PSP/RSP PARAM fields */ 553 DAT_IA_HANDLE ia_handle; 554 DAT_CONN_QUAL conn_qual; 555 DAT_EVD_HANDLE evd_handle; 556 DAT_PSP_FLAGS psp_flags; 557 DAT_EP_HANDLE ep_handle; 558 559 /* maintenence fields */ 560 DAT_BOOLEAN listening; /* PSP is registered & active */ 561 ib_cm_srvc_handle_t cm_srvc_handle; /* Used by Mellanox CM */ 562 DAPL_LLIST_HEAD cr_list_head; /* CR pending queue */ 563 DAT_COUNT cr_list_count; /* count of CRs on queue */ 564 }; 565 566 /* DAPL_CR maps to DAT_CR_HANDLE */ 567 struct dapl_cr { 568 DAPL_HEADER header; 569 570 /* 571 * for convenience the data is kept as a DAT_CR_PARAM. 572 * however, the "local_endpoint" field is always NULL 573 * so this wastes a pointer. This is probably ok to 574 * simplify code, espedially dat_cr_query. 575 */ 576 DAT_CR_PARAM param; 577 /* IB specific fields */ 578 ib_cm_handle_t ib_cm_handle; 579 580 DAT_SOCK_ADDR6 remote_ia_address; 581 /* 582 * Assuming that the maximum private data size is small. 583 * If it gets large, use of a pointer may be appropriate. 584 */ 585 unsigned char private_data[DAPL_MAX_PRIVATE_DATA_SIZE]; 586 /* 587 * Need to be able to associate the CR back to the PSP for 588 * dapl_cr_reject. 589 */ 590 DAPL_SP *sp_ptr; 591 }; 592 593 /* DAPL_SRQ maps to DAT_SRQ_HANDLE */ 594 struct dapl_srq { 595 DAPL_HEADER header; 596 DAT_SRQ_PARAM param; 597 /* SRQ cannot be freed till EPs attached to srq are freed */ 598 DAPL_ATOMIC srq_ref_count; 599 ib_srq_handle_t srq_handle; 600 /* DTO data */ 601 DAPL_ATOMIC recv_count; 602 DAPL_COOKIE_BUFFER recv_buffer; 603 }; 604 605 typedef enum dapl_dto_type { 606 DAPL_DTO_TYPE_SEND, 607 DAPL_DTO_TYPE_RECV, 608 DAPL_DTO_TYPE_RDMA_WRITE, 609 DAPL_DTO_TYPE_RDMA_READ 610 } DAPL_DTO_TYPE; 611 612 typedef enum dapl_cookie_type { 613 DAPL_COOKIE_TYPE_NULL, 614 DAPL_COOKIE_TYPE_DTO, 615 DAPL_COOKIE_TYPE_RMR 616 } DAPL_COOKIE_TYPE; 617 618 /* DAPL_DTO_COOKIE used as context for DTO WQEs */ 619 struct dapl_dto_cookie { 620 DAPL_DTO_TYPE type; 621 DAT_DTO_COOKIE cookie; 622 DAT_COUNT size; /* used for SEND and RDMA write */ 623 }; 624 625 /* DAPL_RMR_COOKIE used as context for bind WQEs */ 626 struct dapl_rmr_cookie { 627 DAPL_RMR *rmr; 628 DAT_RMR_COOKIE cookie; 629 }; 630 631 typedef enum dapl_cookie_queue_type { 632 DAPL_COOKIE_QUEUE_EP, 633 DAPL_COOKIE_QUEUE_SRQ 634 } DAPL_COOKIE_QUEUE_TYPE; 635 636 /* DAPL_COOKIE used as context for WQEs */ 637 struct dapl_cookie { 638 DAPL_COOKIE_TYPE type; /* Must be first, to define struct. */ 639 DAPL_COOKIE_QUEUE_TYPE queue_type; 640 union { 641 void *ptr; 642 DAPL_EP *ep; 643 DAPL_SRQ *srq; 644 } queue; 645 DAT_COUNT index; 646 union { 647 DAPL_DTO_COOKIE dto; 648 DAPL_RMR_COOKIE rmr; 649 } val; 650 }; 651 652 /* 653 * Generic HCA name field 654 */ 655 #define DAPL_HCA_NAME_MAX_LEN 260 656 typedef char DAPL_HCA_NAME[DAPL_HCA_NAME_MAX_LEN + 1]; 657 658 #if defined(IBHOSTS_NAMING) 659 660 /* 661 * Simple mapping table to match IP addresses to GIDs. Loaded 662 * by dapl_init. 663 */ 664 typedef struct _dapl_gid_map_table { 665 uint32_t ip_address; 666 ib_gid_t gid; 667 } DAPL_GID_MAP; 668 669 #endif /* IBHOSTS_NAMING */ 670 671 /* 672 * 673 * Function Prototypes 674 * 675 */ 676 677 /* 678 * DAT Mandated functions 679 */ 680 extern DAT_RETURN 681 dapl_ia_open( 682 IN const DAT_NAME_PTR, /* name */ 683 IN DAT_COUNT, /* asynch_evd_qlen */ 684 INOUT DAT_EVD_HANDLE *, /* asynch_evd_handle */ 685 OUT DAT_IA_HANDLE *, /* ia_handle */ 686 IN boolean_t); /* ro_aware_client */ 687 688 extern DAT_RETURN 689 dapl_ia_close( 690 IN DAT_IA_HANDLE, /* ia_handle */ 691 IN DAT_CLOSE_FLAGS); /* ia_flags */ 692 693 694 extern DAT_RETURN 695 dapl_ia_query( 696 IN DAT_IA_HANDLE, /* ia handle */ 697 OUT DAT_EVD_HANDLE *, /* async_evd_handle */ 698 IN DAT_IA_ATTR_MASK, /* ia_params_mask */ 699 OUT DAT_IA_ATTR *, /* ia_params */ 700 IN DAT_PROVIDER_ATTR_MASK, /* provider_params_mask */ 701 OUT DAT_PROVIDER_ATTR *); /* provider_params */ 702 703 704 /* helper functions */ 705 extern DAT_RETURN 706 dapl_set_consumer_context( 707 IN DAT_HANDLE, /* dat handle */ 708 IN DAT_CONTEXT); /* context */ 709 710 extern DAT_RETURN 711 dapl_get_consumer_context( 712 IN DAT_HANDLE, /* dat handle */ 713 OUT DAT_CONTEXT *); /* context */ 714 715 extern DAT_RETURN 716 dapl_get_handle_type( 717 IN DAT_HANDLE, 718 OUT DAT_HANDLE_TYPE *); 719 720 721 /* CNO functions */ 722 extern DAT_RETURN 723 dapl_cno_create( 724 IN DAT_IA_HANDLE, /* ia_handle */ 725 IN DAT_OS_WAIT_PROXY_AGENT, /* agent */ 726 OUT DAT_CNO_HANDLE *); /* cno_handle */ 727 728 extern DAT_RETURN 729 dapl_cno_modify_agent( 730 IN DAT_CNO_HANDLE, /* cno_handle */ 731 IN DAT_OS_WAIT_PROXY_AGENT); /* agent */ 732 733 extern DAT_RETURN 734 dapl_cno_query( 735 IN DAT_CNO_HANDLE, /* cno_handle */ 736 IN DAT_CNO_PARAM_MASK, /* cno_param_mask */ 737 OUT DAT_CNO_PARAM *); /* cno_param */ 738 739 extern DAT_RETURN 740 dapl_cno_free(IN DAT_CNO_HANDLE); /* cno_handle */ 741 742 extern DAT_RETURN 743 dapl_cno_wait( 744 IN DAT_CNO_HANDLE, /* cno_handle */ 745 IN DAT_TIMEOUT, /* timeout */ 746 OUT DAT_EVD_HANDLE *); /* evd_handle */ 747 748 749 /* CR Functions */ 750 extern DAT_RETURN 751 dapl_cr_query( 752 IN DAT_CR_HANDLE, /* cr_handle */ 753 IN DAT_CR_PARAM_MASK, /* cr_args_mask */ 754 OUT DAT_CR_PARAM *); /* cwr_args */ 755 756 extern DAT_RETURN 757 dapl_cr_accept( 758 IN DAT_CR_HANDLE, /* cr_handle */ 759 IN DAT_EP_HANDLE, /* ep_handle */ 760 IN DAT_COUNT, /* private_data_size */ 761 IN const DAT_PVOID); /* private_data */ 762 763 extern DAT_RETURN 764 dapl_cr_reject(IN DAT_CR_HANDLE); 765 766 extern DAT_RETURN 767 dapl_cr_handoff( 768 IN DAT_CR_HANDLE, /* cr_handle */ 769 IN DAT_CONN_QUAL); /* handoff */ 770 771 /* EVD Functions */ 772 extern DAT_RETURN 773 dapl_evd_create( 774 IN DAT_IA_HANDLE, /* ia_handle */ 775 IN DAT_COUNT, /* evd_min_qlen */ 776 IN DAT_CNO_HANDLE, /* cno_handle */ 777 IN DAT_EVD_FLAGS, /* evd_flags */ 778 OUT DAT_EVD_HANDLE *); /* evd_handle */ 779 780 extern DAT_RETURN 781 dapl_evd_query( 782 IN DAT_EVD_HANDLE, /* evd_handle */ 783 IN DAT_EVD_PARAM_MASK, /* evd_args_mask */ 784 OUT DAT_EVD_PARAM *); /* evd_args */ 785 786 #if 0 /* kdapl */ 787 extern DAT_RETURN 788 dapl_evd_modify_upcall( 789 IN DAT_EVD_HANDLE, /* evd_handle */ 790 IN DAT_UPCALL_POLICY, /* upcall_policy */ 791 IN DAT_UPCALL_OBJECT); /* upcall */ 792 #else 793 794 extern DAT_RETURN 795 dapl_evd_modify_cno( 796 IN DAT_EVD_HANDLE, /* evd_handle */ 797 IN DAT_CNO_HANDLE); /* cno_handle */ 798 799 extern DAT_RETURN 800 dapl_evd_enable(IN DAT_EVD_HANDLE); /* evd_handle */ 801 802 extern DAT_RETURN 803 dapl_evd_disable(IN DAT_EVD_HANDLE); /* evd_handle */ 804 805 extern DAT_RETURN 806 dapl_evd_wait( 807 IN DAT_EVD_HANDLE, /* evd_handle */ 808 IN DAT_TIMEOUT, /* timeout */ 809 IN DAT_COUNT, /* threshold */ 810 OUT DAT_EVENT *, /* event */ 811 OUT DAT_COUNT *); /* nmore */ 812 #endif 813 814 extern DAT_RETURN 815 dapl_evd_resize( 816 IN DAT_EVD_HANDLE, /* evd_handle */ 817 IN DAT_COUNT); /* evd_qlen */ 818 819 extern DAT_RETURN 820 dapl_evd_wait( 821 IN DAT_EVD_HANDLE, /* evd_handle */ 822 IN DAT_TIMEOUT, /* timeout */ 823 IN DAT_COUNT, /* threshold */ 824 OUT DAT_EVENT *, /* event */ 825 OUT DAT_COUNT *); /* nmore */ 826 827 extern DAT_RETURN 828 dapl_evd_post_se( 829 DAT_EVD_HANDLE, /* evd_handle */ 830 const DAT_EVENT *); /* event */ 831 832 extern DAT_RETURN 833 dapl_evd_dequeue( 834 IN DAT_EVD_HANDLE, /* evd_handle */ 835 OUT DAT_EVENT *); /* event */ 836 837 extern DAT_RETURN 838 dapl_evd_free(IN DAT_EVD_HANDLE); 839 840 extern DAT_RETURN 841 dapl_evd_set_unwaitable(IN DAT_EVD_HANDLE evd_handle); 842 843 extern DAT_RETURN 844 dapl_evd_clear_unwaitable(IN DAT_EVD_HANDLE evd_handle); 845 846 847 /* EP functions */ 848 extern DAT_RETURN 849 dapl_ep_create( 850 IN DAT_IA_HANDLE, /* ia_handle */ 851 IN DAT_PZ_HANDLE, /* pz_handle */ 852 IN DAT_EVD_HANDLE, /* in_dto_completion_evd_handle */ 853 IN DAT_EVD_HANDLE, /* out_dto_completion_evd_handle */ 854 IN DAT_EVD_HANDLE, /* connect_evd_handle */ 855 IN const DAT_EP_ATTR *, /* ep_parameters */ 856 OUT DAT_EP_HANDLE *); /* ep_handle */ 857 858 extern DAT_RETURN 859 dapl_ep_query( 860 IN DAT_EP_HANDLE, /* ep_handle */ 861 IN DAT_EP_PARAM_MASK, /* ep_args_mask */ 862 OUT DAT_EP_PARAM *); /* ep_args */ 863 864 extern DAT_RETURN 865 dapl_ep_modify( 866 IN DAT_EP_HANDLE, /* ep_handle */ 867 IN DAT_EP_PARAM_MASK, /* ep_args_mask */ 868 IN const DAT_EP_PARAM *); /* ep_args */ 869 870 extern DAT_RETURN 871 dapl_ep_connect( 872 IN DAT_EP_HANDLE, /* ep_handle */ 873 IN DAT_IA_ADDRESS_PTR, /* remote_ia_address */ 874 IN DAT_CONN_QUAL, /* remote_conn_qual */ 875 IN DAT_TIMEOUT, /* timeout */ 876 IN DAT_COUNT, /* private_data_size */ 877 IN const DAT_PVOID, /* private_data */ 878 IN DAT_QOS, /* quality_of_service */ 879 IN DAT_CONNECT_FLAGS); /* connect_flags */ 880 881 extern DAT_RETURN 882 dapl_ep_dup_connect( 883 IN DAT_EP_HANDLE, /* ep_handle */ 884 IN DAT_EP_HANDLE, /* ep_dup_handle */ 885 IN DAT_TIMEOUT, /* timeout */ 886 IN DAT_COUNT, /* private_data_size */ 887 IN const DAT_PVOID, /* private_data */ 888 IN DAT_QOS); /* quality_of_service */ 889 890 extern DAT_RETURN 891 dapl_ep_disconnect( 892 IN DAT_EP_HANDLE, /* ep_handle */ 893 IN DAT_CLOSE_FLAGS); /* completion_flags */ 894 895 extern DAT_RETURN 896 dapl_ep_post_send( 897 IN DAT_EP_HANDLE, /* ep_handle */ 898 IN DAT_COUNT, /* num_segments */ 899 IN DAT_LMR_TRIPLET *, /* local_iov */ 900 IN DAT_DTO_COOKIE, /* user_cookie */ 901 IN DAT_COMPLETION_FLAGS); /* completion_flags */ 902 903 extern DAT_RETURN 904 dapl_ep_post_recv( 905 IN DAT_EP_HANDLE, /* ep_handle */ 906 IN DAT_COUNT, /* num_segments */ 907 IN DAT_LMR_TRIPLET *, /* local_iov */ 908 IN DAT_DTO_COOKIE, /* user_cookie */ 909 IN DAT_COMPLETION_FLAGS); /* completion_flags */ 910 911 extern DAT_RETURN 912 dapl_ep_post_rdma_read( 913 IN DAT_EP_HANDLE, /* ep_handle */ 914 IN DAT_COUNT, /* num_segments */ 915 IN DAT_LMR_TRIPLET *, /* local_iov */ 916 IN DAT_DTO_COOKIE, /* user_cookie */ 917 IN const DAT_RMR_TRIPLET *, /* remote_iov */ 918 IN DAT_COMPLETION_FLAGS); /* completion_flags */ 919 920 extern DAT_RETURN 921 dapl_ep_post_rdma_write( 922 IN DAT_EP_HANDLE, /* ep_handle */ 923 IN DAT_COUNT, /* num_segments */ 924 IN DAT_LMR_TRIPLET *, /* local_iov */ 925 IN DAT_DTO_COOKIE, /* user_cookie */ 926 IN const DAT_RMR_TRIPLET *, /* remote_iov */ 927 IN DAT_COMPLETION_FLAGS); /* completion_flags */ 928 929 extern DAT_RETURN 930 dapl_ep_get_status( 931 IN DAT_EP_HANDLE, /* ep_handle */ 932 OUT DAT_EP_STATE *, /* ep_state */ 933 OUT DAT_BOOLEAN *, /* in_dto_idle */ 934 OUT DAT_BOOLEAN *); /* out_dto_idle */ 935 936 extern DAT_RETURN 937 dapl_ep_free(IN DAT_EP_HANDLE); /* ep_handle */ 938 939 extern DAT_RETURN 940 dapl_ep_reset(IN DAT_EP_HANDLE); /* ep_handle */ 941 942 943 /* LMR functions */ 944 extern DAT_RETURN 945 dapl_lmr_create( 946 IN DAT_IA_HANDLE, /* ia_handle */ 947 IN DAT_MEM_TYPE, /* mem_type */ 948 IN DAT_REGION_DESCRIPTION, /* region_description */ 949 IN DAT_VLEN, /* length */ 950 IN DAT_PZ_HANDLE, /* pz_handle */ 951 IN DAT_MEM_PRIV_FLAGS, /* privileges */ 952 OUT DAT_LMR_HANDLE *, /* lmr_handle */ 953 OUT DAT_LMR_CONTEXT *, /* lmr_context */ 954 OUT DAT_RMR_CONTEXT *, /* rmr_context */ 955 OUT DAT_VLEN *, /* registered_length */ 956 OUT DAT_VADDR *); /* registered_address */ 957 958 extern DAT_RETURN 959 dapl_lmr_query( 960 IN DAT_LMR_HANDLE, 961 IN DAT_LMR_PARAM_MASK, 962 OUT DAT_LMR_PARAM *); 963 964 extern DAT_RETURN 965 dapl_lmr_free(IN DAT_LMR_HANDLE); 966 967 968 /* RMR Functions */ 969 extern DAT_RETURN 970 dapl_rmr_create( 971 IN DAT_PZ_HANDLE, /* pz_handle */ 972 OUT DAT_RMR_HANDLE *); /* rmr_handle */ 973 974 extern DAT_RETURN 975 dapl_rmr_query( 976 IN DAT_RMR_HANDLE, /* rmr_handle */ 977 IN DAT_RMR_PARAM_MASK, /* rmr_args_mask */ 978 OUT DAT_RMR_PARAM *); /* rmr_args */ 979 980 extern DAT_RETURN 981 dapl_rmr_bind( 982 IN DAT_RMR_HANDLE, /* rmr_handle */ 983 IN const DAT_LMR_TRIPLET *, /* lmr_triplet */ 984 IN DAT_MEM_PRIV_FLAGS, /* mem_priv */ 985 IN DAT_EP_HANDLE, /* ep_handle */ 986 IN DAT_RMR_COOKIE, /* user_cookie */ 987 IN DAT_COMPLETION_FLAGS, /* completion_flags */ 988 INOUT DAT_RMR_CONTEXT *); /* context */ 989 990 extern DAT_RETURN 991 dapl_rmr_free(IN DAT_RMR_HANDLE); 992 993 994 /* PSP Functions */ 995 extern DAT_RETURN 996 dapl_psp_create( 997 IN DAT_IA_HANDLE, /* ia_handle */ 998 IN DAT_CONN_QUAL, /* conn_qual */ 999 IN DAT_EVD_HANDLE, /* evd_handle */ 1000 IN DAT_PSP_FLAGS, /* psp_flags */ 1001 OUT DAT_PSP_HANDLE *); /* psp_handle */ 1002 1003 extern DAT_RETURN 1004 dapl_psp_create_any( 1005 IN DAT_IA_HANDLE, /* ia_handle */ 1006 OUT DAT_CONN_QUAL *, /* conn_qual */ 1007 IN DAT_EVD_HANDLE, /* evd_handle */ 1008 IN DAT_PSP_FLAGS, /* psp_flags */ 1009 OUT DAT_PSP_HANDLE *); /* psp_handle */ 1010 1011 extern DAT_RETURN 1012 dapl_psp_query( 1013 IN DAT_PSP_HANDLE, 1014 IN DAT_PSP_PARAM_MASK, 1015 OUT DAT_PSP_PARAM *); 1016 1017 extern DAT_RETURN 1018 dapl_psp_free(IN DAT_PSP_HANDLE); /* psp_handle */ 1019 1020 1021 /* RSP Functions */ 1022 extern DAT_RETURN 1023 dapl_rsp_create( 1024 IN DAT_IA_HANDLE, /* ia_handle */ 1025 IN DAT_CONN_QUAL, /* conn_qual */ 1026 IN DAT_EP_HANDLE, /* ep_handle */ 1027 IN DAT_EVD_HANDLE, /* evd_handle */ 1028 OUT DAT_RSP_HANDLE *); /* rsp_handle */ 1029 1030 extern DAT_RETURN 1031 dapl_rsp_query( 1032 IN DAT_RSP_HANDLE, 1033 IN DAT_RSP_PARAM_MASK, 1034 OUT DAT_RSP_PARAM *); 1035 1036 extern DAT_RETURN 1037 dapl_rsp_free(IN DAT_RSP_HANDLE); /* rsp_handle */ 1038 1039 1040 /* PZ Functions */ 1041 extern DAT_RETURN 1042 dapl_pz_create( 1043 IN DAT_IA_HANDLE, /* ia_handle */ 1044 OUT DAT_PZ_HANDLE *); /* pz_handle */ 1045 1046 extern DAT_RETURN 1047 dapl_pz_query( 1048 IN DAT_PZ_HANDLE, /* pz_handle */ 1049 IN DAT_PZ_PARAM_MASK, /* pz_args_mask */ 1050 OUT DAT_PZ_PARAM *); /* pz_args */ 1051 1052 extern DAT_RETURN 1053 dapl_pz_free(IN DAT_PZ_HANDLE); /* pz_handle */ 1054 1055 /* Non-coherent memory fucntions */ 1056 1057 extern DAT_RETURN dapl_lmr_sync_rdma_read( 1058 IN DAT_IA_HANDLE, /* ia_handle */ 1059 IN const DAT_LMR_TRIPLET *, /* local_segments */ 1060 IN DAT_VLEN); /* num_segments */ 1061 1062 extern DAT_RETURN dapl_lmr_sync_rdma_write( 1063 IN DAT_IA_HANDLE, /* ia_handle */ 1064 IN const DAT_LMR_TRIPLET *, /* local_segments */ 1065 IN DAT_VLEN); /* num_segments */ 1066 1067 /* 1068 * SRQ functions 1069 */ 1070 extern DAT_RETURN dapl_ep_create_with_srq( 1071 IN DAT_IA_HANDLE, /* ia_handle */ 1072 IN DAT_PZ_HANDLE, /* pz_handle */ 1073 IN DAT_EVD_HANDLE, /* recv_evd_handle */ 1074 IN DAT_EVD_HANDLE, /* request_evd_handle */ 1075 IN DAT_EVD_HANDLE, /* connect_evd_handle */ 1076 IN DAT_SRQ_HANDLE, /* srq_handle */ 1077 IN const DAT_EP_ATTR *, /* ep_attributes */ 1078 OUT DAT_EP_HANDLE *); /* ep_handle */ 1079 1080 extern DAT_RETURN dapl_ep_recv_query( 1081 IN DAT_EP_HANDLE, /* ep_handle */ 1082 OUT DAT_COUNT *, /* nbufs_allocated */ 1083 OUT DAT_COUNT *); /* bufs_alloc_span */ 1084 1085 extern DAT_RETURN dapl_ep_set_watermark( 1086 IN DAT_EP_HANDLE, /* ep_handle */ 1087 IN DAT_COUNT, /* soft_high_watermark */ 1088 IN DAT_COUNT); /* hard_high_watermark */ 1089 1090 extern DAT_RETURN dapl_srq_create( 1091 IN DAT_IA_HANDLE, /* ia_handle */ 1092 IN DAT_PZ_HANDLE, /* pz_handle */ 1093 IN DAT_SRQ_ATTR *, /* srq_attr */ 1094 OUT DAT_SRQ_HANDLE *); /* srq_handle */ 1095 1096 extern DAT_RETURN dapl_srq_free( 1097 IN DAT_SRQ_HANDLE); /* srq_handle */ 1098 1099 extern DAT_RETURN dapl_srq_post_recv( 1100 IN DAT_SRQ_HANDLE, /* srq_handle */ 1101 IN DAT_COUNT, /* num_segments */ 1102 IN DAT_LMR_TRIPLET *, /* local_iov */ 1103 IN DAT_DTO_COOKIE); /* user_cookie */ 1104 1105 extern DAT_RETURN dapl_srq_query( 1106 IN DAT_SRQ_HANDLE, /* srq_handle */ 1107 IN DAT_SRQ_PARAM_MASK, /* srq_param_mask */ 1108 OUT DAT_SRQ_PARAM *); /* srq_param */ 1109 1110 extern DAT_RETURN dapl_srq_resize( 1111 IN DAT_SRQ_HANDLE, /* srq_handle */ 1112 IN DAT_COUNT); /* srq_max_recv_dto */ 1113 1114 extern DAT_RETURN dapl_srq_set_lw( 1115 IN DAT_SRQ_HANDLE, /* srq_handle */ 1116 IN DAT_COUNT); /* low_watermark */ 1117 1118 1119 /* 1120 * DAPL internal utility function prototpyes 1121 */ 1122 extern void 1123 dapl_llist_init_head(DAPL_LLIST_HEAD *head); 1124 1125 extern void 1126 dapl_llist_init_entry(DAPL_LLIST_ENTRY *entry); 1127 1128 extern DAT_BOOLEAN 1129 dapl_llist_is_empty(DAPL_LLIST_HEAD *head); 1130 1131 extern void 1132 dapl_llist_add_head( 1133 DAPL_LLIST_HEAD *head, 1134 DAPL_LLIST_ENTRY *entry, 1135 void *data); 1136 1137 extern void 1138 dapl_llist_add_tail( 1139 DAPL_LLIST_HEAD *head, 1140 DAPL_LLIST_ENTRY *entry, 1141 void *data); 1142 1143 extern void 1144 dapl_llist_add_entry( 1145 DAPL_LLIST_HEAD *head, 1146 DAPL_LLIST_ENTRY *entry, 1147 DAPL_LLIST_ENTRY *new_entry, 1148 void *data); 1149 1150 extern void * 1151 dapl_llist_remove_head(DAPL_LLIST_HEAD *head); 1152 1153 extern void * 1154 dapl_llist_remove_tail(DAPL_LLIST_HEAD *head); 1155 1156 extern void * 1157 dapl_llist_remove_entry(DAPL_LLIST_HEAD *head, 1158 DAPL_LLIST_ENTRY *entry); 1159 1160 extern void * 1161 dapl_llist_peek_head(DAPL_LLIST_HEAD *head); 1162 1163 extern void * 1164 dapl_llist_next_entry( 1165 IN DAPL_LLIST_HEAD *head, 1166 IN DAPL_LLIST_ENTRY *cur_ent); 1167 1168 extern void 1169 dapl_llist_debug_print_list(DAPL_LLIST_HEAD *head); 1170 1171 #ifdef __cplusplus 1172 } 1173 #endif 1174 1175 #endif /* _DAPL_H_ */ 1176