67 /*
68 * Function:
69 * ibtl_cm_get_chan_private
70 * Input:
71 * chan Channel Handle.
72 * Output:
73 * cm_private_p The CM private data.
74 * Returns:
75 * CM private data.
76 * Description:
77 * A helper function to get CM's Private data for the specified channel.
78 */
79 void *
80 ibtl_cm_get_chan_private(ibt_channel_hdl_t chan)
81 {
82 void *cm_private;
83
84 IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_chan_private(%p)", chan);
85 mutex_enter(&chan->ch_cm_mutex);
86 cm_private = chan->ch_cm_private;
87 #ifndef __lock_lint
88 /* IBCM will call the release function if cm_private is non-NULL */
89 if (cm_private == NULL)
90 #endif
91 mutex_exit(&chan->ch_cm_mutex);
92 return (cm_private);
93 }
94
95 void
96 ibtl_cm_release_chan_private(ibt_channel_hdl_t chan)
97 {
98 #ifndef __lock_lint
99 mutex_exit(&chan->ch_cm_mutex);
100 #endif
101 }
102
103 void
104 ibtl_cm_wait_chan_private(ibt_channel_hdl_t chan)
105 {
106 mutex_enter(&chan->ch_cm_mutex);
107 if (chan->ch_cm_private != NULL)
108 cv_wait(&chan->ch_cm_cv, &chan->ch_cm_mutex);
109 mutex_exit(&chan->ch_cm_mutex);
110 delay(drv_usectohz(50000));
111 }
112
113
114 /*
115 * Function:
116 * ibtl_cm_get_chan_type
117 * Input:
118 * chan Channel Handle.
119 * Output:
120 * none.
493 mutex_exit(&ibtl_clnt_list_mutex);
494 kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
495 goto get_plist_start;
496 }
497
498 *port_list_p = p_listp;
499 /*
500 * Src count hasn't changed, still holding the lock fill-in the
501 * required source point information.
502 */
503 retval = ibtl_cm_get_cnt(attr, flags, p_listp, &rcount);
504 mutex_exit(&ibtl_clnt_list_mutex);
505 if (retval != IBT_SUCCESS) {
506 kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
507 *port_list_p = NULL;
508 return (retval);
509 }
510
511 p_listp = *port_list_p;
512
513 _NOTE(NO_COMPETING_THREADS_NOW)
514
515 for (i = 0; i < count - 1; i++) {
516 for (j = 0; j < count - 1 - i; j++) {
517 if (p_listp[j].p_hca_guid != p_listp[j+1].p_hca_guid) {
518 multi_hca = B_TRUE;
519 break;
520 }
521 }
522 if (multi_hca == B_TRUE)
523 break;
524 }
525
526 if (multi_hca == B_TRUE)
527 for (i = 0; i < count; i++)
528 p_listp[i].p_multi |= IBTL_CM_MULTI_HCA;
529
530 /*
531 * Sort (bubble sort) the list based on MTU quality (higher on top).
532 * Sorting is only performed, if IBT_PATH_AVAIL is set.
533 */
534 if (((attr->pa_mtu.r_selector == IBT_GT) || (flags & IBT_PATH_AVAIL)) &&
559 }
560 }
561 }
562
563 /*
564 * If SGID is specified, then make sure that SGID info is first
565 * in the array.
566 */
567 if (attr->pa_sgid.gid_guid && (p_listp->p_count > 1) &&
568 (p_listp[0].p_sgid.gid_guid != attr->pa_sgid.gid_guid)) {
569 for (i = 1; i < count; i++) {
570 if (p_listp[i].p_sgid.gid_guid ==
571 attr->pa_sgid.gid_guid) {
572 tmp = p_listp[i];
573 p_listp[i] = p_listp[0];
574 p_listp[0] = tmp;
575 }
576 }
577 }
578
579 #ifndef lint
580 _NOTE(COMPETING_THREADS_NOW)
581 #endif
582
583 IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_active_plist: "
584 "Returned <%d> entries @0x%p", count, *port_list_p);
585
586 return (retval);
587 }
588
589
590 void
591 ibtl_cm_free_active_plist(ibtl_cm_port_list_t *plist)
592 {
593 int count;
594
595 IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_free_active_plist(%p)", plist);
596
597 if (plist != NULL) {
598 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*plist))
599 count = plist->p_count;
600 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*plist))
601
602 kmem_free(plist, count * sizeof (ibtl_cm_port_list_t));
603 }
604 }
605
606 /*
607 * Function:
608 * ibtl_cm_get_1st_full_pkey_ix
609 * Input:
610 * hca_guid HCA GUID.
611 * port Port Number.
612 * Output:
613 * None.
614 * Returns:
615 * P_Key Index of the first full member available from the P_Key table
616 * of the specified HCA<->Port.
617 * Description:
618 * A helper function to get P_Key Index of the first full member P_Key
619 * available on the specified HCA and Port combination.
620 */
621 uint16_t
|
67 /*
68 * Function:
69 * ibtl_cm_get_chan_private
70 * Input:
71 * chan Channel Handle.
72 * Output:
73 * cm_private_p The CM private data.
74 * Returns:
75 * CM private data.
76 * Description:
77 * A helper function to get CM's Private data for the specified channel.
78 */
79 void *
80 ibtl_cm_get_chan_private(ibt_channel_hdl_t chan)
81 {
82 void *cm_private;
83
84 IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_chan_private(%p)", chan);
85 mutex_enter(&chan->ch_cm_mutex);
86 cm_private = chan->ch_cm_private;
87 /* IBCM will call the release function if cm_private is non-NULL */
88 if (cm_private == NULL)
89 mutex_exit(&chan->ch_cm_mutex);
90 return (cm_private);
91 }
92
93 void
94 ibtl_cm_release_chan_private(ibt_channel_hdl_t chan)
95 {
96 mutex_exit(&chan->ch_cm_mutex);
97 }
98
99 void
100 ibtl_cm_wait_chan_private(ibt_channel_hdl_t chan)
101 {
102 mutex_enter(&chan->ch_cm_mutex);
103 if (chan->ch_cm_private != NULL)
104 cv_wait(&chan->ch_cm_cv, &chan->ch_cm_mutex);
105 mutex_exit(&chan->ch_cm_mutex);
106 delay(drv_usectohz(50000));
107 }
108
109
110 /*
111 * Function:
112 * ibtl_cm_get_chan_type
113 * Input:
114 * chan Channel Handle.
115 * Output:
116 * none.
489 mutex_exit(&ibtl_clnt_list_mutex);
490 kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
491 goto get_plist_start;
492 }
493
494 *port_list_p = p_listp;
495 /*
496 * Src count hasn't changed, still holding the lock fill-in the
497 * required source point information.
498 */
499 retval = ibtl_cm_get_cnt(attr, flags, p_listp, &rcount);
500 mutex_exit(&ibtl_clnt_list_mutex);
501 if (retval != IBT_SUCCESS) {
502 kmem_free(p_listp, count * sizeof (ibtl_cm_port_list_t));
503 *port_list_p = NULL;
504 return (retval);
505 }
506
507 p_listp = *port_list_p;
508
509 for (i = 0; i < count - 1; i++) {
510 for (j = 0; j < count - 1 - i; j++) {
511 if (p_listp[j].p_hca_guid != p_listp[j+1].p_hca_guid) {
512 multi_hca = B_TRUE;
513 break;
514 }
515 }
516 if (multi_hca == B_TRUE)
517 break;
518 }
519
520 if (multi_hca == B_TRUE)
521 for (i = 0; i < count; i++)
522 p_listp[i].p_multi |= IBTL_CM_MULTI_HCA;
523
524 /*
525 * Sort (bubble sort) the list based on MTU quality (higher on top).
526 * Sorting is only performed, if IBT_PATH_AVAIL is set.
527 */
528 if (((attr->pa_mtu.r_selector == IBT_GT) || (flags & IBT_PATH_AVAIL)) &&
553 }
554 }
555 }
556
557 /*
558 * If SGID is specified, then make sure that SGID info is first
559 * in the array.
560 */
561 if (attr->pa_sgid.gid_guid && (p_listp->p_count > 1) &&
562 (p_listp[0].p_sgid.gid_guid != attr->pa_sgid.gid_guid)) {
563 for (i = 1; i < count; i++) {
564 if (p_listp[i].p_sgid.gid_guid ==
565 attr->pa_sgid.gid_guid) {
566 tmp = p_listp[i];
567 p_listp[i] = p_listp[0];
568 p_listp[0] = tmp;
569 }
570 }
571 }
572
573 IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_get_active_plist: "
574 "Returned <%d> entries @0x%p", count, *port_list_p);
575
576 return (retval);
577 }
578
579
580 void
581 ibtl_cm_free_active_plist(ibtl_cm_port_list_t *plist)
582 {
583 int count;
584
585 IBTF_DPRINTF_L3(ibtf_cm, "ibtl_cm_free_active_plist(%p)", plist);
586
587 if (plist != NULL) {
588 count = plist->p_count;
589 kmem_free(plist, count * sizeof (ibtl_cm_port_list_t));
590 }
591 }
592
593 /*
594 * Function:
595 * ibtl_cm_get_1st_full_pkey_ix
596 * Input:
597 * hca_guid HCA GUID.
598 * port Port Number.
599 * Output:
600 * None.
601 * Returns:
602 * P_Key Index of the first full member available from the P_Key table
603 * of the specified HCA<->Port.
604 * Description:
605 * A helper function to get P_Key Index of the first full member P_Key
606 * available on the specified HCA and Port combination.
607 */
608 uint16_t
|