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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/kmem.h> 28 #include <sys/sunddi.h> 29 #include <sys/ib/mgt/ibmf/ibmf_saa_impl.h> 30 #include <sys/ib/mgt/ibmf/ibmf_saa_utils.h> 31 32 #define IBMF_SAA_HDR_SIZE 20 33 #define IBMF_SAA_DEFAULT_RID_SIZE 4 34 #define IBMF_SAA_PARTITION_RID_SIZE 5 35 #define IBMF_SAA_INFORMINFO_RID_SIZE 18 36 37 #define IB_MAD_NOTICE_SIZE 80 38 #define IB_MAD_CLASSPORTINFO_SIZE 72 39 #define IB_MAD_INFORMINFO_SIZE 36 40 41 #define SM_TRAP_DATA_DETAILS_SIZE 54 42 #define SM_NODEINFO_SIZE 40 43 #define SM_NODEDESC_SIZE 64 44 #define SM_PORTINFO_SIZE 54 45 #define SM_SLTOVL_SIZE 8 46 #define SM_SWITCHINFO_SIZE 17 47 #define SM_LINEARFDB_SIZE 64 48 #define SM_RANDOMFDB_SIZE 64 49 #define SM_MULTICASTFDB_SIZE 64 50 #define SM_SMINFO_SIZE 21 51 #define SM_GUIDINFO_SIZE 64 52 #define SM_PARTITION_SIZE 64 53 #define SM_VLARB_SIZE 64 54 55 #define IBMF_SAA_NODE_RECORD_SIZE 108 56 #define IBMF_SAA_PORTINFO_RECORD_SIZE 58 57 #define IBMF_SAA_SLTOVL_RECORD_SIZE 16 58 #define IBMF_SAA_SWITCHINFO_RECORD_SIZE 21 59 #define IBMF_SAA_LINEARFDB_RECORD_SIZE 72 60 #define IBMF_SAA_RANDOMFDB_RECORD_SIZE 72 61 #define IBMF_SAA_MULTICASTFDB_RECORD_SIZE 72 62 #define IBMF_SAA_SMINFO_RECORD_SIZE 25 63 #define IBMF_SAA_INFORMINFO_RECORD_SIZE 60 64 #define IBMF_SAA_LINK_RECORD_SIZE 6 65 #define IBMF_SAA_GUIDINFO_RECORD_SIZE 72 66 #define IBMF_SAA_SERVICE_RECORD_SIZE 176 67 #define IBMF_SAA_PARTITION_RECORD_SIZE 72 68 #define IBMF_SAA_PATH_RECORD_SIZE 64 69 #define IBMF_SAA_VLARB_RECORD_SIZE 72 70 #define IBMF_SAA_MCMEMBER_RECORD_SIZE 52 71 #define IBMF_SAA_TRACE_RECORD_SIZE 46 72 #define IBMF_SAA_MULTIPATH_RECORD_SIZE 24 73 #define IBMF_SAA_SERVICEASSN_RECORD_SIZE 80 74 75 extern int ibmf_trace_level; 76 77 /* These functions have only been tested on a big-endian system */ 78 static void ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record); 79 static void ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record); 80 static void ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record); 81 static void ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record); 82 static void ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer, 83 void *record); 84 static void ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer, 85 void *record); 86 static void ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer, 87 void *record); 88 static void ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer, 89 void *record); 90 static void ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer, 91 void *record); 92 static void ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer, 93 void *record); 94 static void ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record); 95 static void ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer, 96 void *record); 97 static void ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record); 98 static void ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer, 99 void *record); 100 static void ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record); 101 static void ibmf_saa_partition_record_parse_buffer(uchar_t *buffer, 102 void *record); 103 static void ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record); 104 static void ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record); 105 static void ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer, 106 void *record); 107 static void ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record); 108 static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer, 109 void *record); 110 static void ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer, 111 void *record); 112 113 static void ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer); 114 static void ibmf_saa_notice_to_buf(void *record, uchar_t *buffer); 115 static void ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer); 116 static void ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer); 117 static void ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer); 118 static void ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer); 119 static void ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer); 120 static void ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer); 121 static void ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer); 122 static void ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer); 123 static void ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer); 124 static void ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer); 125 static void ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer); 126 static void ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer); 127 static void ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer); 128 static void ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer); 129 static void ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer); 130 static void ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer); 131 static void ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer); 132 static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer); 133 static void ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer); 134 135 /* 136 * *_record_parse_buffer functions: 137 * 138 * Each of these functions parses a buffer containing a single SA record. 139 * The function copies the buffer into a structure taking care of any padding 140 * and byte-endianness issues. There is one function for each of the 22 141 * attributes (Table 155). 142 * 143 * ibmf_utils_unpack_data() must be called for each structure in the structure 144 * since Solaris will align the internal structure on a 64-bit boundary, even if 145 * the first element is a 32-bit value. 146 * 147 * Input Arguments 148 * buffer pointer character array containing raw data 149 * 150 * Output Arguments 151 * record pointer to the SA attribute structure 152 * 153 * Returns void 154 */ 155 156 static void 157 ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record) 158 { 159 ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record; 160 161 ibmf_utils_unpack_data("2csl2Ll2s2l2Ll2s2l", buffer, 162 IB_MAD_CLASSPORTINFO_SIZE, cpi, sizeof (ib_mad_classportinfo_t)); 163 } 164 165 static void 166 ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record) 167 { 168 ib_mad_notice_t *notice = (ib_mad_notice_t *)record; 169 170 ibmf_utils_unpack_data("4c3s54c2L", buffer, IB_MAD_NOTICE_SIZE, 171 notice, sizeof (ib_mad_notice_t)); 172 } 173 174 static void 175 ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record) 176 { 177 ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record; 178 179 ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE, 180 informinfo, sizeof (ib_mad_informinfo_t)); 181 } 182 183 static void 184 ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record) 185 { 186 sa_node_record_t *node_record = (sa_node_record_t *)record; 187 188 /* first get record identifier information */ 189 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE, 190 node_record, 4); 191 192 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 193 194 /* next get node info */ 195 ibmf_utils_unpack_data("4c3L2s2l", buffer, SM_NODEINFO_SIZE, 196 &node_record->NodeInfo, sizeof (sm_nodeinfo_t)); 197 198 buffer += SM_NODEINFO_SIZE; 199 200 ibmf_utils_unpack_data("64c", buffer, SM_NODEDESC_SIZE, 201 &node_record->NodeDescription, sizeof (sm_nodedesc_t)); 202 } 203 204 static void 205 ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer, void *record) 206 { 207 208 sa_portinfo_record_t *portinfo_record = 209 (sa_portinfo_record_t *)record; 210 211 /* first get record identifier information */ 212 ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE, 213 portinfo_record, 4); 214 215 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 216 217 /* next get portinfo info */ 218 ibmf_utils_unpack_data("LLsslss16c3s4c", buffer, SM_PORTINFO_SIZE, 219 &portinfo_record->PortInfo, sizeof (sm_portinfo_t)); 220 } 221 222 static void 223 ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer, void *record) 224 { 225 226 sa_SLtoVLmapping_record_t *SLtoVLmapping_record = 227 (sa_SLtoVLmapping_record_t *)record; 228 229 /* first get record identifier information (plus 4 bytes reserved) */ 230 ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, 231 SLtoVLmapping_record, 8); 232 233 /* SLtoVL mapping has 4 reserved bytes between RID and attribute */ 234 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 235 236 /* next get SLtoVLmapping info */ 237 ibmf_utils_unpack_data("8c", buffer, SM_SLTOVL_SIZE, 238 &SLtoVLmapping_record->SLtoVLMappingTable, 239 sizeof (sm_SLtoVL_mapping_table_t)); 240 } 241 242 static void 243 ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer, void *record) 244 { 245 246 sa_switchinfo_record_t *switchinfo_record = 247 (sa_switchinfo_record_t *)record; 248 249 /* first get record identifier information */ 250 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE, 251 switchinfo_record, 4); 252 253 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 254 255 /* next get switchinfo info */ 256 ibmf_utils_unpack_data("4s4c2sc", buffer, SM_SWITCHINFO_SIZE, 257 &switchinfo_record->SwitchInfo, sizeof (sm_switchinfo_t)); 258 259 } 260 261 static void 262 ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer, void *record) 263 { 264 265 sa_linearft_record_t *linearft_record = 266 (sa_linearft_record_t *)record; 267 268 /* first get record identifier information (plus 4 bytes reserved) */ 269 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, 270 linearft_record, 8); 271 272 /* LFT has 4 reserved bytes between RID and attribute */ 273 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 274 275 /* next get linearft info */ 276 ibmf_utils_unpack_data("64c", buffer, SM_LINEARFDB_SIZE, 277 &linearft_record->LinearFT, sizeof (sm_linear_forwarding_table_t)); 278 } 279 280 static void 281 ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer, void *record) 282 { 283 284 sa_randomft_record_t *randomft_record = 285 (sa_randomft_record_t *)record; 286 287 /* first get record identifier information (plus 4 bytes reserved) */ 288 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, 289 randomft_record, 8); 290 291 /* RFT has 4 reserved bytes between RID and attribute */ 292 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 293 294 /* next get randomft info */ 295 ibmf_utils_unpack_data("64c", buffer, SM_RANDOMFDB_SIZE, 296 &randomft_record->RandomFT, sizeof (sm_random_forwarding_table_t)); 297 } 298 299 static void 300 ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer, void *record) 301 { 302 303 sa_multicastft_record_t *multicastft_record = 304 (sa_multicastft_record_t *)record; 305 306 /* first get record identifier information (plus 4 bytes reserved) */ 307 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, 308 multicastft_record, 8); 309 310 /* MFT has 4 reserved bytes between RID and attribute */ 311 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 312 313 /* next get multicastft info */ 314 ibmf_utils_unpack_data("32s", buffer, SM_MULTICASTFDB_SIZE, 315 &multicastft_record->MulticastFT, 316 sizeof (sm_multicast_forwarding_table_t)); 317 } 318 319 static void 320 ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record) 321 { 322 323 sa_sminfo_record_t *sminfo_record = 324 (sa_sminfo_record_t *)record; 325 326 /* first get record identifier information */ 327 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE, 328 sminfo_record, 4); 329 330 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 331 332 /* next get sminfo info */ 333 ibmf_utils_unpack_data("2Llc", buffer, SM_SMINFO_SIZE, 334 &sminfo_record->SMInfo, 335 sizeof (sm_sminfo_t)); 336 } 337 338 static void 339 ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer, void *record) 340 { 341 342 sa_informinfo_record_t *informinfo_record = 343 (sa_informinfo_record_t *)record; 344 345 /* first get record identifier information */ 346 ibmf_utils_unpack_data("2Ls", buffer, IBMF_SAA_INFORMINFO_RID_SIZE, 347 informinfo_record, 18); 348 349 /* InformInfo has 6 reserved bytes between RID and attribute */ 350 buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6; 351 352 /* next get informinfo info */ 353 ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE, 354 &informinfo_record->InformInfo, 355 sizeof (ib_mad_informinfo_t)); 356 } 357 358 static void 359 ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record) 360 { 361 362 sa_link_record_t *link_record = (sa_link_record_t *)record; 363 364 ibmf_utils_unpack_data("s2cs", buffer, IBMF_SAA_LINK_RECORD_SIZE, 365 link_record, sizeof (sa_link_record_t)); 366 } 367 368 static void 369 ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer, void *record) 370 { 371 372 sa_guidinfo_record_t *guidinfo_record = 373 (sa_guidinfo_record_t *)record; 374 375 /* first get record identifier information (plus 4 bytes reserved) */ 376 ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, 377 guidinfo_record, 8); 378 379 /* GUIDInfo has 4 reserved bytes between RID and attribute */ 380 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 381 382 /* next get guidinfo info */ 383 ibmf_utils_unpack_data("8L", buffer, SM_GUIDINFO_SIZE, 384 &guidinfo_record->GUIDInfo, sizeof (sm_guidinfo_t)); 385 } 386 387 static void 388 ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record) 389 { 390 391 sa_service_record_t *service_record = (sa_service_record_t *)record; 392 393 ibmf_utils_unpack_data("3L2sl2L64c16c8s4l2L", buffer, 394 IBMF_SAA_SERVICE_RECORD_SIZE, service_record, 395 sizeof (sa_service_record_t)); 396 } 397 398 static void 399 ibmf_saa_partition_record_parse_buffer(uchar_t *buffer, void *record) 400 { 401 402 sa_pkey_table_record_t *partition_record = 403 (sa_pkey_table_record_t *)record; 404 405 /* first get record identifier information (plus 4 bytes reserved) */ 406 ibmf_utils_unpack_data("2s4c", buffer, IBMF_SAA_PARTITION_RID_SIZE + 3, 407 partition_record, 8); 408 409 /* Partition record has 3 reserved bytes between RID and attribute */ 410 buffer += IBMF_SAA_PARTITION_RID_SIZE + 3; 411 412 /* next get partition info */ 413 ibmf_utils_unpack_data("32s", buffer, SM_PARTITION_SIZE, 414 &partition_record->P_KeyTable, sizeof (sm_pkey_table_t)); 415 } 416 417 static void 418 ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record) 419 { 420 421 sa_path_record_t *path_record = (sa_path_record_t *)record; 422 423 ibmf_utils_unpack_data("2l4L2sl2c2s4c", buffer, 424 IBMF_SAA_PATH_RECORD_SIZE, path_record, sizeof (sa_path_record_t)); 425 } 426 427 static void 428 ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record) 429 { 430 431 sa_VLarb_table_record_t *VLarb_table_record = 432 (sa_VLarb_table_record_t *)record; 433 434 /* first get record identifier information (plus 4 bytes reserved) */ 435 ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, 436 VLarb_table_record, 8); 437 438 /* VLarb record has 4 reserved bytes between RID and attribute */ 439 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 440 441 /* next get VLarb_table info */ 442 ibmf_utils_unpack_data("64c", buffer, SM_VLARB_SIZE, 443 &VLarb_table_record->VLArbTable, 444 sizeof (sm_VLarb_table_t)); 445 } 446 447 static void 448 ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer, void *record) 449 { 450 451 sa_mcmember_record_t *mcmember_record = 452 (sa_mcmember_record_t *)record; 453 454 ibmf_utils_unpack_data("4Lls2cs2c2l", buffer, 455 IBMF_SAA_MCMEMBER_RECORD_SIZE, 456 mcmember_record, sizeof (sa_mcmember_record_t)); 457 } 458 459 static void 460 ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record) 461 { 462 463 sa_trace_record_t *trace_record = 464 (sa_trace_record_t *)record; 465 466 ibmf_utils_unpack_data("Ls2c4L2c", buffer, 467 IBMF_SAA_TRACE_RECORD_SIZE, 468 trace_record, sizeof (sa_trace_record_t)); 469 } 470 471 /* 472 * ibmf_saa_multipath_record_parse_buffer: 473 * 474 * First unpack the standard part of the multipath record. Then find the number 475 * of gids and unpack those. This function will probably never be called as the 476 * ibmf_saa should not receive any multipath records. It's in here for 477 * completeness. 478 */ 479 static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer, 480 void *record) 481 { 482 char gid_str[20]; 483 uint16_t num_gids; 484 485 sa_multipath_record_t *multipath_record = 486 (sa_multipath_record_t *)record; 487 488 ibmf_utils_unpack_data("l2c2s14c", buffer, 489 IBMF_SAA_MULTIPATH_RECORD_SIZE, multipath_record, 490 sizeof (sa_multipath_record_t)); 491 492 num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount; 493 494 (void) sprintf(gid_str, "%dL", 2 * num_gids); 495 496 ibmf_utils_unpack_data(gid_str, buffer + IBMF_SAA_MULTIPATH_RECORD_SIZE, 497 sizeof (ib_gid_t) * num_gids, 498 multipath_record + sizeof (sa_multipath_record_t), 499 sizeof (ib_gid_t) * num_gids); 500 501 } 502 503 static void 504 ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer, void *record) 505 { 506 507 sa_service_assn_record_t *service_assn_record = 508 (sa_service_assn_record_t *)record; 509 510 ibmf_utils_unpack_data("2L64c", buffer, 511 IBMF_SAA_SERVICEASSN_RECORD_SIZE, 512 service_assn_record, sizeof (sa_service_assn_record_t)); 513 } 514 515 void 516 ibmf_saa_gid_trap_parse_buffer(uchar_t *buffer, sm_trap_64_t *sm_trap_64) 517 { 518 519 ibmf_utils_unpack_data("6c2L32c", buffer, SM_TRAP_DATA_DETAILS_SIZE, 520 sm_trap_64, sizeof (sm_trap_64_t)); 521 } 522 523 void 524 ibmf_saa_capmask_chg_trap_parse_buffer(uchar_t *buffer, 525 sm_trap_144_t *sm_trap_144) 526 { 527 528 ibmf_utils_unpack_data("2cs2cl44c", buffer, SM_TRAP_DATA_DETAILS_SIZE, 529 sm_trap_144, sizeof (sm_trap_144_t)); 530 } 531 532 void 533 ibmf_saa_sysimg_guid_chg_trap_parse_buffer(uchar_t *buffer, 534 sm_trap_145_t *sm_trap_145) 535 { 536 537 ibmf_utils_unpack_data("2cs2cL44c", buffer, SM_TRAP_DATA_DETAILS_SIZE, 538 sm_trap_145, sizeof (sm_trap_145_t)); 539 } 540 541 /* 542 * *_record_to_buf functions: 543 * 544 * Each of these functions copies a single SA record out of a structure and into 545 * a buffer for sending on the wire. The function will take care of any padding 546 * and byte-endianness isues. There is one function for each of the 22 547 * attributes (Table 155). 548 * 549 * ibmf_utils_pack_data() must be called for each structure in the structure 550 * since Solaris will align the internal structure on a 64-bit boundary, even if 551 * the first element is a 32-bit value. 552 * 553 * Input Arguments 554 * record pointer to the structure to be parsed 555 * 556 * Output Arguments 557 * buffer pointer to array to place the data in (allocated by caller) 558 * 559 * Returns void 560 */ 561 562 static void 563 ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer) 564 { 565 ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record; 566 567 ibmf_utils_pack_data("2csl2Ll2s2l2Ll2s2l", 568 cpi, sizeof (ib_mad_classportinfo_t), 569 buffer, IB_MAD_CLASSPORTINFO_SIZE); 570 } 571 572 static void 573 ibmf_saa_notice_to_buf(void *record, uchar_t *buffer) 574 { 575 ib_mad_notice_t *notice = (ib_mad_notice_t *)record; 576 577 ibmf_utils_pack_data("4c3s54c2L", notice, sizeof (ib_mad_notice_t), 578 buffer, IB_MAD_NOTICE_SIZE); 579 } 580 581 static void 582 ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer) 583 { 584 ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record; 585 586 ibmf_utils_pack_data("2L3s2c2s2l", informinfo, 587 sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE); 588 } 589 590 static void 591 ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer) 592 { 593 594 sa_node_record_t *node_record = (sa_node_record_t *)record; 595 596 /* first get record identifier information */ 597 ibmf_utils_pack_data("2s", node_record, 4, buffer, 598 IBMF_SAA_DEFAULT_RID_SIZE); 599 600 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 601 602 /* next get node info */ 603 ibmf_utils_pack_data("4c3L2s2l", &node_record->NodeInfo, 604 sizeof (sm_nodeinfo_t), buffer, SM_NODEINFO_SIZE); 605 606 buffer += SM_NODEINFO_SIZE; 607 608 /* next get node description */ 609 ibmf_utils_pack_data("64c", &node_record->NodeDescription, 610 sizeof (sm_nodedesc_t), buffer, SM_NODEDESC_SIZE); 611 612 } 613 614 static void 615 ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer) 616 { 617 618 sa_portinfo_record_t *portinfo_record = 619 (sa_portinfo_record_t *)record; 620 621 /* first get record identifier information */ 622 ibmf_utils_pack_data("s2c", portinfo_record, 4, buffer, 623 IBMF_SAA_DEFAULT_RID_SIZE); 624 625 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 626 627 /* next get portinfo info */ 628 ibmf_utils_pack_data("LLsslss16c3s4c", 629 &portinfo_record->PortInfo, sizeof (sm_portinfo_t), buffer, 630 SM_PORTINFO_SIZE); 631 632 } 633 634 static void 635 ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer) 636 { 637 638 sa_SLtoVLmapping_record_t *SLtoVLmapping_record = 639 (sa_SLtoVLmapping_record_t *)record; 640 641 /* first get record identifier information (plus 4 bytes reserved) */ 642 ibmf_utils_pack_data("s2cl", SLtoVLmapping_record, 8, buffer, 643 IBMF_SAA_DEFAULT_RID_SIZE + 4); 644 645 /* SLtoVL mapping has 4 reserved bytes between RID and attribute */ 646 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 647 648 /* next get SLtoVLmapping info */ 649 ibmf_utils_pack_data("8c", &SLtoVLmapping_record->SLtoVLMappingTable, 650 sizeof (sm_SLtoVL_mapping_table_t), buffer, SM_SLTOVL_SIZE); 651 } 652 653 static void 654 ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer) 655 { 656 657 sa_switchinfo_record_t *switchinfo_record = 658 (sa_switchinfo_record_t *)record; 659 660 /* first get record identifier information */ 661 ibmf_utils_pack_data("2s", switchinfo_record, 4, buffer, 662 IBMF_SAA_DEFAULT_RID_SIZE); 663 664 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 665 666 /* next get switchinfo info */ 667 ibmf_utils_pack_data("4s4c2sc", &switchinfo_record->SwitchInfo, 668 sizeof (sm_switchinfo_t), buffer, SM_SWITCHINFO_SIZE); 669 670 } 671 672 static void 673 ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer) 674 { 675 676 sa_linearft_record_t *linearft_record = 677 (sa_linearft_record_t *)record; 678 679 /* first get record identifier information (plus 4 bytes reserved) */ 680 ibmf_utils_pack_data("2sl", linearft_record, 8, buffer, 681 IBMF_SAA_DEFAULT_RID_SIZE + 4); 682 683 /* LFT has 4 reserved bytes between RID and attribute */ 684 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 685 686 /* next get linearft info */ 687 ibmf_utils_pack_data("64c", &linearft_record->LinearFT, 688 sizeof (sm_linear_forwarding_table_t), buffer, SM_LINEARFDB_SIZE); 689 } 690 691 static void 692 ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer) 693 { 694 695 sa_randomft_record_t *randomft_record = 696 (sa_randomft_record_t *)record; 697 698 /* first get record identifier information (plus 4 bytes reserved) */ 699 ibmf_utils_pack_data("2sl", randomft_record, 8, buffer, 700 IBMF_SAA_DEFAULT_RID_SIZE + 4); 701 702 /* RFT has 4 reserved bytes between RID and attribute */ 703 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 704 705 /* next get randomft info */ 706 ibmf_utils_pack_data("64c", &randomft_record->RandomFT, 707 sizeof (sm_random_forwarding_table_t), buffer, SM_RANDOMFDB_SIZE); 708 } 709 710 static void 711 ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer) 712 { 713 714 sa_multicastft_record_t *multicastft_record = 715 (sa_multicastft_record_t *)record; 716 717 /* first get record identifier information (plus 4 bytes reserved) */ 718 ibmf_utils_pack_data("2sl", multicastft_record, 8, buffer, 719 IBMF_SAA_DEFAULT_RID_SIZE + 4); 720 721 /* MFT has 4 reserved bytes between RID and attribute */ 722 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 723 724 /* next get multicastft info */ 725 ibmf_utils_pack_data("32s", &multicastft_record->MulticastFT, 726 sizeof (sm_multicast_forwarding_table_t), buffer, 727 SM_MULTICASTFDB_SIZE); 728 } 729 730 static void 731 ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer) 732 { 733 734 sa_sminfo_record_t *sminfo_record = 735 (sa_sminfo_record_t *)record; 736 737 /* first get record identifier information */ 738 ibmf_utils_pack_data("2s", sminfo_record, 4, buffer, 739 IBMF_SAA_DEFAULT_RID_SIZE); 740 741 buffer += IBMF_SAA_DEFAULT_RID_SIZE; 742 743 /* next get sminfo info */ 744 ibmf_utils_pack_data("2Llc", &sminfo_record->SMInfo, 745 sizeof (sm_sminfo_t), buffer, SM_SMINFO_SIZE); 746 } 747 748 static void 749 ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer) 750 { 751 752 sa_informinfo_record_t *informinfo_record = 753 (sa_informinfo_record_t *)record; 754 755 /* first get record identifier information */ 756 ibmf_utils_pack_data("2Ls", informinfo_record, 18, buffer, 757 IBMF_SAA_INFORMINFO_RID_SIZE); 758 759 /* InformInfo has 6 reserved bytes between RID and attribute */ 760 buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6; 761 762 /* next get informinfo info */ 763 ibmf_utils_pack_data("2L3s2c2s2l", &informinfo_record->InformInfo, 764 sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE); 765 } 766 767 static void 768 ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer) 769 { 770 771 sa_link_record_t *link_record = (sa_link_record_t *)record; 772 773 ibmf_utils_pack_data("s2cs", link_record, 774 sizeof (sa_link_record_t), buffer, IBMF_SAA_LINK_RECORD_SIZE); 775 } 776 777 static void 778 ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer) 779 { 780 781 sa_guidinfo_record_t *guidinfo_record = 782 (sa_guidinfo_record_t *)record; 783 784 /* first get record identifier information (plus 4 bytes reserved) */ 785 ibmf_utils_pack_data("s2cl", guidinfo_record, 786 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); 787 788 /* GUIDInfo has 4 reserved bytes between RID and attribute */ 789 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 790 791 /* next get guidinfo info */ 792 ibmf_utils_pack_data("8L", &guidinfo_record->GUIDInfo, 793 sizeof (sm_guidinfo_t), buffer, SM_GUIDINFO_SIZE); 794 } 795 796 static void 797 ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer) 798 { 799 800 sa_service_record_t *service_record = (sa_service_record_t *)record; 801 802 ibmf_utils_pack_data("3L2sl2L64c16c8s4l2L", service_record, 803 sizeof (sa_service_record_t), buffer, IBMF_SAA_SERVICE_RECORD_SIZE); 804 } 805 806 static void 807 ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer) 808 { 809 810 sa_pkey_table_record_t *partition_record = 811 (sa_pkey_table_record_t *)record; 812 813 /* first get record identifier information (plus 4 bytes reserved) */ 814 ibmf_utils_pack_data("2s4c", partition_record, 8, buffer, 815 IBMF_SAA_PARTITION_RID_SIZE + 3); 816 817 /* Partition record has 3 reserved bytes between RID and attribute */ 818 buffer += IBMF_SAA_PARTITION_RID_SIZE + 3; 819 820 /* next get partition info */ 821 ibmf_utils_pack_data("32s", &partition_record->P_KeyTable, 822 sizeof (sm_pkey_table_t), buffer, SM_PARTITION_SIZE); 823 } 824 825 static void 826 ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer) 827 { 828 829 sa_path_record_t *path_record = (sa_path_record_t *)record; 830 831 ibmf_utils_pack_data("2l4L2sl2c2s4c", path_record, 832 sizeof (sa_path_record_t), buffer, IBMF_SAA_PATH_RECORD_SIZE); 833 } 834 835 static void 836 ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer) 837 { 838 839 sa_VLarb_table_record_t *VLarb_table_record = 840 (sa_VLarb_table_record_t *)record; 841 842 /* first get record identifier information (plus 4 bytes reserved) */ 843 ibmf_utils_pack_data("s2c", VLarb_table_record, 8, buffer, 844 IBMF_SAA_DEFAULT_RID_SIZE + 4); 845 846 /* VLarb record has 4 reserved bytes between RID and attribute */ 847 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; 848 849 /* next get VLarb_table info */ 850 ibmf_utils_pack_data("64c", &VLarb_table_record->VLArbTable, 851 sizeof (sm_VLarb_table_t), buffer, SM_VLARB_SIZE); 852 } 853 854 855 static void 856 ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer) 857 { 858 859 sa_mcmember_record_t *mcmember_record = 860 (sa_mcmember_record_t *)record; 861 862 ibmf_utils_pack_data("4Lls2cs2c2l", mcmember_record, 863 sizeof (sa_mcmember_record_t), 864 buffer, IBMF_SAA_MCMEMBER_RECORD_SIZE); 865 } 866 867 static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer) 868 { 869 char gid_str[20]; 870 uint16_t num_gids; 871 sa_multipath_record_t *multipath_record = 872 (sa_multipath_record_t *)record; 873 874 num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount; 875 876 (void) sprintf(gid_str, "l2c2s14c%dL", 2 * num_gids); 877 878 ibmf_utils_pack_data(gid_str, multipath_record, 879 sizeof (sa_multipath_record_t) + sizeof (ib_gid_t) * num_gids, 880 buffer, 881 IBMF_SAA_MULTIPATH_RECORD_SIZE + sizeof (ib_gid_t) * num_gids); 882 } 883 884 static void 885 ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer) 886 { 887 888 sa_service_assn_record_t *service_assn_record = 889 (sa_service_assn_record_t *)record; 890 891 ibmf_utils_pack_data("2L64c", service_assn_record, 892 sizeof (sa_service_assn_record_t), 893 buffer, IBMF_SAA_SERVICEASSN_RECORD_SIZE); 894 } 895 896 int 897 ibmf_saa_utils_pack_sa_hdr(ib_sa_hdr_t *sa_hdr, void **packed_class_hdr, 898 size_t *packed_class_hdr_len, int km_sleep_flag) 899 { 900 901 *packed_class_hdr = kmem_zalloc(IBMF_SAA_HDR_SIZE, km_sleep_flag); 902 if (*packed_class_hdr == NULL) { 903 904 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1, 905 ibmf_saa_utils_pack_sa_hdr_err, 906 IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_sa_hdr: " 907 "could not allocate memory for header\n"); 908 909 return (IBMF_NO_MEMORY); 910 } 911 912 ibmf_utils_pack_data("LssL", sa_hdr, sizeof (ib_sa_hdr_t), 913 (uchar_t *)*packed_class_hdr, IBMF_SAA_HDR_SIZE); 914 915 *packed_class_hdr_len = IBMF_SAA_HDR_SIZE; 916 917 return (IBMF_SUCCESS); 918 } 919 920 int 921 ibmf_saa_utils_unpack_sa_hdr(void *packed_class_hdr, 922 size_t packed_class_hdr_len, ib_sa_hdr_t **sa_hdr, int km_sleep_flag) 923 { 924 if (packed_class_hdr_len != IBMF_SAA_HDR_SIZE) { 925 926 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1, 927 ibmf_saa_utils_unpack_sa_hdr_err, 928 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: %s," 929 " sa_class_hdr_len = %d, pkt_class_hdr_len = %d\n", 930 tnf_string, msg, "invalid class hdr length for SA packet", 931 tnf_int, sa_class_hdr_len, IBMF_SAA_HDR_SIZE, 932 tnf_int, pkt_class_hdr_len, packed_class_hdr_len); 933 934 return (IBMF_REQ_INVALID); 935 } 936 937 *sa_hdr = kmem_zalloc(sizeof (ib_sa_hdr_t), km_sleep_flag); 938 if (*sa_hdr == NULL) { 939 940 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1, 941 ibmf_saa_utils_unpack_sa_hdr_err, 942 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: " 943 "could not allocate memory for header\n"); 944 945 return (IBMF_NO_MEMORY); 946 } 947 948 ibmf_utils_unpack_data("LssL", (uchar_t *)packed_class_hdr, 949 IBMF_SAA_HDR_SIZE, *sa_hdr, sizeof (ib_sa_hdr_t)); 950 951 return (IBMF_SUCCESS); 952 } 953 954 /* 955 * ibmf_saa_utils_pack_payload: 956 * 957 * Takes a pointer to an array of sa record structures. For each element packs 958 * the structure into a character buffer removing any padding and account for 959 * endianness issues. 960 * 961 */ 962 int 963 ibmf_saa_utils_pack_payload(uchar_t *structs_payload, size_t 964 structs_payload_length, uint16_t attr_id, void **buf_payloadp, 965 size_t *buf_payload_lengthp, int km_sleep_flag) 966 { 967 968 int i; 969 int struct_size, buf_size; 970 int num_records; 971 void (*pack_data_fn)(void *, uchar_t *); 972 973 if (structs_payload_length == 0) { 974 975 *buf_payload_lengthp = 0; 976 *buf_payloadp = NULL; 977 978 return (IBMF_SUCCESS); 979 } 980 981 ASSERT(structs_payload != NULL); 982 983 /* trace records should never be sent (or packed) by ibmf_saa */ 984 ASSERT(attr_id != SA_TRACERECORD_ATTRID); 985 986 switch (attr_id) { 987 case SA_CLASSPORTINFO_ATTRID: 988 struct_size = sizeof (ib_mad_classportinfo_t); 989 buf_size = IB_MAD_CLASSPORTINFO_SIZE; 990 pack_data_fn = ibmf_saa_classportinfo_to_buf; 991 break; 992 case SA_NOTICE_ATTRID: 993 struct_size = sizeof (ib_mad_notice_t); 994 buf_size = IB_MAD_NOTICE_SIZE; 995 pack_data_fn = ibmf_saa_notice_to_buf; 996 break; 997 case SA_INFORMINFO_ATTRID: 998 struct_size = sizeof (ib_mad_informinfo_t); 999 buf_size = IB_MAD_INFORMINFO_SIZE; 1000 pack_data_fn = ibmf_saa_informinfo_to_buf; 1001 break; 1002 case SA_NODERECORD_ATTRID: 1003 struct_size = sizeof (sa_node_record_t); 1004 buf_size = IBMF_SAA_NODE_RECORD_SIZE; 1005 pack_data_fn = ibmf_saa_node_record_to_buf; 1006 break; 1007 case SA_PORTINFORECORD_ATTRID: 1008 struct_size = sizeof (sa_portinfo_record_t); 1009 buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE; 1010 pack_data_fn = ibmf_saa_portinfo_record_to_buf; 1011 break; 1012 case SA_SLTOVLRECORD_ATTRID: 1013 struct_size = sizeof (sa_SLtoVLmapping_record_t); 1014 buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE; 1015 pack_data_fn = ibmf_saa_SLtoVLmapping_record_to_buf; 1016 break; 1017 case SA_SWITCHINFORECORD_ATTRID: 1018 struct_size = sizeof (sa_switchinfo_record_t); 1019 buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE; 1020 pack_data_fn = ibmf_saa_switchinfo_record_to_buf; 1021 break; 1022 case SA_LINEARFDBRECORD_ATTRID: 1023 struct_size = sizeof (sa_linearft_record_t); 1024 buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE; 1025 pack_data_fn = ibmf_saa_linearft_record_to_buf; 1026 break; 1027 case SA_RANDOMFDBRECORD_ATTRID: 1028 struct_size = sizeof (sa_randomft_record_t); 1029 buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE; 1030 pack_data_fn = ibmf_saa_randomft_record_to_buf; 1031 break; 1032 case SA_MULTICASTFDBRECORD_ATTRID: 1033 struct_size = sizeof (sa_multicastft_record_t); 1034 buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE; 1035 pack_data_fn = ibmf_saa_multicastft_record_to_buf; 1036 break; 1037 case SA_SMINFORECORD_ATTRID: 1038 struct_size = sizeof (sa_sminfo_record_t); 1039 buf_size = IBMF_SAA_SMINFO_RECORD_SIZE; 1040 pack_data_fn = ibmf_saa_sminfo_record_to_buf; 1041 break; 1042 case SA_INFORMINFORECORD_ATTRID: 1043 struct_size = sizeof (sa_informinfo_record_t); 1044 buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE; 1045 pack_data_fn = ibmf_saa_informinfo_record_to_buf; 1046 break; 1047 case SA_LINKRECORD_ATTRID: 1048 struct_size = sizeof (sa_link_record_t); 1049 buf_size = IBMF_SAA_LINK_RECORD_SIZE; 1050 pack_data_fn = ibmf_saa_link_record_to_buf; 1051 break; 1052 case SA_GUIDINFORECORD_ATTRID: 1053 struct_size = sizeof (sa_guidinfo_record_t); 1054 buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE; 1055 pack_data_fn = ibmf_saa_guidinfo_record_to_buf; 1056 break; 1057 case SA_SERVICERECORD_ATTRID: 1058 struct_size = sizeof (sa_service_record_t); 1059 buf_size = IBMF_SAA_SERVICE_RECORD_SIZE; 1060 pack_data_fn = ibmf_saa_service_record_to_buf; 1061 break; 1062 case SA_PARTITIONRECORD_ATTRID: 1063 struct_size = sizeof (sa_pkey_table_record_t); 1064 buf_size = IBMF_SAA_PARTITION_RECORD_SIZE; 1065 pack_data_fn = ibmf_saa_partition_record_to_buf; 1066 break; 1067 case SA_PATHRECORD_ATTRID: 1068 struct_size = sizeof (sa_path_record_t); 1069 buf_size = IBMF_SAA_PATH_RECORD_SIZE; 1070 pack_data_fn = ibmf_saa_path_record_to_buf; 1071 break; 1072 case SA_VLARBRECORD_ATTRID: 1073 struct_size = sizeof (sa_VLarb_table_record_t); 1074 buf_size = IBMF_SAA_VLARB_RECORD_SIZE; 1075 pack_data_fn = ibmf_saa_vlarb_record_to_buf; 1076 break; 1077 case SA_MCMEMBERRECORD_ATTRID: 1078 struct_size = sizeof (sa_mcmember_record_t); 1079 buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE; 1080 pack_data_fn = ibmf_saa_mcmember_record_to_buf; 1081 break; 1082 case SA_MULTIPATHRECORD_ATTRID: 1083 /* 1084 * array is of size 1 since multipath can be request 1085 * only; data size greater than multipath_record_t 1086 * size is due to gids at the end 1087 */ 1088 struct_size = structs_payload_length; 1089 buf_size = IBMF_SAA_MULTIPATH_RECORD_SIZE + 1090 struct_size - sizeof (sa_multipath_record_t); 1091 pack_data_fn = ibmf_saa_multipath_record_to_buf; 1092 break; 1093 case SA_SERVICEASSNRECORD_ATTRID: 1094 struct_size = sizeof (sa_service_assn_record_t); 1095 buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE; 1096 pack_data_fn = ibmf_saa_service_assn_record_to_buf; 1097 break; 1098 default: 1099 1100 /* don't know about structure; do bcopy */ 1101 *buf_payload_lengthp = structs_payload_length; 1102 *buf_payloadp = kmem_zalloc(*buf_payload_lengthp, 1103 km_sleep_flag); 1104 if (*buf_payloadp == NULL) { 1105 1106 *buf_payload_lengthp = 0; 1107 return (IBMF_NO_MEMORY); 1108 } 1109 1110 bcopy(structs_payload, *buf_payloadp, 1111 *buf_payload_lengthp); 1112 1113 return (IBMF_SUCCESS); 1114 } 1115 1116 *buf_payload_lengthp = structs_payload_length / struct_size * buf_size; 1117 num_records = structs_payload_length / struct_size; 1118 *buf_payloadp = kmem_zalloc(*buf_payload_lengthp, km_sleep_flag); 1119 if (*buf_payloadp == NULL) { 1120 1121 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1, 1122 ibmf_saa_utils_pack_payload_err, 1123 IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_payload: %s," 1124 " size = %d\n", 1125 tnf_string, msg, "could not allocate memory for payload", 1126 tnf_int, size, *buf_payload_lengthp); 1127 1128 *buf_payload_lengthp = 0; 1129 return (IBMF_NO_MEMORY); 1130 } 1131 1132 for (i = 0; i < num_records; i++) { 1133 1134 pack_data_fn( 1135 (void *)((uchar_t *)structs_payload + i * struct_size), 1136 ((uchar_t *)*buf_payloadp + i * buf_size)); 1137 } 1138 1139 return (IBMF_SUCCESS); 1140 } 1141 1142 1143 /* 1144 * ibmf_saa_utils_unpack_payload: 1145 * 1146 * Unpacks a buffer of data received over the wire and places into an array of 1147 * structure in host format. 1148 * 1149 * for getResp() ibmf always reports payload length as 200 bytes 1150 * (MAD_SIZE - headers). To keep the client from having to determine the actual 1151 * length of the one attribute (since we do it here) the is_get_resp parameter 1152 * indicates that there is one attribute in the buffer. 1153 */ 1154 int 1155 ibmf_saa_utils_unpack_payload(uchar_t *buf_payload, size_t buf_payload_length, 1156 uint16_t attr_id, void **structs_payloadp, size_t *structs_payload_lengthp, 1157 uint16_t attr_offset, boolean_t is_get_resp, int km_sleep_flag) 1158 { 1159 1160 int i; 1161 int struct_size, buf_size; 1162 int num_records; 1163 void (*unpack_data_fn)(uchar_t *, void *); 1164 int bytes_between_recs; 1165 1166 if (buf_payload_length == 0) { 1167 1168 *structs_payload_lengthp = 0; 1169 *structs_payloadp = NULL; 1170 1171 return (IBMF_SUCCESS); 1172 } 1173 1174 switch (attr_id) { 1175 case SA_CLASSPORTINFO_ATTRID: 1176 struct_size = sizeof (ib_mad_classportinfo_t); 1177 buf_size = IB_MAD_CLASSPORTINFO_SIZE; 1178 unpack_data_fn = ibmf_saa_classportinfo_parse_buffer; 1179 break; 1180 case SA_NOTICE_ATTRID: 1181 struct_size = sizeof (ib_mad_notice_t); 1182 buf_size = IB_MAD_NOTICE_SIZE; 1183 unpack_data_fn = ibmf_saa_notice_parse_buffer; 1184 break; 1185 case SA_INFORMINFO_ATTRID: 1186 struct_size = sizeof (ib_mad_informinfo_t); 1187 buf_size = IB_MAD_INFORMINFO_SIZE; 1188 unpack_data_fn = ibmf_saa_informinfo_parse_buffer; 1189 break; 1190 case SA_NODERECORD_ATTRID: 1191 struct_size = sizeof (sa_node_record_t); 1192 buf_size = IBMF_SAA_NODE_RECORD_SIZE; 1193 unpack_data_fn = ibmf_saa_node_record_parse_buffer; 1194 break; 1195 case SA_PORTINFORECORD_ATTRID: 1196 struct_size = sizeof (sa_portinfo_record_t); 1197 buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE; 1198 unpack_data_fn = ibmf_saa_portinfo_record_parse_buffer; 1199 break; 1200 case SA_SLTOVLRECORD_ATTRID: 1201 struct_size = sizeof (sa_SLtoVLmapping_record_t); 1202 buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE; 1203 unpack_data_fn = 1204 ibmf_saa_SLtoVLmapping_record_parse_buffer; 1205 break; 1206 case SA_SWITCHINFORECORD_ATTRID: 1207 struct_size = sizeof (sa_switchinfo_record_t); 1208 buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE; 1209 unpack_data_fn = 1210 ibmf_saa_switchinfo_record_parse_buffer; 1211 break; 1212 case SA_LINEARFDBRECORD_ATTRID: 1213 struct_size = sizeof (sa_linearft_record_t); 1214 buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE; 1215 unpack_data_fn = ibmf_saa_linearft_record_parse_buffer; 1216 break; 1217 case SA_RANDOMFDBRECORD_ATTRID: 1218 struct_size = sizeof (sa_randomft_record_t); 1219 buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE; 1220 unpack_data_fn = ibmf_saa_randomft_record_parse_buffer; 1221 break; 1222 case SA_MULTICASTFDBRECORD_ATTRID: 1223 struct_size = sizeof (sa_multicastft_record_t); 1224 buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE; 1225 unpack_data_fn = 1226 ibmf_saa_multicastft_record_parse_buffer; 1227 break; 1228 case SA_SMINFORECORD_ATTRID: 1229 struct_size = sizeof (sa_sminfo_record_t); 1230 buf_size = IBMF_SAA_SMINFO_RECORD_SIZE; 1231 unpack_data_fn = ibmf_saa_sminfo_record_parse_buffer; 1232 break; 1233 case SA_INFORMINFORECORD_ATTRID: 1234 struct_size = sizeof (sa_informinfo_record_t); 1235 buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE; 1236 unpack_data_fn = 1237 ibmf_saa_informinfo_record_parse_buffer; 1238 break; 1239 case SA_LINKRECORD_ATTRID: 1240 struct_size = sizeof (sa_link_record_t); 1241 buf_size = IBMF_SAA_LINK_RECORD_SIZE; 1242 unpack_data_fn = ibmf_saa_link_record_parse_buffer; 1243 break; 1244 case SA_GUIDINFORECORD_ATTRID: 1245 struct_size = sizeof (sa_guidinfo_record_t); 1246 buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE; 1247 unpack_data_fn = ibmf_saa_guidinfo_record_parse_buffer; 1248 break; 1249 case SA_SERVICERECORD_ATTRID: 1250 struct_size = sizeof (sa_service_record_t); 1251 buf_size = IBMF_SAA_SERVICE_RECORD_SIZE; 1252 unpack_data_fn = ibmf_saa_service_record_parse_buffer; 1253 break; 1254 case SA_PARTITIONRECORD_ATTRID: 1255 struct_size = sizeof (sa_pkey_table_record_t); 1256 buf_size = IBMF_SAA_PARTITION_RECORD_SIZE; 1257 unpack_data_fn = 1258 ibmf_saa_partition_record_parse_buffer; 1259 break; 1260 case SA_PATHRECORD_ATTRID: 1261 struct_size = sizeof (sa_path_record_t); 1262 buf_size = IBMF_SAA_PATH_RECORD_SIZE; 1263 unpack_data_fn = ibmf_saa_path_record_parse_buffer; 1264 break; 1265 case SA_VLARBRECORD_ATTRID: 1266 struct_size = sizeof (sa_VLarb_table_record_t); 1267 buf_size = IBMF_SAA_VLARB_RECORD_SIZE; 1268 unpack_data_fn = ibmf_saa_vlarb_record_parse_buffer; 1269 break; 1270 case SA_MCMEMBERRECORD_ATTRID: 1271 struct_size = sizeof (sa_mcmember_record_t); 1272 buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE; 1273 unpack_data_fn = ibmf_saa_mcmember_record_parse_buffer; 1274 break; 1275 case SA_TRACERECORD_ATTRID: 1276 struct_size = sizeof (sa_trace_record_t); 1277 buf_size = IBMF_SAA_TRACE_RECORD_SIZE; 1278 unpack_data_fn = ibmf_saa_trace_record_parse_buffer; 1279 break; 1280 case SA_MULTIPATHRECORD_ATTRID: 1281 /* 1282 * array is of size 1 since multipath can be request 1283 * only; data size greater than multipath_record_t 1284 * size is due to gids at the end 1285 */ 1286 buf_size = buf_payload_length; 1287 struct_size = sizeof (sa_multipath_record_t) + 1288 buf_size - IBMF_SAA_MULTIPATH_RECORD_SIZE; 1289 unpack_data_fn = ibmf_saa_multipath_record_parse_buffer; 1290 break; 1291 case SA_SERVICEASSNRECORD_ATTRID: 1292 struct_size = sizeof (sa_service_assn_record_t); 1293 buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE; 1294 unpack_data_fn = 1295 ibmf_saa_service_assn_record_parse_buffer; 1296 break; 1297 default: 1298 /* don't know about structure; do bcopy */ 1299 1300 *structs_payload_lengthp = buf_payload_length; 1301 *structs_payloadp = kmem_zalloc( 1302 *structs_payload_lengthp, km_sleep_flag); 1303 if (*structs_payloadp == NULL) { 1304 1305 *structs_payload_lengthp = 0; 1306 return (IBMF_NO_MEMORY); 1307 } 1308 1309 bcopy(buf_payload, *structs_payloadp, 1310 *structs_payload_lengthp); 1311 1312 return (IBMF_SUCCESS); 1313 } 1314 1315 /* compute distance between successive records */ 1316 if (attr_offset > 0) { 1317 1318 if ((attr_offset * 8) < buf_size) { 1319 1320 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1, 1321 ibmf_saa_utils_unpack_payload, IBMF_TNF_ERROR, "", 1322 "ibmf_saa_utils_unpack_payload: %s, attr_offset = " 1323 "%d, attr_size = %d\n", 1324 tnf_string, msg, "attribute offset times 8 is less" 1325 " than attribute size", 1326 tnf_int, attr_offset, attr_offset, 1327 tnf_int, attr_size, buf_size); 1328 1329 return (IBMF_TRANS_FAILURE); 1330 } 1331 1332 bytes_between_recs = attr_offset * 8; 1333 } else { 1334 bytes_between_recs = buf_size; 1335 } 1336 1337 if (is_get_resp == B_TRUE) { 1338 1339 buf_payload_length = buf_size; 1340 num_records = 1; 1341 } else { 1342 1343 num_records = buf_payload_length / bytes_between_recs; 1344 } 1345 1346 *structs_payload_lengthp = num_records * struct_size; 1347 1348 *structs_payloadp = kmem_zalloc(*structs_payload_lengthp, 1349 km_sleep_flag); 1350 if (*structs_payloadp == NULL) { 1351 1352 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1, 1353 ibmf_saa_utils_unpack_payload_err, 1354 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_payload: %s," 1355 " size = %d\n", 1356 tnf_string, msg, "could not allocate memory for payload", 1357 tnf_int, size, *structs_payload_lengthp); 1358 1359 *structs_payload_lengthp = 0; 1360 return (IBMF_NO_MEMORY); 1361 } 1362 1363 1364 for (i = 0; i < num_records; i++) { 1365 1366 unpack_data_fn( 1367 (uchar_t *)buf_payload + (i * bytes_between_recs), 1368 (void *)((uchar_t *)*structs_payloadp + i * 1369 struct_size)); 1370 } 1371 1372 return (IBMF_SUCCESS); 1373 } 1374