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