1 /* 2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 */ 4 5 /* 6 * This file contains code imported from the OFED rds source file transport.c 7 * Oracle elects to have and use the contents of transport.c under and governed 8 * by the OpenIB.org BSD license (see below for full license text). However, 9 * the following notice accompanied the original version of this file: 10 */ 11 12 /* 13 * Copyright (c) 2006 Oracle. All rights reserved. 14 * 15 * This software is available to you under a choice of one of two 16 * licenses. You may choose to be licensed under the terms of the GNU 17 * General Public License (GPL) Version 2, available from the file 18 * COPYING in the main directory of this source tree, or the 19 * OpenIB.org BSD license below: 20 * 21 * Redistribution and use in source and binary forms, with or 22 * without modification, are permitted provided that the following 23 * conditions are met: 24 * 25 * - Redistributions of source code must retain the above 26 * copyright notice, this list of conditions and the following 27 * disclaimer. 28 * 29 * - Redistributions in binary form must reproduce the above 30 * copyright notice, this list of conditions and the following 31 * disclaimer in the documentation and/or other materials 32 * provided with the distribution. 33 * 34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 35 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 36 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 37 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 38 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 39 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 40 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 41 * SOFTWARE. 42 * 43 */ 44 #include <sys/ksynch.h> 45 #include <sys/list.h> 46 #include <sys/rds.h> 47 #include <sys/sysmacros.h> 48 49 #include <sys/ib/clients/rdsv3/rdsv3.h> 50 #include <sys/ib/clients/rdsv3/loop.h> 51 #include <sys/ib/clients/rdsv3/rdsv3_impl.h> 52 #include <sys/ib/clients/rdsv3/rdsv3_debug.h> 53 54 struct rdsv3_transport *transports[RDS_TRANS_COUNT]; 55 krwlock_t trans_sem; /* this was a semaphore */ 56 57 int 58 rdsv3_trans_register(struct rdsv3_transport *trans) 59 { 60 RDSV3_DPRINTF4("rdsv3_trans_register", "Enter(trans: %p)", trans); 61 62 rw_enter(&trans_sem, RW_WRITER); 63 64 if (transports[trans->t_type]) { 65 cmn_err(CE_WARN, 66 "RDSV3 Transport type %d already registered\n", 67 trans->t_type); 68 rw_exit(&trans_sem); 69 return (1); 70 } else { 71 transports[trans->t_type] = trans; 72 RDSV3_DPRINTF2("rdsv3_trans_register", 73 "Registered RDS/%s transport\n", trans->t_name); 74 } 75 76 rw_exit(&trans_sem); 77 78 RDSV3_DPRINTF4("rdsv3_trans_register", "Return(trans: %p)", trans); 79 80 return (0); 81 } 82 83 void 84 rdsv3_trans_unregister(struct rdsv3_transport *trans) 85 { 86 RDSV3_DPRINTF4("rdsv3_trans_register", "Enter(trans: %p)", trans); 87 88 rw_enter(&trans_sem, RW_WRITER); 89 90 transports[trans->t_type] = NULL; 91 92 rw_exit(&trans_sem); 93 94 RDSV3_DPRINTF4("rdsv3_trans_register", "Return(trans: %p)", trans); 95 } 96 97 struct rdsv3_transport * 98 rdsv3_trans_get_preferred(uint32_be_t addr) 99 { 100 struct rdsv3_transport *ret = NULL; 101 int i; 102 103 RDSV3_DPRINTF4("rdsv3_trans_get_preferred", "Enter(addr: %x)", 104 ntohl(addr)); 105 106 if (rdsv3_isloopback(addr)) 107 return (&rdsv3_loop_transport); 108 109 rw_enter(&trans_sem, RW_READER); 110 for (i = 0; i < RDS_TRANS_COUNT; i++) { 111 if (transports[i] && 112 transports[i]->laddr_check(addr) == 0) { 113 ret = transports[i]; 114 break; 115 } 116 } 117 rw_exit(&trans_sem); 118 119 RDSV3_DPRINTF4("rdsv3_trans_get_preferred", 120 "Return(addr: %x, ret: %p)", ntohl(addr), ret); 121 122 return (ret); 123 } 124 125 /* 126 * This returns the number of stats entries in the snapshot and only 127 * copies them using the iter if there is enough space for them. The 128 * caller passes in the global stats so that we can size and copy while 129 * holding the lock. 130 */ 131 /* ARGSUSED */ 132 unsigned int 133 rdsv3_trans_stats_info_copy(struct rdsv3_info_iterator *iter, 134 unsigned int avail) 135 { 136 struct rdsv3_transport *trans; 137 unsigned int total = 0; 138 unsigned int part; 139 int i; 140 141 rw_enter(&trans_sem, RW_READER); 142 143 for (i = 0; i < RDS_TRANS_COUNT; i++) { 144 trans = transports[i]; 145 if (!trans || !trans->stats_info_copy) 146 continue; 147 148 part = trans->stats_info_copy(iter, avail); 149 avail -= min(avail, part); 150 total += part; 151 } 152 153 rw_exit(&trans_sem); 154 155 return (total); 156 } 157