vsw_hio.c revision 6ab6cb20c72ce71fe6022b1c164f36dfe716e425
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A/* Functions imported from other files */ 2N/A/* Functions exported to other files */ 2N/A/* Support functions */ 2N/A * vsw_hio_init -- Initialize the HybridIO related info. 2N/A * - Query SHARES and RINGS capability. Both capabilities 2N/A * need to be supported by the physical-device. 2N/A * Register to get reboot and panic events so that 2N/A * we can cleanup HybridIO resources gracefully. 2N/A /* setup kstats for hybrid resources */ 2N/A * vsw_hio_alloc_share -- Allocate and setup the share for a guest domain. 2N/A * - Allocate a free share. 2N/A * - Bind the Guest's MAC address. 2N/A /* No free shares available */ 2N/A * already assigned to it. 2N/A D2(
vswp,
"Alloc a share failed for ldc=0x%lx rv=%d",
2N/A * Query the RX group number to bind the port's 2N/A * MAC address to it. 2N/A /* Cache some useful info */ 2N/A /* Bind the Guest's MAC address */ 2N/A /* something went wrong, cleanup */ 2N/A * vsw_hio_bind_macaddr -- Remove the port's MAC address from the 2N/A * physdev and bind it to the Share's RX group. 2N/A /* Get the RX groupinfo */ 2N/A /* Unset the MAC address first */ 2N/A /* Bind the MAC address to the RX group */ 2N/A /* Restore the address back as it was */ 2N/A * vsw_hio_unbind_macaddr -- Unbind the port's MAC address and restore 2N/A * it back as it was before. 2N/A /* Unbind the MAC address from the RX group */ 2N/A /* Program the MAC address back */ 2N/A * vsw_hio_find_free_share -- Find a free Share. 2N/A * vsw_hio_find_vshare_ldcid -- Given ldc_id, find the corresponding 2N/A * vsw_hio_find_vshare_port -- Given portp, find the corresponding 2N/A * vsw_hio_free_share -- Unbind the MAC address and free share. 2N/A /* First unbind the MAC address and restore it back */ 2N/A /* DERR only for printing by default */ 2N/A DERR(
vswp,
"Share freed for ldc_id=0x%lx Cookie=0x%lX",
2N/A * vsw_hio_cleanup -- Cleanup the HybridIO. It unregisters the callbs 2N/A * and frees all shares. 2N/A /* Unregister reboot and panic callbs. */ 2N/A * vsw_hio_free_all_shares -- A routine to free all shares gracefully. 2N/A * The following are the steps followed to accomplish this: 2N/A * - First clear 'hio_capable' to avoid further share allocations. 2N/A * - If a share is in accepted(ACKD) state, that means the guest 2N/A * has HybridIO setup etc. If so, send a DEL_SHARE message and 2N/A * give some time(delay) for the guest to ACK. 2N/A * - If the Share is another state, give some time to transition to 2N/A * ACKD state, then try the above. 2N/A * - After max retries, reset the ports to brute force the shares 2N/A * to be freed. Give a little delay for the LDC reset code to 2N/A * Acquire plist->lockrw to make the locking a bit easier 2N/A * and keep the ports in a stable state while we are cleaningup 2N/A * first clear the hio_capable flag so that no more 2N/A * HybridIO operations are initiated. 2N/A * If the share is in DDS_ACKD state, then 2N/A * send DEL_SHARE message so that guest can 2N/A * release its Hybrid resource. 2N/A /* send DDS_DEL_SHARE */ 2N/A * No alternative, reset the port 2N/A * to force the release of Hybrid 2N/A * Last retry, reset the port. 2N/A * If it is reboot case, issue an immediate 2N/A " cause a reset to trigger cleanup for " 2N/A /* Clean up is done */ 2N/A * Release the lock so that reply for DEL_SHARE 2N/A * messages come and get processed, that is, shares 2N/A * This delay is also needed for the port reset to 2N/A * release the Hybrid resource. 2N/A /* By now, all shares should be freed */ 2N/A * vsw_hio_start_ports -- Start HybridIO for ports that have 2N/A * already established connection before HybridIO is intialized. 2N/A /* Cause a rest to trigger HybridIO setup */ 2N/A * vsw_hio_start -- Start HybridIO for a guest(given LDC) 2N/A /* Verify if a share was already allocated */ 2N/A D2(
vswp,
"%s:Share already allocated to ldc=0x%lx",
2N/A D2(
vswp,
"%s: no Share available for ldc=0x%lx",
2N/A * Failed to send a DDS message, so cleanup now. 2N/A /* DERR only to print by default */ 2N/A DERR(
vswp,
"Share allocated for ldc_id=0x%lx Cookie=0x%lX",
2N/A * vsw_hio_stop -- Stop/clean the HybridIO config for a guest(given ldc). 2N/A * vsw_hio_send_delshare_msg -- Send a DEL_SHARE message to the guest. 2N/A * vsw_send_dds_msg -- Send a DDS message. 2N/A * vsw_process_dds_msg -- Process a DDS message received from a guest. 2N/A * We expect to receive DDS messages only from guests that 2N/A * have HybridIO started. 2N/A /* A response for ADD_SHARE message. */ 2N/A " message req_id=0x%X share's req_id=0x%X",
2N/A /* cleanup for NACK */ 2N/A /* A response for DEL_SHARE message */ 2N/A " message share req_id=0x%X share's req_id=0x%X",
2N/A /* There is nothing we can do, free share now */ /* Guest has released Share voluntarily, so free it now */ DERR(
vswp,
"%s: Invalid DDS message type=0x%X",
* vsw_send_dds_resp_msg -- Send a DDS response message. * vsw_hio_port_update -- update Hybrid mode change for a port. /* Verify if the mode really changed */ /* Hybrid Mode is disabled, so stop HybridIO */ /* reset the port to initiate HybridIO setup */ * vsw_hio_stop_port -- Stop HybridIO for a given port. Sequence * followed is similar to vsw_hio_free_all_shares(). D1(
vswp,
"%s:sending DEL_SHARE msg for " * Cause a port reset to trigger " cause a reset to trigger cleanup for " /* Check if the share still assigned to this port */ * Release the lock so that reply for DEL_SHARE * messages come and get processed, that is, shares /* Check if the share still assigned to this port */ * vsw_hio_rest_all -- Resets all ports that have shares allocated. * It is called only in the panic code path, so the LDC channels * Reset the port with immediate flag enabled, * to cause LDC reset immediately. * vsw_hio_reboot_callb -- Called for reboot event. It tries to * free all currently allocated shares. * vsw_hio_panic_callb -- Called from panic event. It resets all * the ports that have shares allocated. This is done to * trigger the cleanup in the guest ahead of HV reset. * Setup kstats for hio statistics. * vsw_hio_stats_t structure is variable size structure * having fields defined only for one share. So, we need * allocate additional space for the rest of the shares. "hio_share_", i,
"_state");
/* not hio capable, just return */