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