00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <stdint.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <unistd.h>
00026 #include <byteswap.h>
00027 #include <errno.h>
00028 #include <assert.h>
00029 #include <gpxe/list.h>
00030 #include <gpxe/errortab.h>
00031 #include <gpxe/if_arp.h>
00032 #include <gpxe/netdevice.h>
00033 #include <gpxe/iobuf.h>
00034 #include <gpxe/ipoib.h>
00035 #include <gpxe/process.h>
00036 #include <gpxe/infiniband.h>
00037 #include <gpxe/ib_mi.h>
00038 #include <gpxe/ib_sma.h>
00039
00040
00041
00042
00043
00044
00045
00046
00047 struct list_head ib_devices = LIST_HEAD_INIT ( ib_devices );
00048
00049
00050 static struct list_head open_ib_devices = LIST_HEAD_INIT ( open_ib_devices );
00051
00052
00053 #define EINPROGRESS_INIT ( EINPROGRESS | EUNIQ_01 )
00054 #define EINPROGRESS_ARMED ( EINPROGRESS | EUNIQ_02 )
00055
00056
00057 struct errortab infiniband_errors[] __errortab = {
00058 { EINPROGRESS_INIT, "Initialising" },
00059 { EINPROGRESS_ARMED, "Armed" },
00060 };
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 struct ib_completion_queue *
00078 ib_create_cq ( struct ib_device *ibdev, unsigned int num_cqes,
00079 struct ib_completion_queue_operations *op ) {
00080 struct ib_completion_queue *cq;
00081 int rc;
00082
00083 DBGC ( ibdev, "IBDEV %p creating completion queue\n", ibdev );
00084
00085
00086 cq = zalloc ( sizeof ( *cq ) );
00087 if ( ! cq )
00088 goto err_alloc_cq;
00089 cq->ibdev = ibdev;
00090 list_add ( &cq->list, &ibdev->cqs );
00091 cq->num_cqes = num_cqes;
00092 INIT_LIST_HEAD ( &cq->work_queues );
00093 cq->op = op;
00094
00095
00096 if ( ( rc = ibdev->op->create_cq ( ibdev, cq ) ) != 0 ) {
00097 DBGC ( ibdev, "IBDEV %p could not initialise completion "
00098 "queue: %s\n", ibdev, strerror ( rc ) );
00099 goto err_dev_create_cq;
00100 }
00101
00102 DBGC ( ibdev, "IBDEV %p created %d-entry completion queue %p (%p) "
00103 "with CQN %#lx\n", ibdev, num_cqes, cq,
00104 ib_cq_get_drvdata ( cq ), cq->cqn );
00105 return cq;
00106
00107 ibdev->op->destroy_cq ( ibdev, cq );
00108 err_dev_create_cq:
00109 list_del ( &cq->list );
00110 free ( cq );
00111 err_alloc_cq:
00112 return NULL;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121 void ib_destroy_cq ( struct ib_device *ibdev,
00122 struct ib_completion_queue *cq ) {
00123 DBGC ( ibdev, "IBDEV %p destroying completion queue %#lx\n",
00124 ibdev, cq->cqn );
00125 assert ( list_empty ( &cq->work_queues ) );
00126 ibdev->op->destroy_cq ( ibdev, cq );
00127 list_del ( &cq->list );
00128 free ( cq );
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 void ib_poll_cq ( struct ib_device *ibdev,
00138 struct ib_completion_queue *cq ) {
00139 struct ib_work_queue *wq;
00140
00141
00142 ibdev->op->poll_cq ( ibdev, cq );
00143
00144
00145 list_for_each_entry ( wq, &cq->work_queues, list ) {
00146 if ( ! wq->is_send )
00147 ib_refill_recv ( ibdev, wq->qp );
00148 }
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 struct ib_queue_pair * ib_create_qp ( struct ib_device *ibdev,
00173 enum ib_queue_pair_type type,
00174 unsigned int num_send_wqes,
00175 struct ib_completion_queue *send_cq,
00176 unsigned int num_recv_wqes,
00177 struct ib_completion_queue *recv_cq ) {
00178 struct ib_queue_pair *qp;
00179 size_t total_size;
00180 int rc;
00181
00182 DBGC ( ibdev, "IBDEV %p creating queue pair\n", ibdev );
00183
00184
00185 total_size = ( sizeof ( *qp ) +
00186 ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ) +
00187 ( num_recv_wqes * sizeof ( qp->recv.iobufs[0] ) ) );
00188 qp = zalloc ( total_size );
00189 if ( ! qp )
00190 goto err_alloc_qp;
00191 qp->ibdev = ibdev;
00192 list_add ( &qp->list, &ibdev->qps );
00193 qp->type = type;
00194 qp->send.qp = qp;
00195 qp->send.is_send = 1;
00196 qp->send.cq = send_cq;
00197 list_add ( &qp->send.list, &send_cq->work_queues );
00198 qp->send.psn = ( random() & 0xffffffUL );
00199 qp->send.num_wqes = num_send_wqes;
00200 qp->send.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) );
00201 qp->recv.qp = qp;
00202 qp->recv.cq = recv_cq;
00203 list_add ( &qp->recv.list, &recv_cq->work_queues );
00204 qp->recv.psn = ( random() & 0xffffffUL );
00205 qp->recv.num_wqes = num_recv_wqes;
00206 qp->recv.iobufs = ( ( ( void * ) qp ) + sizeof ( *qp ) +
00207 ( num_send_wqes * sizeof ( qp->send.iobufs[0] ) ));
00208 INIT_LIST_HEAD ( &qp->mgids );
00209
00210
00211 if ( ( rc = ibdev->op->create_qp ( ibdev, qp ) ) != 0 ) {
00212 DBGC ( ibdev, "IBDEV %p could not initialise queue pair: "
00213 "%s\n", ibdev, strerror ( rc ) );
00214 goto err_dev_create_qp;
00215 }
00216 DBGC ( ibdev, "IBDEV %p created queue pair %p (%p) with QPN %#lx\n",
00217 ibdev, qp, ib_qp_get_drvdata ( qp ), qp->qpn );
00218 DBGC ( ibdev, "IBDEV %p QPN %#lx has %d send entries at [%p,%p)\n",
00219 ibdev, qp->qpn, num_send_wqes, qp->send.iobufs,
00220 qp->recv.iobufs );
00221 DBGC ( ibdev, "IBDEV %p QPN %#lx has %d receive entries at [%p,%p)\n",
00222 ibdev, qp->qpn, num_recv_wqes, qp->recv.iobufs,
00223 ( ( ( void * ) qp ) + total_size ) );
00224
00225
00226 switch ( type ) {
00227 case IB_QPT_SMI:
00228 qp->ext_qpn = IB_QPN_SMI;
00229 break;
00230 case IB_QPT_GSI:
00231 qp->ext_qpn = IB_QPN_GSI;
00232 break;
00233 default:
00234 qp->ext_qpn = qp->qpn;
00235 break;
00236 }
00237 if ( qp->ext_qpn != qp->qpn ) {
00238 DBGC ( ibdev, "IBDEV %p QPN %#lx has external QPN %#lx\n",
00239 ibdev, qp->qpn, qp->ext_qpn );
00240 }
00241
00242 return qp;
00243
00244 ibdev->op->destroy_qp ( ibdev, qp );
00245 err_dev_create_qp:
00246 list_del ( &qp->send.list );
00247 list_del ( &qp->recv.list );
00248 list_del ( &qp->list );
00249 free ( qp );
00250 err_alloc_qp:
00251 return NULL;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 int ib_modify_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
00263 int rc;
00264
00265 DBGC ( ibdev, "IBDEV %p modifying QPN %#lx\n", ibdev, qp->qpn );
00266
00267 if ( ( rc = ibdev->op->modify_qp ( ibdev, qp ) ) != 0 ) {
00268 DBGC ( ibdev, "IBDEV %p could not modify QPN %#lx: %s\n",
00269 ibdev, qp->qpn, strerror ( rc ) );
00270 return rc;
00271 }
00272
00273 return 0;
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 void ib_destroy_qp ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
00283 struct io_buffer *iobuf;
00284 unsigned int i;
00285
00286 DBGC ( ibdev, "IBDEV %p destroying QPN %#lx\n",
00287 ibdev, qp->qpn );
00288
00289 assert ( list_empty ( &qp->mgids ) );
00290
00291
00292 ibdev->op->destroy_qp ( ibdev, qp );
00293
00294
00295 for ( i = 0 ; i < qp->send.num_wqes ; i++ ) {
00296 if ( ( iobuf = qp->send.iobufs[i] ) != NULL )
00297 ib_complete_send ( ibdev, qp, iobuf, -ECANCELED );
00298 }
00299 for ( i = 0 ; i < qp->recv.num_wqes ; i++ ) {
00300 if ( ( iobuf = qp->recv.iobufs[i] ) != NULL ) {
00301 ib_complete_recv ( ibdev, qp, NULL, iobuf,
00302 -ECANCELED );
00303 }
00304 }
00305
00306
00307 list_del ( &qp->send.list );
00308 list_del ( &qp->recv.list );
00309
00310
00311 list_del ( &qp->list );
00312 free ( qp );
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322 struct ib_queue_pair * ib_find_qp_qpn ( struct ib_device *ibdev,
00323 unsigned long qpn ) {
00324 struct ib_queue_pair *qp;
00325
00326 list_for_each_entry ( qp, &ibdev->qps, list ) {
00327 if ( ( qpn == qp->qpn ) || ( qpn == qp->ext_qpn ) )
00328 return qp;
00329 }
00330 return NULL;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340 struct ib_queue_pair * ib_find_qp_mgid ( struct ib_device *ibdev,
00341 struct ib_gid *gid ) {
00342 struct ib_queue_pair *qp;
00343 struct ib_multicast_gid *mgid;
00344
00345 list_for_each_entry ( qp, &ibdev->qps, list ) {
00346 list_for_each_entry ( mgid, &qp->mgids, list ) {
00347 if ( memcmp ( &mgid->gid, gid,
00348 sizeof ( mgid->gid ) ) == 0 ) {
00349 return qp;
00350 }
00351 }
00352 }
00353 return NULL;
00354 }
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364 struct ib_work_queue * ib_find_wq ( struct ib_completion_queue *cq,
00365 unsigned long qpn, int is_send ) {
00366 struct ib_work_queue *wq;
00367
00368 list_for_each_entry ( wq, &cq->work_queues, list ) {
00369 if ( ( wq->qp->qpn == qpn ) && ( wq->is_send == is_send ) )
00370 return wq;
00371 }
00372 return NULL;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 int ib_post_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00385 struct ib_address_vector *av,
00386 struct io_buffer *iobuf ) {
00387 struct ib_address_vector av_copy;
00388 int rc;
00389
00390
00391 if ( qp->send.fill >= qp->send.num_wqes ) {
00392 DBGC ( ibdev, "IBDEV %p QPN %#lx send queue full\n",
00393 ibdev, qp->qpn );
00394 return -ENOBUFS;
00395 }
00396
00397
00398 if ( ! av )
00399 av = &qp->av;
00400
00401
00402 memcpy ( &av_copy, av, sizeof ( av_copy ) );
00403 av = &av_copy;
00404
00405
00406 if ( ! av->qkey )
00407 av->qkey = qp->qkey;
00408 if ( ! av->rate )
00409 av->rate = IB_RATE_2_5;
00410
00411
00412 if ( ( rc = ibdev->op->post_send ( ibdev, qp, av, iobuf ) ) != 0 ) {
00413 DBGC ( ibdev, "IBDEV %p QPN %#lx could not post send WQE: "
00414 "%s\n", ibdev, qp->qpn, strerror ( rc ) );
00415 return rc;
00416 }
00417
00418 qp->send.fill++;
00419 return 0;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 int ib_post_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00431 struct io_buffer *iobuf ) {
00432 int rc;
00433
00434
00435 if ( iob_tailroom ( iobuf ) < IB_MAX_PAYLOAD_SIZE ) {
00436 DBGC ( ibdev, "IBDEV %p QPN %#lx wrong RX buffer size (%zd)\n",
00437 ibdev, qp->qpn, iob_tailroom ( iobuf ) );
00438 return -EINVAL;
00439 }
00440
00441
00442 if ( qp->recv.fill >= qp->recv.num_wqes ) {
00443 DBGC ( ibdev, "IBDEV %p QPN %#lx receive queue full\n",
00444 ibdev, qp->qpn );
00445 return -ENOBUFS;
00446 }
00447
00448
00449 if ( ( rc = ibdev->op->post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
00450 DBGC ( ibdev, "IBDEV %p QPN %#lx could not post receive WQE: "
00451 "%s\n", ibdev, qp->qpn, strerror ( rc ) );
00452 return rc;
00453 }
00454
00455 qp->recv.fill++;
00456 return 0;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 void ib_complete_send ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00468 struct io_buffer *iobuf, int rc ) {
00469
00470 if ( qp->send.cq->op->complete_send ) {
00471 qp->send.cq->op->complete_send ( ibdev, qp, iobuf, rc );
00472 } else {
00473 free_iob ( iobuf );
00474 }
00475 qp->send.fill--;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 void ib_complete_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00488 struct ib_address_vector *av,
00489 struct io_buffer *iobuf, int rc ) {
00490
00491 if ( qp->recv.cq->op->complete_recv ) {
00492 qp->recv.cq->op->complete_recv ( ibdev, qp, av, iobuf, rc );
00493 } else {
00494 free_iob ( iobuf );
00495 }
00496 qp->recv.fill--;
00497 }
00498
00499
00500
00501
00502
00503
00504
00505 void ib_refill_recv ( struct ib_device *ibdev, struct ib_queue_pair *qp ) {
00506 struct io_buffer *iobuf;
00507 int rc;
00508
00509
00510 while ( qp->recv.fill < qp->recv.num_wqes ) {
00511
00512
00513 iobuf = alloc_iob ( IB_MAX_PAYLOAD_SIZE );
00514 if ( ! iobuf ) {
00515
00516 return;
00517 }
00518
00519
00520 if ( ( rc = ib_post_recv ( ibdev, qp, iobuf ) ) != 0 ) {
00521 DBGC ( ibdev, "IBDEV %p could not refill: %s\n",
00522 ibdev, strerror ( rc ) );
00523 free_iob ( iobuf );
00524
00525 return;
00526 }
00527 }
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 int ib_open ( struct ib_device *ibdev ) {
00544 int rc;
00545
00546
00547 if ( ibdev->open_count++ > 0 ) {
00548
00549 return 0;
00550 }
00551
00552
00553 ibdev->smi = ib_create_mi ( ibdev, IB_QPT_SMI );
00554 if ( ! ibdev->smi ) {
00555 DBGC ( ibdev, "IBDEV %p could not create SMI\n", ibdev );
00556 rc = -ENOMEM;
00557 goto err_create_smi;
00558 }
00559
00560
00561 if ( ( rc = ib_create_sma ( ibdev, ibdev->smi ) ) != 0 ) {
00562 DBGC ( ibdev, "IBDEV %p could not create SMA: %s\n",
00563 ibdev, strerror ( rc ) );
00564 goto err_create_sma;
00565 }
00566
00567
00568 ibdev->gsi = ib_create_mi ( ibdev, IB_QPT_GSI );
00569 if ( ! ibdev->gsi ) {
00570 DBGC ( ibdev, "IBDEV %p could not create GSI\n", ibdev );
00571 rc = -ENOMEM;
00572 goto err_create_gsi;
00573 }
00574
00575
00576 if ( ( rc = ibdev->op->open ( ibdev ) ) != 0 ) {
00577 DBGC ( ibdev, "IBDEV %p could not open: %s\n",
00578 ibdev, strerror ( rc ) );
00579 goto err_open;
00580 }
00581
00582
00583 list_add ( &ibdev->open_list, &open_ib_devices );
00584
00585 assert ( ibdev->open_count == 1 );
00586 return 0;
00587
00588 ibdev->op->close ( ibdev );
00589 err_open:
00590 ib_destroy_mi ( ibdev, ibdev->gsi );
00591 err_create_gsi:
00592 ib_destroy_sma ( ibdev, ibdev->smi );
00593 err_create_sma:
00594 ib_destroy_mi ( ibdev, ibdev->smi );
00595 err_create_smi:
00596 assert ( ibdev->open_count == 1 );
00597 ibdev->open_count = 0;
00598 return rc;
00599 }
00600
00601
00602
00603
00604
00605
00606 void ib_close ( struct ib_device *ibdev ) {
00607
00608
00609 ibdev->open_count--;
00610
00611
00612 if ( ibdev->open_count == 0 ) {
00613 list_del ( &ibdev->open_list );
00614 ib_destroy_mi ( ibdev, ibdev->gsi );
00615 ib_destroy_sma ( ibdev, ibdev->smi );
00616 ib_destroy_mi ( ibdev, ibdev->smi );
00617 ibdev->op->close ( ibdev );
00618 }
00619 }
00620
00621
00622
00623
00624
00625
00626
00627 int ib_link_rc ( struct ib_device *ibdev ) {
00628 switch ( ibdev->port_state ) {
00629 case IB_PORT_STATE_DOWN: return -ENOTCONN;
00630 case IB_PORT_STATE_INIT: return -EINPROGRESS_INIT;
00631 case IB_PORT_STATE_ARMED: return -EINPROGRESS_ARMED;
00632 case IB_PORT_STATE_ACTIVE: return 0;
00633 default: return -EINVAL;
00634 }
00635 }
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00657 struct ib_gid *gid ) {
00658 struct ib_multicast_gid *mgid;
00659 int rc;
00660
00661
00662 mgid = zalloc ( sizeof ( *mgid ) );
00663 if ( ! mgid ) {
00664 rc = -ENOMEM;
00665 goto err_alloc_mgid;
00666 }
00667 memcpy ( &mgid->gid, gid, sizeof ( mgid->gid ) );
00668 list_add ( &mgid->list, &qp->mgids );
00669
00670
00671 if ( ( rc = ibdev->op->mcast_attach ( ibdev, qp, gid ) ) != 0 )
00672 goto err_dev_mcast_attach;
00673
00674 return 0;
00675
00676 err_dev_mcast_attach:
00677 list_del ( &mgid->list );
00678 free ( mgid );
00679 err_alloc_mgid:
00680 return rc;
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690 void ib_mcast_detach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
00691 struct ib_gid *gid ) {
00692 struct ib_multicast_gid *mgid;
00693
00694
00695 ibdev->op->mcast_detach ( ibdev, qp, gid );
00696
00697
00698 list_for_each_entry ( mgid, &qp->mgids, list ) {
00699 if ( memcmp ( &mgid->gid, gid, sizeof ( mgid->gid ) ) == 0 ) {
00700 list_del ( &mgid->list );
00701 free ( mgid );
00702 break;
00703 }
00704 }
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 int ib_get_hca_info ( struct ib_device *ibdev,
00722 struct ib_gid_half *hca_guid ) {
00723 struct ib_device *tmp;
00724 int num_ports = 0;
00725
00726
00727
00728
00729 for_each_ibdev ( tmp ) {
00730 if ( tmp->dev != ibdev->dev )
00731 continue;
00732 if ( num_ports == 0 ) {
00733 memcpy ( hca_guid, &tmp->gid.u.half[1],
00734 sizeof ( *hca_guid ) );
00735 }
00736 num_ports++;
00737 }
00738 return num_ports;
00739 }
00740
00741
00742
00743
00744
00745
00746
00747 int ib_set_port_info ( struct ib_device *ibdev, union ib_mad *mad ) {
00748 int rc;
00749
00750
00751 if ( ! ibdev->op->set_port_info ) {
00752 DBGC ( ibdev, "IBDEV %p does not support setting port "
00753 "information\n", ibdev );
00754 return -ENOTSUP;
00755 }
00756
00757 if ( ( rc = ibdev->op->set_port_info ( ibdev, mad ) ) != 0 ) {
00758 DBGC ( ibdev, "IBDEV %p could not set port information: %s\n",
00759 ibdev, strerror ( rc ) );
00760 return rc;
00761 }
00762
00763 return 0;
00764 };
00765
00766
00767
00768
00769
00770
00771
00772 int ib_set_pkey_table ( struct ib_device *ibdev, union ib_mad *mad ) {
00773 int rc;
00774
00775
00776 if ( ! ibdev->op->set_pkey_table ) {
00777 DBGC ( ibdev, "IBDEV %p does not support setting partition "
00778 "key table\n", ibdev );
00779 return -ENOTSUP;
00780 }
00781
00782 if ( ( rc = ibdev->op->set_pkey_table ( ibdev, mad ) ) != 0 ) {
00783 DBGC ( ibdev, "IBDEV %p could not set partition key table: "
00784 "%s\n", ibdev, strerror ( rc ) );
00785 return rc;
00786 }
00787
00788 return 0;
00789 };
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803 void ib_link_state_changed ( struct ib_device *ibdev ) {
00804
00805
00806 ipoib_link_state_changed ( ibdev );
00807 }
00808
00809
00810
00811
00812
00813
00814 void ib_poll_eq ( struct ib_device *ibdev ) {
00815 struct ib_completion_queue *cq;
00816
00817
00818 ibdev->op->poll_eq ( ibdev );
00819
00820
00821 list_for_each_entry ( cq, &ibdev->cqs, list )
00822 ib_poll_cq ( ibdev, cq );
00823 }
00824
00825
00826
00827
00828
00829
00830 static void ib_step ( struct process *process __unused ) {
00831 struct ib_device *ibdev;
00832
00833 for_each_ibdev ( ibdev )
00834 ib_poll_eq ( ibdev );
00835 }
00836
00837
00838 struct process ib_process __permanent_process = {
00839 .list = LIST_HEAD_INIT ( ib_process.list ),
00840 .step = ib_step,
00841 };
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 struct ib_device * alloc_ibdev ( size_t priv_size ) {
00857 struct ib_device *ibdev;
00858 void *drv_priv;
00859 size_t total_len;
00860
00861 total_len = ( sizeof ( *ibdev ) + priv_size );
00862 ibdev = zalloc ( total_len );
00863 if ( ibdev ) {
00864 drv_priv = ( ( ( void * ) ibdev ) + sizeof ( *ibdev ) );
00865 ib_set_drvdata ( ibdev, drv_priv );
00866 INIT_LIST_HEAD ( &ibdev->cqs );
00867 INIT_LIST_HEAD ( &ibdev->qps );
00868 ibdev->port_state = IB_PORT_STATE_DOWN;
00869 ibdev->lid = IB_LID_NONE;
00870 ibdev->pkey = IB_PKEY_DEFAULT;
00871 }
00872 return ibdev;
00873 }
00874
00875
00876
00877
00878
00879
00880
00881 int register_ibdev ( struct ib_device *ibdev ) {
00882 int rc;
00883
00884
00885 ibdev_get ( ibdev );
00886 list_add_tail ( &ibdev->list, &ib_devices );
00887
00888
00889 if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
00890 DBGC ( ibdev, "IBDEV %p could not add IPoIB device: %s\n",
00891 ibdev, strerror ( rc ) );
00892 goto err_ipoib_probe;
00893 }
00894
00895 DBGC ( ibdev, "IBDEV %p registered (phys %s)\n", ibdev,
00896 ibdev->dev->name );
00897 return 0;
00898
00899 err_ipoib_probe:
00900 list_del ( &ibdev->list );
00901 ibdev_put ( ibdev );
00902 return rc;
00903 }
00904
00905
00906
00907
00908
00909
00910 void unregister_ibdev ( struct ib_device *ibdev ) {
00911
00912
00913 ipoib_remove ( ibdev );
00914
00915
00916 list_del ( &ibdev->list );
00917 ibdev_put ( ibdev );
00918 DBGC ( ibdev, "IBDEV %p unregistered\n", ibdev );
00919 }
00920
00921
00922
00923
00924
00925
00926
00927 struct ib_device * find_ibdev ( struct ib_gid *gid ) {
00928 struct ib_device *ibdev;
00929
00930 for_each_ibdev ( ibdev ) {
00931 if ( memcmp ( gid, &ibdev->gid, sizeof ( *gid ) ) == 0 )
00932 return ibdev;
00933 }
00934 return NULL;
00935 }
00936
00937
00938
00939
00940
00941
00942 struct ib_device * last_opened_ibdev ( void ) {
00943 struct ib_device *ibdev;
00944
00945 list_for_each_entry ( ibdev, &open_ib_devices, open_list ) {
00946 assert ( ibdev->open_count != 0 );
00947 return ibdev;
00948 }
00949
00950 return NULL;
00951 }