19e86db7Hyon Kim/*
29e86db7Hyon Kim * CDDL HEADER START
39e86db7Hyon Kim *
49e86db7Hyon Kim * The contents of this file are subject to the terms of the
59e86db7Hyon Kim * Common Development and Distribution License (the "License").
69e86db7Hyon Kim * You may not use this file except in compliance with the License.
79e86db7Hyon Kim *
89e86db7Hyon Kim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e86db7Hyon Kim * or http://www.opensolaris.org/os/licensing.
109e86db7Hyon Kim * See the License for the specific language governing permissions
119e86db7Hyon Kim * and limitations under the License.
129e86db7Hyon Kim *
139e86db7Hyon Kim * When distributing Covered Code, include this CDDL HEADER in each
149e86db7Hyon Kim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e86db7Hyon Kim * If applicable, add the following below this CDDL HEADER, with the
169e86db7Hyon Kim * fields enclosed by brackets "[]" replaced with your own identifying
179e86db7Hyon Kim * information: Portions Copyright [yyyy] [name of copyright owner]
189e86db7Hyon Kim *
199e86db7Hyon Kim * CDDL HEADER END
209e86db7Hyon Kim */
219e86db7Hyon Kim
229e86db7Hyon Kim/*
239e86db7Hyon Kim * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
249e86db7Hyon Kim * Use is subject to license terms.
259e86db7Hyon Kim */
269e86db7Hyon Kim
279e86db7Hyon Kim#include    <sun_sas.h>
289e86db7Hyon Kim
299e86db7Hyon Kim/*
309e86db7Hyon Kim * Closes an adapter
319e86db7Hyon Kim *
329e86db7Hyon Kim * the handle is removed from the open_handles list
339e86db7Hyon Kim */
349e86db7Hyon Kimvoid
359e86db7Hyon KimSun_sasCloseAdapter(HBA_HANDLE handle)
369e86db7Hyon Kim{
379e86db7Hyon Kim	const char			ROUTINE[] = "Sun_sasCloseAdapter";
389e86db7Hyon Kim	struct open_handle		*open_handle_ptr, *open_handle_prev_ptr;
399e86db7Hyon Kim	int				found = 0;
409e86db7Hyon Kim
419e86db7Hyon Kim	if (global_hba_head == NULL) {
429e86db7Hyon Kim		log(LOG_DEBUG, ROUTINE,
439e86db7Hyon Kim		    "Attempted to close an invalid handle %08lx. "
449e86db7Hyon Kim		    "There are no hba handles loaded in the VSL.",
459e86db7Hyon Kim		    handle);
469e86db7Hyon Kim		return;
479e86db7Hyon Kim	}
489e86db7Hyon Kim
499e86db7Hyon Kim	/* Removing handle from open_handles; */
509e86db7Hyon Kim	lock(&open_handles_lock);
519e86db7Hyon Kim	if (global_hba_head->open_handles == NULL) {
529e86db7Hyon Kim		/* check to see if there are any open global_hba_head */
539e86db7Hyon Kim		log(LOG_DEBUG, ROUTINE,
549e86db7Hyon Kim		    "Attempted to close an invalid handle %08lx. "
559e86db7Hyon Kim		    "There are no open handles in the VSL.",
569e86db7Hyon Kim		    handle);
579e86db7Hyon Kim	} else if (global_hba_head->open_handles->next == NULL) {
589e86db7Hyon Kim		/* there is only one handle open */
599e86db7Hyon Kim		if (global_hba_head->open_handles->handle == handle) {
609e86db7Hyon Kim			free(global_hba_head->open_handles);
619e86db7Hyon Kim			global_hba_head->open_handles = NULL;
629e86db7Hyon Kim		} else {
639e86db7Hyon Kim			log(LOG_DEBUG, ROUTINE,
649e86db7Hyon Kim			    "Attempted to close an invalid handle %08lx. "
659e86db7Hyon Kim			    "Unable to find handle to close.", handle);
669e86db7Hyon Kim		}
679e86db7Hyon Kim	} else {	/* there is more than one handle open */
689e86db7Hyon Kim		open_handle_ptr = global_hba_head->open_handles;
699e86db7Hyon Kim		if (open_handle_ptr->handle == handle) {
709e86db7Hyon Kim			global_hba_head->open_handles = open_handle_ptr->next;
719e86db7Hyon Kim			free(open_handle_ptr);
729e86db7Hyon Kim		} else {
739e86db7Hyon Kim			for (open_handle_ptr = open_handle_ptr->next,
749e86db7Hyon Kim			    open_handle_prev_ptr =
759e86db7Hyon Kim			    global_hba_head->open_handles;
769e86db7Hyon Kim			    open_handle_ptr != NULL;
779e86db7Hyon Kim			    open_handle_ptr = open_handle_ptr->next) {
789e86db7Hyon Kim				if (open_handle_ptr->handle == handle) {
799e86db7Hyon Kim					open_handle_prev_ptr->next =
809e86db7Hyon Kim					    open_handle_ptr->next;
819e86db7Hyon Kim					free(open_handle_ptr);
829e86db7Hyon Kim					found = 1;
839e86db7Hyon Kim					break;
849e86db7Hyon Kim				} else {
859e86db7Hyon Kim					open_handle_prev_ptr =
869e86db7Hyon Kim					    open_handle_prev_ptr->next;
879e86db7Hyon Kim				}
889e86db7Hyon Kim			}
899e86db7Hyon Kim			if (found == 0) {
909e86db7Hyon Kim				log(LOG_DEBUG, ROUTINE,
919e86db7Hyon Kim				    "Attempted to close an invalid handle "
929e86db7Hyon Kim				    "%08lx.  Unable to find handle to close.",
939e86db7Hyon Kim				    handle);
949e86db7Hyon Kim			}
959e86db7Hyon Kim		}
969e86db7Hyon Kim	}
979e86db7Hyon Kim
989e86db7Hyon Kim	unlock(&open_handles_lock);
999e86db7Hyon Kim}