/** * This method will initialize the remote node table for use. * * @param[in out] remote_node_table The remote that which is to be * initialized. * @param[in] remote_node_entries The number of entries to put in the table. * * @return none */ void scic_sds_remote_node_table_initialize( SCIC_REMOTE_NODE_TABLE_T * remote_node_table, U32 remote_node_entries ) { U32 index; // Initialize the raw data we could improve the speed by only initializing // those entries that we are actually going to be used memset( remote_node_table->available_remote_nodes, 0x00, sizeof(remote_node_table->available_remote_nodes) ); memset( remote_node_table->remote_node_groups, 0x00, sizeof(remote_node_table->remote_node_groups) ); // Initialize the available remote node sets remote_node_table->available_nodes_array_size = (U16) (remote_node_entries / SCIC_SDS_REMOTE_NODES_PER_DWORD) + ((remote_node_entries % SCIC_SDS_REMOTE_NODES_PER_DWORD) != 0); // Initialize each full DWORD to a FULL SET of remote nodes for (index = 0; index < remote_node_entries; index++) { scic_sds_remote_node_table_set_node_index(remote_node_table, index); } remote_node_table->group_array_size = (U16) (remote_node_entries / (SCU_STP_REMOTE_NODE_COUNT * 32)) + ((remote_node_entries % (SCU_STP_REMOTE_NODE_COUNT * 32)) != 0); for (index = 0; index < (remote_node_entries / SCU_STP_REMOTE_NODE_COUNT); index++) { // These are all guaranteed to be full slot values so fill them in the // available sets of 3 remote nodes scic_sds_remote_node_table_set_group_index(remote_node_table, 2, index); } // Now fill in any remainders that we may find if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 2) { scic_sds_remote_node_table_set_group_index(remote_node_table, 1, index); } else if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 1) { scic_sds_remote_node_table_set_group_index(remote_node_table, 0, index); } }
/** * This method will free a single remote node index back to the remote node * table. This routine will update the remote node groups * * @param[in] remote_node_table * @param[in] remote_node_index */ static void scic_sds_remote_node_table_release_single_remote_node( SCIC_REMOTE_NODE_TABLE_T * remote_node_table, U16 remote_node_index ) { U32 group_index; U8 group_value; group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT; group_value = scic_sds_remote_node_table_get_group_value(remote_node_table, group_index); // Assert that we are not trying to add an entry to a slot that is already // full. ASSERT(group_value != SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE); if (group_value == 0x00) { // There are no entries in this slot so it must be added to the single // slot table. scic_sds_remote_node_table_set_group_index(remote_node_table, 0, group_index); } else if ((group_value & (group_value -1)) == 0) { // There is only one entry in this slot so it must be moved from the // single slot table to the dual slot table scic_sds_remote_node_table_clear_group_index(remote_node_table, 0, group_index); scic_sds_remote_node_table_set_group_index(remote_node_table, 1, group_index); } else { // There are two entries in the slot so it must be moved from the dual // slot table to the tripple slot table. scic_sds_remote_node_table_clear_group_index(remote_node_table, 1, group_index); scic_sds_remote_node_table_set_group_index(remote_node_table, 2, group_index); } scic_sds_remote_node_table_set_node_index(remote_node_table, remote_node_index); }
/** * * @remote_node_table: * * This method will free a single remote node index back to the remote node * table. This routine will update the remote node groups */ static void scic_sds_remote_node_table_release_single_remote_node( struct scic_remote_node_table *remote_node_table, u16 remote_node_index) { u32 group_index; u8 group_value; group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT; group_value = scic_sds_remote_node_table_get_group_value(remote_node_table, group_index); /* * Assert that we are not trying to add an entry to a slot that is already * full. */ BUG_ON(group_value == SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE); if (group_value == 0x00) { /* * There are no entries in this slot so it must be added to the single * slot table. */ scic_sds_remote_node_table_set_group_index(remote_node_table, 0, group_index); } else if ((group_value & (group_value - 1)) == 0) { /* * There is only one entry in this slot so it must be moved from the * single slot table to the dual slot table */ scic_sds_remote_node_table_clear_group_index(remote_node_table, 0, group_index); scic_sds_remote_node_table_set_group_index(remote_node_table, 1, group_index); } else { /* * There are two entries in the slot so it must be moved from the dual * slot table to the tripple slot table. */ scic_sds_remote_node_table_clear_group_index(remote_node_table, 1, group_index); scic_sds_remote_node_table_set_group_index(remote_node_table, 2, group_index); } scic_sds_remote_node_table_set_node_index(remote_node_table, remote_node_index); }