/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #define IBMF_SAA_HDR_SIZE 20 #define IBMF_SAA_DEFAULT_RID_SIZE 4 #define IBMF_SAA_PARTITION_RID_SIZE 5 #define IBMF_SAA_INFORMINFO_RID_SIZE 18 #define IB_MAD_NOTICE_SIZE 80 #define IB_MAD_CLASSPORTINFO_SIZE 72 #define IB_MAD_INFORMINFO_SIZE 36 #define SM_TRAP_DATA_DETAILS_SIZE 54 #define SM_NODEINFO_SIZE 40 #define SM_NODEDESC_SIZE 64 #define SM_PORTINFO_SIZE 54 #define SM_SLTOVL_SIZE 8 #define SM_SWITCHINFO_SIZE 17 #define SM_LINEARFDB_SIZE 64 #define SM_RANDOMFDB_SIZE 64 #define SM_MULTICASTFDB_SIZE 64 #define SM_SMINFO_SIZE 21 #define SM_GUIDINFO_SIZE 64 #define SM_PARTITION_SIZE 64 #define SM_VLARB_SIZE 64 #define IBMF_SAA_NODE_RECORD_SIZE 108 #define IBMF_SAA_PORTINFO_RECORD_SIZE 58 #define IBMF_SAA_SLTOVL_RECORD_SIZE 16 #define IBMF_SAA_SWITCHINFO_RECORD_SIZE 21 #define IBMF_SAA_LINEARFDB_RECORD_SIZE 72 #define IBMF_SAA_RANDOMFDB_RECORD_SIZE 72 #define IBMF_SAA_MULTICASTFDB_RECORD_SIZE 72 #define IBMF_SAA_SMINFO_RECORD_SIZE 25 #define IBMF_SAA_INFORMINFO_RECORD_SIZE 60 #define IBMF_SAA_LINK_RECORD_SIZE 6 #define IBMF_SAA_GUIDINFO_RECORD_SIZE 72 #define IBMF_SAA_SERVICE_RECORD_SIZE 176 #define IBMF_SAA_PARTITION_RECORD_SIZE 72 #define IBMF_SAA_PATH_RECORD_SIZE 64 #define IBMF_SAA_VLARB_RECORD_SIZE 72 #define IBMF_SAA_MCMEMBER_RECORD_SIZE 52 #define IBMF_SAA_TRACE_RECORD_SIZE 46 #define IBMF_SAA_MULTIPATH_RECORD_SIZE 24 #define IBMF_SAA_SERVICEASSN_RECORD_SIZE 80 extern int ibmf_trace_level; /* These functions have only been tested on a big-endian system */ static void ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_partition_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer, void *record); static void ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_notice_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer); static void ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer); /* * *_record_parse_buffer functions: * * Each of these functions parses a buffer containing a single SA record. * The function copies the buffer into a structure taking care of any padding * and byte-endianness issues. There is one function for each of the 22 * attributes (Table 155). * * ibmf_utils_unpack_data() must be called for each structure in the structure * since Solaris will align the internal structure on a 64-bit boundary, even if * the first element is a 32-bit value. * * Input Arguments * buffer pointer character array containing raw data * * Output Arguments * record pointer to the SA attribute structure * * Returns void */ static void ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record) { ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record; ibmf_utils_unpack_data("2csl2Ll2s2l2Ll2s2l", buffer, IB_MAD_CLASSPORTINFO_SIZE, cpi, sizeof (ib_mad_classportinfo_t)); } static void ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record) { ib_mad_notice_t *notice = (ib_mad_notice_t *)record; ibmf_utils_unpack_data("4c3s54c2L", buffer, IB_MAD_NOTICE_SIZE, notice, sizeof (ib_mad_notice_t)); } static void ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record) { ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record; ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE, informinfo, sizeof (ib_mad_informinfo_t)); } static void ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record) { sa_node_record_t *node_record = (sa_node_record_t *)record; /* first get record identifier information */ ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE, node_record, 4); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get node info */ ibmf_utils_unpack_data("4c3L2s2l", buffer, SM_NODEINFO_SIZE, &node_record->NodeInfo, sizeof (sm_nodeinfo_t)); buffer += SM_NODEINFO_SIZE; ibmf_utils_unpack_data("64c", buffer, SM_NODEDESC_SIZE, &node_record->NodeDescription, sizeof (sm_nodedesc_t)); } static void ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer, void *record) { sa_portinfo_record_t *portinfo_record = (sa_portinfo_record_t *)record; /* first get record identifier information */ ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE, portinfo_record, 4); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get portinfo info */ ibmf_utils_unpack_data("LLsslss16c3s4c", buffer, SM_PORTINFO_SIZE, &portinfo_record->PortInfo, sizeof (sm_portinfo_t)); } static void ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer, void *record) { sa_SLtoVLmapping_record_t *SLtoVLmapping_record = (sa_SLtoVLmapping_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, SLtoVLmapping_record, 8); /* SLtoVL mapping has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get SLtoVLmapping info */ ibmf_utils_unpack_data("8c", buffer, SM_SLTOVL_SIZE, &SLtoVLmapping_record->SLtoVLMappingTable, sizeof (sm_SLtoVL_mapping_table_t)); } static void ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer, void *record) { sa_switchinfo_record_t *switchinfo_record = (sa_switchinfo_record_t *)record; /* first get record identifier information */ ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE, switchinfo_record, 4); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get switchinfo info */ ibmf_utils_unpack_data("4s4c2sc", buffer, SM_SWITCHINFO_SIZE, &switchinfo_record->SwitchInfo, sizeof (sm_switchinfo_t)); } static void ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer, void *record) { sa_linearft_record_t *linearft_record = (sa_linearft_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, linearft_record, 8); /* LFT has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get linearft info */ ibmf_utils_unpack_data("64c", buffer, SM_LINEARFDB_SIZE, &linearft_record->LinearFT, sizeof (sm_linear_forwarding_table_t)); } static void ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer, void *record) { sa_randomft_record_t *randomft_record = (sa_randomft_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, randomft_record, 8); /* RFT has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get randomft info */ ibmf_utils_unpack_data("64c", buffer, SM_RANDOMFDB_SIZE, &randomft_record->RandomFT, sizeof (sm_random_forwarding_table_t)); } static void ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer, void *record) { sa_multicastft_record_t *multicastft_record = (sa_multicastft_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, multicastft_record, 8); /* MFT has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get multicastft info */ ibmf_utils_unpack_data("32s", buffer, SM_MULTICASTFDB_SIZE, &multicastft_record->MulticastFT, sizeof (sm_multicast_forwarding_table_t)); } static void ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record) { sa_sminfo_record_t *sminfo_record = (sa_sminfo_record_t *)record; /* first get record identifier information */ ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE, sminfo_record, 4); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get sminfo info */ ibmf_utils_unpack_data("2Llc", buffer, SM_SMINFO_SIZE, &sminfo_record->SMInfo, sizeof (sm_sminfo_t)); } static void ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer, void *record) { sa_informinfo_record_t *informinfo_record = (sa_informinfo_record_t *)record; /* first get record identifier information */ ibmf_utils_unpack_data("2Ls", buffer, IBMF_SAA_INFORMINFO_RID_SIZE, informinfo_record, 18); /* InformInfo has 6 reserved bytes between RID and attribute */ buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6; /* next get informinfo info */ ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE, &informinfo_record->InformInfo, sizeof (ib_mad_informinfo_t)); } static void ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record) { sa_link_record_t *link_record = (sa_link_record_t *)record; ibmf_utils_unpack_data("s2cs", buffer, IBMF_SAA_LINK_RECORD_SIZE, link_record, sizeof (sa_link_record_t)); } static void ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer, void *record) { sa_guidinfo_record_t *guidinfo_record = (sa_guidinfo_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, guidinfo_record, 8); /* GUIDInfo has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get guidinfo info */ ibmf_utils_unpack_data("8L", buffer, SM_GUIDINFO_SIZE, &guidinfo_record->GUIDInfo, sizeof (sm_guidinfo_t)); } static void ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record) { sa_service_record_t *service_record = (sa_service_record_t *)record; ibmf_utils_unpack_data("3L2sl2L64c16c8s4l2L", buffer, IBMF_SAA_SERVICE_RECORD_SIZE, service_record, sizeof (sa_service_record_t)); } static void ibmf_saa_partition_record_parse_buffer(uchar_t *buffer, void *record) { sa_pkey_table_record_t *partition_record = (sa_pkey_table_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("2s4c", buffer, IBMF_SAA_PARTITION_RID_SIZE + 3, partition_record, 8); /* Partition record has 3 reserved bytes between RID and attribute */ buffer += IBMF_SAA_PARTITION_RID_SIZE + 3; /* next get partition info */ ibmf_utils_unpack_data("32s", buffer, SM_PARTITION_SIZE, &partition_record->P_KeyTable, sizeof (sm_pkey_table_t)); } static void ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record) { sa_path_record_t *path_record = (sa_path_record_t *)record; ibmf_utils_unpack_data("2l4L2sl2c2s4c", buffer, IBMF_SAA_PATH_RECORD_SIZE, path_record, sizeof (sa_path_record_t)); } static void ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record) { sa_VLarb_table_record_t *VLarb_table_record = (sa_VLarb_table_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4, VLarb_table_record, 8); /* VLarb record has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get VLarb_table info */ ibmf_utils_unpack_data("64c", buffer, SM_VLARB_SIZE, &VLarb_table_record->VLArbTable, sizeof (sm_VLarb_table_t)); } static void ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer, void *record) { sa_mcmember_record_t *mcmember_record = (sa_mcmember_record_t *)record; ibmf_utils_unpack_data("4Lls2cs2c2l", buffer, IBMF_SAA_MCMEMBER_RECORD_SIZE, mcmember_record, sizeof (sa_mcmember_record_t)); } static void ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record) { sa_trace_record_t *trace_record = (sa_trace_record_t *)record; ibmf_utils_unpack_data("Ls2c4L2c", buffer, IBMF_SAA_TRACE_RECORD_SIZE, trace_record, sizeof (sa_trace_record_t)); } /* * ibmf_saa_multipath_record_parse_buffer: * * First unpack the standard part of the multipath record. Then find the number * of gids and unpack those. This function will probably never be called as the * ibmf_saa should not receive any multipath records. It's in here for * completeness. */ static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer, void *record) { char gid_str[20]; uint16_t num_gids; sa_multipath_record_t *multipath_record = (sa_multipath_record_t *)record; ibmf_utils_unpack_data("l2c2s14c", buffer, IBMF_SAA_MULTIPATH_RECORD_SIZE, multipath_record, sizeof (sa_multipath_record_t)); num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount; (void) sprintf(gid_str, "%dL", 2 * num_gids); ibmf_utils_unpack_data(gid_str, buffer + IBMF_SAA_MULTIPATH_RECORD_SIZE, sizeof (ib_gid_t) * num_gids, multipath_record + sizeof (sa_multipath_record_t), sizeof (ib_gid_t) * num_gids); } static void ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer, void *record) { sa_service_assn_record_t *service_assn_record = (sa_service_assn_record_t *)record; ibmf_utils_unpack_data("2L64c", buffer, IBMF_SAA_SERVICEASSN_RECORD_SIZE, service_assn_record, sizeof (sa_service_assn_record_t)); } void ibmf_saa_gid_trap_parse_buffer(uchar_t *buffer, sm_trap_64_t *sm_trap_64) { ibmf_utils_unpack_data("6c2L32c", buffer, SM_TRAP_DATA_DETAILS_SIZE, sm_trap_64, sizeof (sm_trap_64_t)); } void ibmf_saa_capmask_chg_trap_parse_buffer(uchar_t *buffer, sm_trap_144_t *sm_trap_144) { ibmf_utils_unpack_data("2cs2cl44c", buffer, SM_TRAP_DATA_DETAILS_SIZE, sm_trap_144, sizeof (sm_trap_144_t)); } void ibmf_saa_sysimg_guid_chg_trap_parse_buffer(uchar_t *buffer, sm_trap_145_t *sm_trap_145) { ibmf_utils_unpack_data("2cs2cL44c", buffer, SM_TRAP_DATA_DETAILS_SIZE, sm_trap_145, sizeof (sm_trap_145_t)); } /* * *_record_to_buf functions: * * Each of these functions copies a single SA record out of a structure and into * a buffer for sending on the wire. The function will take care of any padding * and byte-endianness isues. There is one function for each of the 22 * attributes (Table 155). * * ibmf_utils_pack_data() must be called for each structure in the structure * since Solaris will align the internal structure on a 64-bit boundary, even if * the first element is a 32-bit value. * * Input Arguments * record pointer to the structure to be parsed * * Output Arguments * buffer pointer to array to place the data in (allocated by caller) * * Returns void */ static void ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer) { ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record; ibmf_utils_pack_data("2csl2Ll2s2l2Ll2s2l", cpi, sizeof (ib_mad_classportinfo_t), buffer, IB_MAD_CLASSPORTINFO_SIZE); } static void ibmf_saa_notice_to_buf(void *record, uchar_t *buffer) { ib_mad_notice_t *notice = (ib_mad_notice_t *)record; ibmf_utils_pack_data("4c3s54c2L", notice, sizeof (ib_mad_notice_t), buffer, IB_MAD_NOTICE_SIZE); } static void ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer) { ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record; ibmf_utils_pack_data("2L3s2c2s2l", informinfo, sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE); } static void ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer) { sa_node_record_t *node_record = (sa_node_record_t *)record; /* first get record identifier information */ ibmf_utils_pack_data("2s", node_record, 4, buffer, IBMF_SAA_DEFAULT_RID_SIZE); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get node info */ ibmf_utils_pack_data("4c3L2s2l", &node_record->NodeInfo, sizeof (sm_nodeinfo_t), buffer, SM_NODEINFO_SIZE); buffer += SM_NODEINFO_SIZE; /* next get node description */ ibmf_utils_pack_data("64c", &node_record->NodeDescription, sizeof (sm_nodedesc_t), buffer, SM_NODEDESC_SIZE); } static void ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer) { sa_portinfo_record_t *portinfo_record = (sa_portinfo_record_t *)record; /* first get record identifier information */ ibmf_utils_pack_data("s2c", portinfo_record, 4, buffer, IBMF_SAA_DEFAULT_RID_SIZE); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get portinfo info */ ibmf_utils_pack_data("LLsslss16c3s4c", &portinfo_record->PortInfo, sizeof (sm_portinfo_t), buffer, SM_PORTINFO_SIZE); } static void ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer) { sa_SLtoVLmapping_record_t *SLtoVLmapping_record = (sa_SLtoVLmapping_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("s2cl", SLtoVLmapping_record, 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); /* SLtoVL mapping has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get SLtoVLmapping info */ ibmf_utils_pack_data("8c", &SLtoVLmapping_record->SLtoVLMappingTable, sizeof (sm_SLtoVL_mapping_table_t), buffer, SM_SLTOVL_SIZE); } static void ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer) { sa_switchinfo_record_t *switchinfo_record = (sa_switchinfo_record_t *)record; /* first get record identifier information */ ibmf_utils_pack_data("2s", switchinfo_record, 4, buffer, IBMF_SAA_DEFAULT_RID_SIZE); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get switchinfo info */ ibmf_utils_pack_data("4s4c2sc", &switchinfo_record->SwitchInfo, sizeof (sm_switchinfo_t), buffer, SM_SWITCHINFO_SIZE); } static void ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer) { sa_linearft_record_t *linearft_record = (sa_linearft_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("2sl", linearft_record, 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); /* LFT has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get linearft info */ ibmf_utils_pack_data("64c", &linearft_record->LinearFT, sizeof (sm_linear_forwarding_table_t), buffer, SM_LINEARFDB_SIZE); } static void ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer) { sa_randomft_record_t *randomft_record = (sa_randomft_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("2sl", randomft_record, 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); /* RFT has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get randomft info */ ibmf_utils_pack_data("64c", &randomft_record->RandomFT, sizeof (sm_random_forwarding_table_t), buffer, SM_RANDOMFDB_SIZE); } static void ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer) { sa_multicastft_record_t *multicastft_record = (sa_multicastft_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("2sl", multicastft_record, 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); /* MFT has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get multicastft info */ ibmf_utils_pack_data("32s", &multicastft_record->MulticastFT, sizeof (sm_multicast_forwarding_table_t), buffer, SM_MULTICASTFDB_SIZE); } static void ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer) { sa_sminfo_record_t *sminfo_record = (sa_sminfo_record_t *)record; /* first get record identifier information */ ibmf_utils_pack_data("2s", sminfo_record, 4, buffer, IBMF_SAA_DEFAULT_RID_SIZE); buffer += IBMF_SAA_DEFAULT_RID_SIZE; /* next get sminfo info */ ibmf_utils_pack_data("2Llc", &sminfo_record->SMInfo, sizeof (sm_sminfo_t), buffer, SM_SMINFO_SIZE); } static void ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer) { sa_informinfo_record_t *informinfo_record = (sa_informinfo_record_t *)record; /* first get record identifier information */ ibmf_utils_pack_data("2Ls", informinfo_record, 18, buffer, IBMF_SAA_INFORMINFO_RID_SIZE); /* InformInfo has 6 reserved bytes between RID and attribute */ buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6; /* next get informinfo info */ ibmf_utils_pack_data("2L3s2c2s2l", &informinfo_record->InformInfo, sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE); } static void ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer) { sa_link_record_t *link_record = (sa_link_record_t *)record; ibmf_utils_pack_data("s2cs", link_record, sizeof (sa_link_record_t), buffer, IBMF_SAA_LINK_RECORD_SIZE); } static void ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer) { sa_guidinfo_record_t *guidinfo_record = (sa_guidinfo_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("s2cl", guidinfo_record, 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); /* GUIDInfo has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get guidinfo info */ ibmf_utils_pack_data("8L", &guidinfo_record->GUIDInfo, sizeof (sm_guidinfo_t), buffer, SM_GUIDINFO_SIZE); } static void ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer) { sa_service_record_t *service_record = (sa_service_record_t *)record; ibmf_utils_pack_data("3L2sl2L64c16c8s4l2L", service_record, sizeof (sa_service_record_t), buffer, IBMF_SAA_SERVICE_RECORD_SIZE); } static void ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer) { sa_pkey_table_record_t *partition_record = (sa_pkey_table_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("2s4c", partition_record, 8, buffer, IBMF_SAA_PARTITION_RID_SIZE + 3); /* Partition record has 3 reserved bytes between RID and attribute */ buffer += IBMF_SAA_PARTITION_RID_SIZE + 3; /* next get partition info */ ibmf_utils_pack_data("32s", &partition_record->P_KeyTable, sizeof (sm_pkey_table_t), buffer, SM_PARTITION_SIZE); } static void ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer) { sa_path_record_t *path_record = (sa_path_record_t *)record; ibmf_utils_pack_data("2l4L2sl2c2s4c", path_record, sizeof (sa_path_record_t), buffer, IBMF_SAA_PATH_RECORD_SIZE); } static void ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer) { sa_VLarb_table_record_t *VLarb_table_record = (sa_VLarb_table_record_t *)record; /* first get record identifier information (plus 4 bytes reserved) */ ibmf_utils_pack_data("s2c", VLarb_table_record, 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4); /* VLarb record has 4 reserved bytes between RID and attribute */ buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4; /* next get VLarb_table info */ ibmf_utils_pack_data("64c", &VLarb_table_record->VLArbTable, sizeof (sm_VLarb_table_t), buffer, SM_VLARB_SIZE); } static void ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer) { sa_mcmember_record_t *mcmember_record = (sa_mcmember_record_t *)record; ibmf_utils_pack_data("4Lls2cs2c2l", mcmember_record, sizeof (sa_mcmember_record_t), buffer, IBMF_SAA_MCMEMBER_RECORD_SIZE); } static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer) { char gid_str[20]; uint16_t num_gids; sa_multipath_record_t *multipath_record = (sa_multipath_record_t *)record; num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount; (void) sprintf(gid_str, "l2c2s14c%dL", 2 * num_gids); ibmf_utils_pack_data(gid_str, multipath_record, sizeof (sa_multipath_record_t) + sizeof (ib_gid_t) * num_gids, buffer, IBMF_SAA_MULTIPATH_RECORD_SIZE + sizeof (ib_gid_t) * num_gids); } static void ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer) { sa_service_assn_record_t *service_assn_record = (sa_service_assn_record_t *)record; ibmf_utils_pack_data("2L64c", service_assn_record, sizeof (sa_service_assn_record_t), buffer, IBMF_SAA_SERVICEASSN_RECORD_SIZE); } int ibmf_saa_utils_pack_sa_hdr(ib_sa_hdr_t *sa_hdr, void **packed_class_hdr, size_t *packed_class_hdr_len, int km_sleep_flag) { *packed_class_hdr = kmem_zalloc(IBMF_SAA_HDR_SIZE, km_sleep_flag); if (*packed_class_hdr == NULL) { IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1, ibmf_saa_utils_pack_sa_hdr_err, IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_sa_hdr: " "could not allocate memory for header\n"); return (IBMF_NO_MEMORY); } ibmf_utils_pack_data("LssL", sa_hdr, sizeof (ib_sa_hdr_t), (uchar_t *)*packed_class_hdr, IBMF_SAA_HDR_SIZE); *packed_class_hdr_len = IBMF_SAA_HDR_SIZE; return (IBMF_SUCCESS); } int ibmf_saa_utils_unpack_sa_hdr(void *packed_class_hdr, size_t packed_class_hdr_len, ib_sa_hdr_t **sa_hdr, int km_sleep_flag) { if (packed_class_hdr_len != IBMF_SAA_HDR_SIZE) { IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1, ibmf_saa_utils_unpack_sa_hdr_err, IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: %s," " sa_class_hdr_len = %d, pkt_class_hdr_len = %d\n", tnf_string, msg, "invalid class hdr length for SA packet", tnf_int, sa_class_hdr_len, IBMF_SAA_HDR_SIZE, tnf_int, pkt_class_hdr_len, packed_class_hdr_len); return (IBMF_REQ_INVALID); } *sa_hdr = kmem_zalloc(sizeof (ib_sa_hdr_t), km_sleep_flag); if (*sa_hdr == NULL) { IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1, ibmf_saa_utils_unpack_sa_hdr_err, IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: " "could not allocate memory for header\n"); return (IBMF_NO_MEMORY); } ibmf_utils_unpack_data("LssL", (uchar_t *)packed_class_hdr, IBMF_SAA_HDR_SIZE, *sa_hdr, sizeof (ib_sa_hdr_t)); return (IBMF_SUCCESS); } /* * ibmf_saa_utils_pack_payload: * * Takes a pointer to an array of sa record structures. For each element packs * the structure into a character buffer removing any padding and account for * endianness issues. * */ int ibmf_saa_utils_pack_payload(uchar_t *structs_payload, size_t structs_payload_length, uint16_t attr_id, void **buf_payloadp, size_t *buf_payload_lengthp, int km_sleep_flag) { int i; int struct_size, buf_size; int num_records; void (*pack_data_fn)(void *, uchar_t *); if (structs_payload_length == 0) { *buf_payload_lengthp = 0; *buf_payloadp = NULL; return (IBMF_SUCCESS); } ASSERT(structs_payload != NULL); /* trace records should never be sent (or packed) by ibmf_saa */ ASSERT(attr_id != SA_TRACERECORD_ATTRID); switch (attr_id) { case SA_CLASSPORTINFO_ATTRID: struct_size = sizeof (ib_mad_classportinfo_t); buf_size = IB_MAD_CLASSPORTINFO_SIZE; pack_data_fn = ibmf_saa_classportinfo_to_buf; break; case SA_NOTICE_ATTRID: struct_size = sizeof (ib_mad_notice_t); buf_size = IB_MAD_NOTICE_SIZE; pack_data_fn = ibmf_saa_notice_to_buf; break; case SA_INFORMINFO_ATTRID: struct_size = sizeof (ib_mad_informinfo_t); buf_size = IB_MAD_INFORMINFO_SIZE; pack_data_fn = ibmf_saa_informinfo_to_buf; break; case SA_NODERECORD_ATTRID: struct_size = sizeof (sa_node_record_t); buf_size = IBMF_SAA_NODE_RECORD_SIZE; pack_data_fn = ibmf_saa_node_record_to_buf; break; case SA_PORTINFORECORD_ATTRID: struct_size = sizeof (sa_portinfo_record_t); buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE; pack_data_fn = ibmf_saa_portinfo_record_to_buf; break; case SA_SLTOVLRECORD_ATTRID: struct_size = sizeof (sa_SLtoVLmapping_record_t); buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE; pack_data_fn = ibmf_saa_SLtoVLmapping_record_to_buf; break; case SA_SWITCHINFORECORD_ATTRID: struct_size = sizeof (sa_switchinfo_record_t); buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE; pack_data_fn = ibmf_saa_switchinfo_record_to_buf; break; case SA_LINEARFDBRECORD_ATTRID: struct_size = sizeof (sa_linearft_record_t); buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE; pack_data_fn = ibmf_saa_linearft_record_to_buf; break; case SA_RANDOMFDBRECORD_ATTRID: struct_size = sizeof (sa_randomft_record_t); buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE; pack_data_fn = ibmf_saa_randomft_record_to_buf; break; case SA_MULTICASTFDBRECORD_ATTRID: struct_size = sizeof (sa_multicastft_record_t); buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE; pack_data_fn = ibmf_saa_multicastft_record_to_buf; break; case SA_SMINFORECORD_ATTRID: struct_size = sizeof (sa_sminfo_record_t); buf_size = IBMF_SAA_SMINFO_RECORD_SIZE; pack_data_fn = ibmf_saa_sminfo_record_to_buf; break; case SA_INFORMINFORECORD_ATTRID: struct_size = sizeof (sa_informinfo_record_t); buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE; pack_data_fn = ibmf_saa_informinfo_record_to_buf; break; case SA_LINKRECORD_ATTRID: struct_size = sizeof (sa_link_record_t); buf_size = IBMF_SAA_LINK_RECORD_SIZE; pack_data_fn = ibmf_saa_link_record_to_buf; break; case SA_GUIDINFORECORD_ATTRID: struct_size = sizeof (sa_guidinfo_record_t); buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE; pack_data_fn = ibmf_saa_guidinfo_record_to_buf; break; case SA_SERVICERECORD_ATTRID: struct_size = sizeof (sa_service_record_t); buf_size = IBMF_SAA_SERVICE_RECORD_SIZE; pack_data_fn = ibmf_saa_service_record_to_buf; break; case SA_PARTITIONRECORD_ATTRID: struct_size = sizeof (sa_pkey_table_record_t); buf_size = IBMF_SAA_PARTITION_RECORD_SIZE; pack_data_fn = ibmf_saa_partition_record_to_buf; break; case SA_PATHRECORD_ATTRID: struct_size = sizeof (sa_path_record_t); buf_size = IBMF_SAA_PATH_RECORD_SIZE; pack_data_fn = ibmf_saa_path_record_to_buf; break; case SA_VLARBRECORD_ATTRID: struct_size = sizeof (sa_VLarb_table_record_t); buf_size = IBMF_SAA_VLARB_RECORD_SIZE; pack_data_fn = ibmf_saa_vlarb_record_to_buf; break; case SA_MCMEMBERRECORD_ATTRID: struct_size = sizeof (sa_mcmember_record_t); buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE; pack_data_fn = ibmf_saa_mcmember_record_to_buf; break; case SA_MULTIPATHRECORD_ATTRID: /* * array is of size 1 since multipath can be request * only; data size greater than multipath_record_t * size is due to gids at the end */ struct_size = structs_payload_length; buf_size = IBMF_SAA_MULTIPATH_RECORD_SIZE + struct_size - sizeof (sa_multipath_record_t); pack_data_fn = ibmf_saa_multipath_record_to_buf; break; case SA_SERVICEASSNRECORD_ATTRID: struct_size = sizeof (sa_service_assn_record_t); buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE; pack_data_fn = ibmf_saa_service_assn_record_to_buf; break; default: /* don't know about structure; do bcopy */ *buf_payload_lengthp = structs_payload_length; *buf_payloadp = kmem_zalloc(*buf_payload_lengthp, km_sleep_flag); if (*buf_payloadp == NULL) { *buf_payload_lengthp = 0; return (IBMF_NO_MEMORY); } bcopy(structs_payload, *buf_payloadp, *buf_payload_lengthp); return (IBMF_SUCCESS); } *buf_payload_lengthp = structs_payload_length / struct_size * buf_size; num_records = structs_payload_length / struct_size; *buf_payloadp = kmem_zalloc(*buf_payload_lengthp, km_sleep_flag); if (*buf_payloadp == NULL) { IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1, ibmf_saa_utils_pack_payload_err, IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_payload: %s," " size = %d\n", tnf_string, msg, "could not allocate memory for payload", tnf_int, size, *buf_payload_lengthp); *buf_payload_lengthp = 0; return (IBMF_NO_MEMORY); } for (i = 0; i < num_records; i++) { pack_data_fn( (void *)((uchar_t *)structs_payload + i * struct_size), ((uchar_t *)*buf_payloadp + i * buf_size)); } return (IBMF_SUCCESS); } /* * ibmf_saa_utils_unpack_payload: * * Unpacks a buffer of data received over the wire and places into an array of * structure in host format. * * for getResp() ibmf always reports payload length as 200 bytes * (MAD_SIZE - headers). To keep the client from having to determine the actual * length of the one attribute (since we do it here) the is_get_resp parameter * indicates that there is one attribute in the buffer. */ int ibmf_saa_utils_unpack_payload(uchar_t *buf_payload, size_t buf_payload_length, uint16_t attr_id, void **structs_payloadp, size_t *structs_payload_lengthp, uint16_t attr_offset, boolean_t is_get_resp, int km_sleep_flag) { int i; int struct_size, buf_size; int num_records; void (*unpack_data_fn)(uchar_t *, void *); int bytes_between_recs; if (buf_payload_length == 0) { *structs_payload_lengthp = 0; *structs_payloadp = NULL; return (IBMF_SUCCESS); } switch (attr_id) { case SA_CLASSPORTINFO_ATTRID: struct_size = sizeof (ib_mad_classportinfo_t); buf_size = IB_MAD_CLASSPORTINFO_SIZE; unpack_data_fn = ibmf_saa_classportinfo_parse_buffer; break; case SA_NOTICE_ATTRID: struct_size = sizeof (ib_mad_notice_t); buf_size = IB_MAD_NOTICE_SIZE; unpack_data_fn = ibmf_saa_notice_parse_buffer; break; case SA_INFORMINFO_ATTRID: struct_size = sizeof (ib_mad_informinfo_t); buf_size = IB_MAD_INFORMINFO_SIZE; unpack_data_fn = ibmf_saa_informinfo_parse_buffer; break; case SA_NODERECORD_ATTRID: struct_size = sizeof (sa_node_record_t); buf_size = IBMF_SAA_NODE_RECORD_SIZE; unpack_data_fn = ibmf_saa_node_record_parse_buffer; break; case SA_PORTINFORECORD_ATTRID: struct_size = sizeof (sa_portinfo_record_t); buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE; unpack_data_fn = ibmf_saa_portinfo_record_parse_buffer; break; case SA_SLTOVLRECORD_ATTRID: struct_size = sizeof (sa_SLtoVLmapping_record_t); buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE; unpack_data_fn = ibmf_saa_SLtoVLmapping_record_parse_buffer; break; case SA_SWITCHINFORECORD_ATTRID: struct_size = sizeof (sa_switchinfo_record_t); buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE; unpack_data_fn = ibmf_saa_switchinfo_record_parse_buffer; break; case SA_LINEARFDBRECORD_ATTRID: struct_size = sizeof (sa_linearft_record_t); buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE; unpack_data_fn = ibmf_saa_linearft_record_parse_buffer; break; case SA_RANDOMFDBRECORD_ATTRID: struct_size = sizeof (sa_randomft_record_t); buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE; unpack_data_fn = ibmf_saa_randomft_record_parse_buffer; break; case SA_MULTICASTFDBRECORD_ATTRID: struct_size = sizeof (sa_multicastft_record_t); buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE; unpack_data_fn = ibmf_saa_multicastft_record_parse_buffer; break; case SA_SMINFORECORD_ATTRID: struct_size = sizeof (sa_sminfo_record_t); buf_size = IBMF_SAA_SMINFO_RECORD_SIZE; unpack_data_fn = ibmf_saa_sminfo_record_parse_buffer; break; case SA_INFORMINFORECORD_ATTRID: struct_size = sizeof (sa_informinfo_record_t); buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE; unpack_data_fn = ibmf_saa_informinfo_record_parse_buffer; break; case SA_LINKRECORD_ATTRID: struct_size = sizeof (sa_link_record_t); buf_size = IBMF_SAA_LINK_RECORD_SIZE; unpack_data_fn = ibmf_saa_link_record_parse_buffer; break; case SA_GUIDINFORECORD_ATTRID: struct_size = sizeof (sa_guidinfo_record_t); buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE; unpack_data_fn = ibmf_saa_guidinfo_record_parse_buffer; break; case SA_SERVICERECORD_ATTRID: struct_size = sizeof (sa_service_record_t); buf_size = IBMF_SAA_SERVICE_RECORD_SIZE; unpack_data_fn = ibmf_saa_service_record_parse_buffer; break; case SA_PARTITIONRECORD_ATTRID: struct_size = sizeof (sa_pkey_table_record_t); buf_size = IBMF_SAA_PARTITION_RECORD_SIZE; unpack_data_fn = ibmf_saa_partition_record_parse_buffer; break; case SA_PATHRECORD_ATTRID: struct_size = sizeof (sa_path_record_t); buf_size = IBMF_SAA_PATH_RECORD_SIZE; unpack_data_fn = ibmf_saa_path_record_parse_buffer; break; case SA_VLARBRECORD_ATTRID: struct_size = sizeof (sa_VLarb_table_record_t); buf_size = IBMF_SAA_VLARB_RECORD_SIZE; unpack_data_fn = ibmf_saa_vlarb_record_parse_buffer; break; case SA_MCMEMBERRECORD_ATTRID: struct_size = sizeof (sa_mcmember_record_t); buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE; unpack_data_fn = ibmf_saa_mcmember_record_parse_buffer; break; case SA_TRACERECORD_ATTRID: struct_size = sizeof (sa_trace_record_t); buf_size = IBMF_SAA_TRACE_RECORD_SIZE; unpack_data_fn = ibmf_saa_trace_record_parse_buffer; break; case SA_MULTIPATHRECORD_ATTRID: /* * array is of size 1 since multipath can be request * only; data size greater than multipath_record_t * size is due to gids at the end */ buf_size = buf_payload_length; struct_size = sizeof (sa_multipath_record_t) + buf_size - IBMF_SAA_MULTIPATH_RECORD_SIZE; unpack_data_fn = ibmf_saa_multipath_record_parse_buffer; break; case SA_SERVICEASSNRECORD_ATTRID: struct_size = sizeof (sa_service_assn_record_t); buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE; unpack_data_fn = ibmf_saa_service_assn_record_parse_buffer; break; default: /* don't know about structure; do bcopy */ *structs_payload_lengthp = buf_payload_length; *structs_payloadp = kmem_zalloc( *structs_payload_lengthp, km_sleep_flag); if (*structs_payloadp == NULL) { *structs_payload_lengthp = 0; return (IBMF_NO_MEMORY); } bcopy(buf_payload, *structs_payloadp, *structs_payload_lengthp); return (IBMF_SUCCESS); } /* compute distance between successive records */ if (attr_offset > 0) { if ((attr_offset * 8) < buf_size) { IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1, ibmf_saa_utils_unpack_payload, IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_payload: %s, attr_offset = " "%d, attr_size = %d\n", tnf_string, msg, "attribute offset times 8 is less" " than attribute size", tnf_int, attr_offset, attr_offset, tnf_int, attr_size, buf_size); return (IBMF_TRANS_FAILURE); } bytes_between_recs = attr_offset * 8; } else { bytes_between_recs = buf_size; } if (is_get_resp == B_TRUE) { buf_payload_length = buf_size; num_records = 1; } else { num_records = buf_payload_length / bytes_between_recs; } *structs_payload_lengthp = num_records * struct_size; *structs_payloadp = kmem_zalloc(*structs_payload_lengthp, km_sleep_flag); if (*structs_payloadp == NULL) { IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1, ibmf_saa_utils_unpack_payload_err, IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_payload: %s," " size = %d\n", tnf_string, msg, "could not allocate memory for payload", tnf_int, size, *structs_payload_lengthp); *structs_payload_lengthp = 0; return (IBMF_NO_MEMORY); } for (i = 0; i < num_records; i++) { unpack_data_fn( (uchar_t *)buf_payload + (i * bytes_between_recs), (void *)((uchar_t *)*structs_payloadp + i * struct_size)); } return (IBMF_SUCCESS); }