#include <sun_sas.h>
HBA_STATUS
Sun_sasFreeLibrary(void)
{
HBA_STATUS status;
lock(&all_hbas_lock);
status = FreeHBA(global_hba_head);
global_hba_head = NULL;
hba_count = 0;
open_handle_index = 1;
unlock(&all_hbas_lock);
(void) mutex_destroy(&all_hbas_lock);
(void) mutex_destroy(&open_handles_lock);
if (gSysEventHandle != NULL)
sysevent_unbind_handle(gSysEventHandle);
loadCount = 0;
return (status);
}
HBA_STATUS
FreeHBA(struct sun_sas_hba *hba)
{
struct sun_sas_hba *hba_ptr = NULL;
struct sun_sas_hba *last_hba_ptr = NULL;
struct sun_sas_port *hba_port = NULL;
struct sun_sas_port *last_hba_port = NULL;
struct sun_sas_port *tgt_port = NULL;
struct sun_sas_port *last_tgt_port = NULL;
struct ScsiEntryList *scsi_info = NULL;
struct ScsiEntryList *last_scsi_info = NULL;
struct phy_info *phy_ptr = NULL;
struct phy_info *last_phy = NULL;
struct open_handle *open_handle = NULL;
struct open_handle *last_open_handle = NULL;
last_hba_ptr = NULL;
for (hba_ptr = hba; hba_ptr != NULL; hba_ptr = hba_ptr->next) {
hba_port = hba_ptr->first_port;
while (hba_port != NULL) {
tgt_port = hba_port->first_attached_port;
while (tgt_port != NULL) {
scsi_info = tgt_port->scsiInfo;
while (scsi_info != NULL) {
last_scsi_info = scsi_info;
scsi_info = scsi_info->next;
free(last_scsi_info);
}
last_tgt_port = tgt_port;
tgt_port = tgt_port->next;
free(last_tgt_port->port_attributes.\
PortSpecificAttribute.SASPort);
free(last_tgt_port);
}
phy_ptr = hba_port->first_phy;
while (phy_ptr != NULL) {
last_phy = phy_ptr;
phy_ptr = phy_ptr->next;
free(last_phy);
}
last_hba_port = hba_port;
hba_port = hba_port->next;
free(last_hba_port->port_attributes.\
PortSpecificAttribute.SASPort);
free(last_hba_port);
}
open_handle = hba_ptr->open_handles;
while (open_handle != NULL) {
last_open_handle = open_handle;
open_handle = open_handle->next;
free(last_open_handle);
}
if (last_hba_ptr != NULL) {
free(last_hba_ptr);
}
last_hba_ptr = hba_ptr;
}
if (last_hba_ptr != NULL) {
free(last_hba_ptr);
}
return (HBA_STATUS_OK);
}