Print this page
4682 panic in mptsas refhash
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Approved by: Albert Lee <trisk@nexenta.com>
4500 mptsas_hash_traverse() is unsafe, leads to missing devices
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Approved by: Albert Lee <trisk@nexenta.com>
*** 20,30 ****
*/
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
! * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
*/
/*
* Copyright (c) 2000 to 2010, LSI Corporation.
--- 20,30 ----
*/
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
! * Copyright (c) 2014, Joyent, Inc. All rights reserved.
* Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
*/
/*
* Copyright (c) 2000 to 2010, LSI Corporation.
*** 95,104 ****
--- 95,105 ----
*/
#include <sys/scsi/impl/scsi_reset_notify.h>
#include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
#include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
#include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
+ #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
#include <sys/raidioctl.h>
#include <sys/fs/dv_node.h> /* devfs_clean */
/*
*** 334,349 ****
static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
int *lun);
static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
! static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask,
! uint8_t phy);
! static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
! uint64_t wwid);
! static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
! uint64_t wwid);
static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
--- 335,350 ----
static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
int *lun);
static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
! static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt,
! mptsas_phymask_t phymask, uint8_t phy);
! static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt,
! mptsas_phymask_t phymask, uint64_t wwid);
! static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
! mptsas_phymask_t phymask, uint64_t wwid);
static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
*** 405,431 ****
int mode, int *rval);
static void mptsas_record_event(void *args);
static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
int mode);
! static void mptsas_hash_init(mptsas_hash_table_t *hashtab);
! static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen);
! static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data);
! static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
! mptsas_phymask_t key2);
! static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
! mptsas_phymask_t key2);
! static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos);
!
! mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t,
uint32_t, mptsas_phymask_t, uint8_t);
! static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab,
! mptsas_smp_t *data);
! static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
! mptsas_phymask_t phymask);
! static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t);
! static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t);
static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
dev_info_t **smp_dip);
/*
* Power management functions
--- 406,418 ----
int mode, int *rval);
static void mptsas_record_event(void *args);
static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
int mode);
! mptsas_target_t *mptsas_tgt_alloc(mptsas_t *, uint16_t, uint64_t,
uint32_t, mptsas_phymask_t, uint8_t);
! static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
dev_info_t **smp_dip);
/*
* Power management functions
*** 693,704 ****
--- 680,786 ----
NDBG0(("mptsas _info"));
return (mod_info(&modlinkage, modinfop));
}
+ static int
+ mptsas_target_eval_devhdl(const void *op, void *arg)
+ {
+ uint16_t dh = *(uint16_t *)arg;
+ const mptsas_target_t *tp = op;
+ return ((int)tp->m_devhdl - (int)dh);
+ }
+
static int
+ mptsas_target_eval_slot(const void *op, void *arg)
+ {
+ mptsas_led_control_t *lcp = arg;
+ const mptsas_target_t *tp = op;
+
+ if (tp->m_enclosure != lcp->Enclosure)
+ return ((int)tp->m_enclosure - (int)lcp->Enclosure);
+
+ return ((int)tp->m_slot_num - (int)lcp->Slot);
+ }
+
+ static int
+ mptsas_target_eval_nowwn(const void *op, void *arg)
+ {
+ uint8_t phy = *(uint8_t *)arg;
+ const mptsas_target_t *tp = op;
+
+ if (tp->m_addr.mta_wwn != 0)
+ return (-1);
+
+ return ((int)tp->m_phynum - (int)phy);
+ }
+
+ static int
+ mptsas_smp_eval_devhdl(const void *op, void *arg)
+ {
+ uint16_t dh = *(uint16_t *)arg;
+ const mptsas_smp_t *sp = op;
+
+ return ((int)sp->m_devhdl - (int)dh);
+ }
+
+ static uint64_t
+ mptsas_target_addr_hash(const void *tp)
+ {
+ const mptsas_target_addr_t *tap = tp;
+
+ return ((tap->mta_wwn & 0xffffffffffffULL) |
+ ((uint64_t)tap->mta_phymask << 48));
+ }
+
+ static int
+ mptsas_target_addr_cmp(const void *a, const void *b)
+ {
+ const mptsas_target_addr_t *aap = a;
+ const mptsas_target_addr_t *bap = b;
+
+ if (aap->mta_wwn < bap->mta_wwn)
+ return (-1);
+ if (aap->mta_wwn > bap->mta_wwn)
+ return (1);
+ return ((int)bap->mta_phymask - (int)aap->mta_phymask);
+ }
+
+ static void
+ mptsas_target_free(void *op)
+ {
+ kmem_free(op, sizeof (mptsas_target_t));
+ }
+
+ static void
+ mptsas_smp_free(void *op)
+ {
+ kmem_free(op, sizeof (mptsas_smp_t));
+ }
+
+ static void
+ mptsas_destroy_hashes(mptsas_t *mpt)
+ {
+ mptsas_target_t *tp;
+ mptsas_smp_t *sp;
+
+ for (tp = refhash_first(mpt->m_targets); tp != NULL;
+ tp = refhash_next(mpt->m_targets, tp)) {
+ refhash_remove(mpt->m_targets, tp);
+ }
+ for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
+ sp = refhash_next(mpt->m_smp_targets, sp)) {
+ refhash_remove(mpt->m_smp_targets, sp);
+ }
+ refhash_destroy(mpt->m_targets);
+ refhash_destroy(mpt->m_smp_targets);
+ mpt->m_targets = NULL;
+ mpt->m_smp_targets = NULL;
+ }
+
+ static int
mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
dev_info_t *pdip;
mptsas_t *mpt;
scsi_hba_tran_t *hba_tran;
*** 1402,1416 ****
}
if (hba_attach_setup) {
mptsas_hba_teardown(mpt);
}
if (mpt->m_active) {
- mptsas_hash_uninit(&mpt->m_active->m_smptbl,
- sizeof (mptsas_smp_t));
- mptsas_hash_uninit(&mpt->m_active->m_tgttbl,
- sizeof (mptsas_target_t));
mptsas_free_active_slots(mpt);
}
if (intr_added) {
mptsas_unregister_intrs(mpt);
}
--- 1484,1499 ----
}
if (hba_attach_setup) {
mptsas_hba_teardown(mpt);
}
+ if (mpt->m_targets)
+ refhash_destroy(mpt->m_targets);
+ if (mpt->m_smp_targets)
+ refhash_destroy(mpt->m_smp_targets);
+
if (mpt->m_active) {
mptsas_free_active_slots(mpt);
}
if (intr_added) {
mptsas_unregister_intrs(mpt);
}
*** 1839,1854 ****
/*
* Delete Phy stats
*/
mptsas_destroy_phy_stats(mpt);
/*
* Delete nt_active.
*/
mutex_enter(&mpt->m_mutex);
- mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t));
- mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t));
mptsas_free_active_slots(mpt);
mutex_exit(&mpt->m_mutex);
/* deallocate everything that was allocated in mptsas_attach */
mptsas_cache_destroy(mpt);
--- 1922,1937 ----
/*
* Delete Phy stats
*/
mptsas_destroy_phy_stats(mpt);
+ mptsas_destroy_hashes(mpt);
+
/*
* Delete nt_active.
*/
mutex_enter(&mpt->m_mutex);
mptsas_free_active_slots(mpt);
mutex_exit(&mpt->m_mutex);
/* deallocate everything that was allocated in mptsas_attach */
mptsas_cache_destroy(mpt);
*** 2105,2115 ****
return (FALSE);
}
/*
* Initialize smp hash table
*/
! mptsas_hash_init(&mpt->m_active->m_smptbl);
mpt->m_smp_devhdl = 0xFFFF;
return (TRUE);
}
--- 2188,2202 ----
return (FALSE);
}
/*
* Initialize smp hash table
*/
! mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT,
! mptsas_target_addr_hash, mptsas_target_addr_cmp,
! mptsas_smp_free, sizeof (mptsas_smp_t),
! offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr),
! KM_SLEEP);
mpt->m_smp_devhdl = 0xFFFF;
return (TRUE);
}
*** 2748,2759 ****
int lun = sd->sd_address.a_lun;
mdi_pathinfo_t *pip = NULL;
mptsas_tgt_private_t *tgt_private = NULL;
mptsas_target_t *ptgt = NULL;
char *psas_wwn = NULL;
! int phymask = 0;
uint64_t sas_wwn = 0;
mpt = SDEV2MPT(sd);
ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
--- 2835,2847 ----
int lun = sd->sd_address.a_lun;
mdi_pathinfo_t *pip = NULL;
mptsas_tgt_private_t *tgt_private = NULL;
mptsas_target_t *ptgt = NULL;
char *psas_wwn = NULL;
! mptsas_phymask_t phymask = 0;
uint64_t sas_wwn = 0;
+ mptsas_target_addr_t addr;
mpt = SDEV2MPT(sd);
ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
*** 2765,2775 ****
return (DDI_FAILURE);
}
/*
* phymask is 0 means the virtual port for RAID
*/
! phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
"phymask", 0);
if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
if ((pip = (void *)(sd->sd_private)) == NULL) {
/*
* Very bad news if this occurs. Somehow scsi_vhci has
--- 2853,2863 ----
return (DDI_FAILURE);
}
/*
* phymask is 0 means the virtual port for RAID
*/
! phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
"phymask", 0);
if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
if ((pip = (void *)(sd->sd_private)) == NULL) {
/*
* Very bad news if this occurs. Somehow scsi_vhci has
*** 2803,2815 ****
ddi_prop_free(psas_wwn);
} else {
sas_wwn = 0;
}
}
ASSERT((sas_wwn != 0) || (phymask != 0));
mutex_enter(&mpt->m_mutex);
! ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask);
mutex_exit(&mpt->m_mutex);
if (ptgt == NULL) {
mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
"gone already! phymask:%x, saswwn %"PRIx64, phymask,
sas_wwn);
--- 2891,2906 ----
ddi_prop_free(psas_wwn);
} else {
sas_wwn = 0;
}
}
+
ASSERT((sas_wwn != 0) || (phymask != 0));
+ addr.mta_wwn = sas_wwn;
+ addr.mta_phymask = phymask;
mutex_enter(&mpt->m_mutex);
! ptgt = refhash_lookup(mpt->m_targets, &addr);
mutex_exit(&mpt->m_mutex);
if (ptgt == NULL) {
mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
"gone already! phymask:%x, saswwn %"PRIx64, phymask,
sas_wwn);
*** 3236,3276 ****
}
int
mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
{
! mptsas_slots_t *slots;
! int slot;
mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
! ASSERT(mutex_owned(&mpt->m_mutex));
! slots = mpt->m_active;
/*
* Account for reserved TM request slot and reserved SMID of 0.
*/
! ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2));
/*
! * m_tags is equivalent to the SMID when sending requests. Since the
! * SMID cannot be 0, start out at one if rolling over past the size
! * of the request queue depth. Also, don't use the last SMID, which is
! * reserved for TM requests.
*/
! slot = (slots->m_tags)++;
! if (slots->m_tags > slots->m_n_slots) {
! slots->m_tags = 1;
! }
! alloc_tag:
! /* Validate tag, should never fail. */
! if (slots->m_slot[slot] == NULL) {
! /*
! * Make sure SMID is not using reserved value of 0
! * and the TM request slot.
! */
! ASSERT((slot > 0) && (slot <= slots->m_n_slots));
cmd->cmd_slot = slot;
slots->m_slot[slot] = cmd;
mpt->m_ncmds++;
/*
--- 3327,3370 ----
}
int
mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
{
! mptsas_slots_t *slots = mpt->m_active;
! uint_t slot, start_rotor;
mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
! ASSERT(MUTEX_HELD(&mpt->m_mutex));
/*
* Account for reserved TM request slot and reserved SMID of 0.
*/
! ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2));
/*
! * Find the next available slot, beginning at m_rotor. If no slot is
! * available, we'll return FALSE to indicate that. This mechanism
! * considers only the normal slots, not the reserved slot 0 nor the
! * task management slot m_n_normal + 1. The rotor is left to point to
! * the normal slot after the one we select, unless we select the last
! * normal slot in which case it returns to slot 1.
*/
! start_rotor = slots->m_rotor;
! do {
! slot = slots->m_rotor++;
! if (slots->m_rotor > slots->m_n_normal)
! slots->m_rotor = 1;
! if (slots->m_rotor == start_rotor)
! break;
! } while (slots->m_slot[slot] != NULL);
!
! if (slots->m_slot[slot] != NULL)
! return (FALSE);
!
! ASSERT(slot != 0 && slot <= slots->m_n_normal);
!
cmd->cmd_slot = slot;
slots->m_slot[slot] = cmd;
mpt->m_ncmds++;
/*
*** 3290,3318 ****
*/
if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
}
return (TRUE);
- } else {
- int i;
-
- /*
- * If slot in use, scan until a free one is found. Don't use 0
- * or final slot, which is reserved for TM requests.
- */
- for (i = 0; i < slots->m_n_slots; i++) {
- slot = slots->m_tags;
- if (++(slots->m_tags) > slots->m_n_slots) {
- slots->m_tags = 1;
- }
- if (slots->m_slot[slot] == NULL) {
- NDBG22(("found free slot %d", slot));
- goto alloc_tag;
- }
- }
- }
- return (FALSE);
}
/*
* prepare the pkt:
* the pkt may have been resubmitted or just reused so
--- 3384,3393 ----
*** 4649,4659 ****
/*
* This is a success reply so just complete the IO. First, do a sanity
* check on the SMID. The final slot is used for TM requests, which
* would not come into this reply handler.
*/
! if ((SMID == 0) || (SMID > slots->m_n_slots)) {
mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
SMID);
ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
return;
}
--- 4724,4734 ----
/*
* This is a success reply so just complete the IO. First, do a sanity
* check on the SMID. The final slot is used for TM requests, which
* would not come into this reply handler.
*/
! if ((SMID == 0) || (SMID > slots->m_n_normal)) {
mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
SMID);
ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
return;
}
*** 4752,4762 ****
(function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
/*
* This could be a TM reply, which use the last allocated SMID,
* so allow for that.
*/
! if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) {
mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
"%d\n", SMID);
ddi_fm_service_impact(mpt->m_dip,
DDI_SERVICE_UNAFFECTED);
return;
--- 4827,4837 ----
(function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
/*
* This could be a TM reply, which use the last allocated SMID,
* so allow for that.
*/
! if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
"%d\n", SMID);
ddi_fm_service_impact(mpt->m_dip,
DDI_SERVICE_UNAFFECTED);
return;
*** 5069,5079 ****
"reconfigure.\n");
break;
}
topo_node->mpt = mpt;
topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
! topo_node->un.phymask = ptgt->m_phymask;
topo_node->devhdl = ptgt->m_devhdl;
topo_node->object = (void *)ptgt;
topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
--- 5144,5154 ----
"reconfigure.\n");
break;
}
topo_node->mpt = mpt;
topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
! topo_node->un.phymask = ptgt->m_addr.mta_phymask;
topo_node->devhdl = ptgt->m_devhdl;
topo_node->object = (void *)ptgt;
topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
*** 5135,5151 ****
case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
case MPI2_IOCSTATUS_BUSY:
/*
* set throttles to drain
*/
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(
! &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
/*
* retry command
*/
--- 5210,5222 ----
case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
case MPI2_IOCSTATUS_BUSY:
/*
* set throttles to drain
*/
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
}
/*
* retry command
*/
*** 5832,5843 ****
if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
/*
* Get latest RAID info.
*/
(void) mptsas_get_raid_info(mpt);
! ptgt = mptsas_search_by_devhdl(
! &mpt->m_active->m_tgttbl, topo_node->devhdl);
if (ptgt == NULL)
break;
} else {
ptgt = (void *)topo_node->object;
}
--- 5903,5914 ----
if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
/*
* Get latest RAID info.
*/
(void) mptsas_get_raid_info(mpt);
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_devhdl, &topo_node->devhdl);
if (ptgt == NULL)
break;
} else {
ptgt = (void *)topo_node->object;
}
*** 5882,5892 ****
mutex_exit(&mpt->m_mutex);
flags = topo_node->flags;
if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
! phymask = ptgt->m_phymask;
phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
(void) sprintf(phy_mask_name, "%x", phymask);
parent = scsi_hba_iport_find(mpt->m_dip,
phy_mask_name);
kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
--- 5953,5963 ----
mutex_exit(&mpt->m_mutex);
flags = topo_node->flags;
if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
! phymask = ptgt->m_addr.mta_phymask;
phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
(void) sprintf(phy_mask_name, "%x", phymask);
parent = scsi_hba_iport_find(mpt->m_dip,
phy_mask_name);
kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
*** 5921,5931 ****
*/
if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
bzero(attached_wwnstr,
sizeof (attached_wwnstr));
(void) sprintf(attached_wwnstr, "w%016"PRIx64,
! ptgt->m_sas_wwn);
if (ddi_prop_update_string(DDI_DEV_T_NONE,
parent,
SCSI_ADDR_PROP_ATTACHED_PORT,
attached_wwnstr)
!= DDI_PROP_SUCCESS) {
--- 5992,6002 ----
*/
if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
bzero(attached_wwnstr,
sizeof (attached_wwnstr));
(void) sprintf(attached_wwnstr, "w%016"PRIx64,
! ptgt->m_addr.mta_wwn);
if (ddi_prop_update_string(DDI_DEV_T_NONE,
parent,
SCSI_ADDR_PROP_ATTACHED_PORT,
attached_wwnstr)
!= DDI_PROP_SUCCESS) {
*** 5979,6000 ****
}
mutex_enter(&mpt->m_mutex);
NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
"phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
! ptgt->m_phymask));
break;
}
case MPTSAS_DR_EVENT_OFFLINE_TARGET:
{
- mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl;
devhdl = topo_node->devhdl;
! ptgt = mptsas_search_by_devhdl(tgttbl, devhdl);
if (ptgt == NULL)
break;
! sas_wwn = ptgt->m_sas_wwn;
phy = ptgt->m_phynum;
addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
if (sas_wwn) {
--- 6050,6071 ----
}
mutex_enter(&mpt->m_mutex);
NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
"phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
! ptgt->m_addr.mta_phymask));
break;
}
case MPTSAS_DR_EVENT_OFFLINE_TARGET:
{
devhdl = topo_node->devhdl;
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_devhdl, &devhdl);
if (ptgt == NULL)
break;
! sas_wwn = ptgt->m_addr.mta_wwn;
phy = ptgt->m_phynum;
addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
if (sas_wwn) {
*** 6018,6029 ****
*/
rval = mptsas_do_scsi_reset(mpt, devhdl);
if (rval) {
NDBG20(("mptsas%d handle_topo_change to reset target "
"before offline devhdl:%x, phymask:%x, rval:%x",
! mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask,
! rval));
}
mutex_exit(&mpt->m_mutex);
ndi_devi_enter(scsi_vhci_dip, &circ);
--- 6089,6100 ----
*/
rval = mptsas_do_scsi_reset(mpt, devhdl);
if (rval) {
NDBG20(("mptsas%d handle_topo_change to reset target "
"before offline devhdl:%x, phymask:%x, rval:%x",
! mpt->m_instance, ptgt->m_devhdl,
! ptgt->m_addr.mta_phymask, rval));
}
mutex_exit(&mpt->m_mutex);
ndi_devi_enter(scsi_vhci_dip, &circ);
*** 6031,6041 ****
rval = mptsas_offline_target(parent, addr);
ndi_devi_exit(parent, circ1);
ndi_devi_exit(scsi_vhci_dip, circ);
NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
"phymask:%x, rval:%x", mpt->m_instance,
! ptgt->m_devhdl, ptgt->m_phymask, rval));
kmem_free(addr, SCSI_MAXNAMELEN);
/*
* Clear parent's props for SMHBA support
--- 6102,6112 ----
rval = mptsas_offline_target(parent, addr);
ndi_devi_exit(parent, circ1);
ndi_devi_exit(scsi_vhci_dip, circ);
NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
"phymask:%x, rval:%x", mpt->m_instance,
! ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval));
kmem_free(addr, SCSI_MAXNAMELEN);
/*
* Clear parent's props for SMHBA support
*** 6074,6085 ****
mutex_enter(&mpt->m_mutex);
ptgt->m_led_status = 0;
(void) mptsas_flush_led_status(mpt, ptgt);
if (rval == DDI_SUCCESS) {
! mptsas_tgt_free(&mpt->m_active->m_tgttbl,
! ptgt->m_sas_wwn, ptgt->m_phymask);
ptgt = NULL;
} else {
/*
* clean DR_INTRANSITION flag to allow I/O down to
* PHCI driver since failover finished.
--- 6145,6155 ----
mutex_enter(&mpt->m_mutex);
ptgt->m_led_status = 0;
(void) mptsas_flush_led_status(mpt, ptgt);
if (rval == DDI_SUCCESS) {
! refhash_remove(mpt->m_targets, ptgt);
ptgt = NULL;
} else {
/*
* clean DR_INTRANSITION flag to allow I/O down to
* PHCI driver since failover finished.
*** 6132,6142 ****
}
case MPTSAS_DR_EVENT_RECONFIG_SMP:
{
mptsas_smp_t smp;
dev_info_t *smpdip;
- mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
devhdl = topo_node->devhdl;
page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
--- 6202,6211 ----
*** 6145,6155 ****
mptsas_log(mpt, CE_WARN, "failed to online smp, "
"handle %x", devhdl);
return;
}
! psmp = mptsas_smp_alloc(smptbl, &smp);
if (psmp == NULL) {
return;
}
mutex_exit(&mpt->m_mutex);
--- 6214,6224 ----
mptsas_log(mpt, CE_WARN, "failed to online smp, "
"handle %x", devhdl);
return;
}
! psmp = mptsas_smp_alloc(mpt, &smp);
if (psmp == NULL) {
return;
}
mutex_exit(&mpt->m_mutex);
*** 6160,6174 ****
mutex_enter(&mpt->m_mutex);
break;
}
case MPTSAS_DR_EVENT_OFFLINE_SMP:
{
- mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
devhdl = topo_node->devhdl;
uint32_t dev_info;
! psmp = mptsas_search_by_devhdl(smptbl, devhdl);
if (psmp == NULL)
break;
/*
* The mptsas_smp_t data is released only if the dip is offlined
* successfully.
--- 6229,6243 ----
mutex_enter(&mpt->m_mutex);
break;
}
case MPTSAS_DR_EVENT_OFFLINE_SMP:
{
devhdl = topo_node->devhdl;
uint32_t dev_info;
! psmp = refhash_linear_search(mpt->m_smp_targets,
! mptsas_smp_eval_devhdl, &devhdl);
if (psmp == NULL)
break;
/*
* The mptsas_smp_t data is released only if the dip is offlined
* successfully.
*** 6220,6231 ****
mutex_enter(&mpt->m_mutex);
NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
"rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
if (rval == DDI_SUCCESS) {
! mptsas_smp_free(smptbl, psmp->m_sasaddr,
! psmp->m_phymask);
} else {
psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
}
bzero(attached_wwnstr, sizeof (attached_wwnstr));
--- 6289,6299 ----
mutex_enter(&mpt->m_mutex);
NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
"rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
if (rval == DDI_SUCCESS) {
! refhash_remove(mpt->m_smp_targets, psmp);
} else {
psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
}
bzero(attached_wwnstr, sizeof (attached_wwnstr));
*** 6380,6398 ****
mptsas_topo_change_list_t *topo_head = NULL;
mptsas_topo_change_list_t *topo_tail = NULL;
mptsas_topo_change_list_t *topo_node = NULL;
mptsas_target_t *ptgt;
mptsas_smp_t *psmp;
- mptsas_hash_table_t *tgttbl, *smptbl;
uint8_t flags = 0, exp_flag;
smhba_info_t *pSmhba = NULL;
NDBG20(("mptsas_handle_event_sync: SAS topology change"));
- tgttbl = &mpt->m_active->m_tgttbl;
- smptbl = &mpt->m_active->m_smptbl;
-
sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
eventreply->EventData;
enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
&sas_topo_change_list->EnclosureHandle);
--- 6448,6462 ----
*** 6434,6453 ****
}
break;
case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
(void) sprintf(string, " not responding, "
"removed");
! psmp = mptsas_search_by_devhdl(smptbl,
! expd_handle);
if (psmp == NULL)
break;
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask = psmp->m_phymask;
topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
topo_node->devhdl = expd_handle;
topo_node->flags = flags;
topo_node->object = NULL;
if (topo_head == NULL) {
--- 6498,6518 ----
}
break;
case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
(void) sprintf(string, " not responding, "
"removed");
! psmp = refhash_linear_search(mpt->m_smp_targets,
! mptsas_smp_eval_devhdl, &expd_handle);
if (psmp == NULL)
break;
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask =
! psmp->m_addr.mta_phymask;
topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
topo_node->devhdl = expd_handle;
topo_node->flags = flags;
topo_node->object = NULL;
if (topo_head == NULL) {
*** 6594,6605 ****
/*
* Target device is removed from the system
* Before the device is really offline from
* from system.
*/
! ptgt = mptsas_search_by_devhdl(tgttbl,
! dev_handle);
/*
* If ptgt is NULL here, it means that the
* DevHandle is not in the hash table. This is
* reasonable sometimes. For example, if a
* disk was pulled, then added, then pulled
--- 6659,6670 ----
/*
* Target device is removed from the system
* Before the device is really offline from
* from system.
*/
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_devhdl, &dev_handle);
/*
* If ptgt is NULL here, it means that the
* DevHandle is not in the hash table. This is
* reasonable sometimes. For example, if a
* disk was pulled, then added, then pulled
*** 6647,6657 ****
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask = ptgt->m_phymask;
topo_node->event =
MPTSAS_DR_EVENT_OFFLINE_TARGET;
topo_node->devhdl = dev_handle;
topo_node->flags = flags;
topo_node->object = NULL;
--- 6712,6723 ----
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask =
! ptgt->m_addr.mta_phymask;
topo_node->event =
MPTSAS_DR_EVENT_OFFLINE_TARGET;
topo_node->devhdl = dev_handle;
topo_node->flags = flags;
topo_node->object = NULL;
*** 6807,6827 ****
Mpi2EventDataIrConfigChangeList_t *irChangeList;
mptsas_topo_change_list_t *topo_head = NULL;
mptsas_topo_change_list_t *topo_tail = NULL;
mptsas_topo_change_list_t *topo_node = NULL;
mptsas_target_t *ptgt;
- mptsas_hash_table_t *tgttbl;
uint8_t num_entries, i, reason;
uint16_t volhandle, diskhandle;
irChangeList = (pMpi2EventDataIrConfigChangeList_t)
eventreply->EventData;
num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
&irChangeList->NumElements);
- tgttbl = &mpt->m_active->m_tgttbl;
-
NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
mpt->m_instance));
for (i = 0; i < num_entries; i++) {
reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
--- 6873,6890 ----
*** 6861,6872 ****
case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
{
NDBG20(("mptsas %d volume deleted\n",
mpt->m_instance));
! ptgt = mptsas_search_by_devhdl(tgttbl,
! volhandle);
if (ptgt == NULL)
break;
/*
* Clear any flags related to volume
--- 6924,6935 ----
case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
{
NDBG20(("mptsas %d volume deleted\n",
mpt->m_instance));
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_devhdl, &volhandle);
if (ptgt == NULL)
break;
/*
* Clear any flags related to volume
*** 6882,6892 ****
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask = ptgt->m_phymask;
topo_node->event =
MPTSAS_DR_EVENT_OFFLINE_TARGET;
topo_node->devhdl = volhandle;
topo_node->flags =
MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
--- 6945,6956 ----
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask =
! ptgt->m_addr.mta_phymask;
topo_node->event =
MPTSAS_DR_EVENT_OFFLINE_TARGET;
topo_node->devhdl = volhandle;
topo_node->flags =
MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
*** 6900,6911 ****
break;
}
case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
case MPI2_EVENT_IR_CHANGE_RC_HIDE:
{
! ptgt = mptsas_search_by_devhdl(tgttbl,
! diskhandle);
if (ptgt == NULL)
break;
/*
* Update DR flag immediately avoid I/O failure
--- 6964,6975 ----
break;
}
case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
case MPI2_EVENT_IR_CHANGE_RC_HIDE:
{
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_devhdl, &diskhandle);
if (ptgt == NULL)
break;
/*
* Update DR flag immediately avoid I/O failure
*** 6916,6926 ****
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask = ptgt->m_phymask;
topo_node->event =
MPTSAS_DR_EVENT_OFFLINE_TARGET;
topo_node->devhdl = diskhandle;
topo_node->flags =
MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
--- 6980,6991 ----
topo_node = kmem_zalloc(
sizeof (mptsas_topo_change_list_t),
KM_SLEEP);
topo_node->mpt = mpt;
! topo_node->un.phymask =
! ptgt->m_addr.mta_phymask;
topo_node->event =
MPTSAS_DR_EVENT_OFFLINE_TARGET;
topo_node->devhdl = diskhandle;
topo_node->flags =
MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
*** 7341,7351 ****
{
Mpi2EventDataIrVolume_t *irVolume;
uint16_t devhandle;
uint32_t state;
int config, vol;
- mptsas_slots_t *slots = mpt->m_active;
uint8_t found = FALSE;
irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
state = ddi_get32(mpt->m_acc_reply_frame_hdl,
&irVolume->NewValue);
--- 7406,7415 ----
*** 7358,7371 ****
* Get latest RAID info and then find the DevHandle for this
* event in the configuration. If the DevHandle is not found
* just exit the event.
*/
(void) mptsas_get_raid_info(mpt);
! for (config = 0; (config < slots->m_num_raid_configs) &&
(!found); config++) {
for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
! if (slots->m_raidconfig[config].m_raidvol[vol].
m_raidhandle == devhandle) {
found = TRUE;
break;
}
}
--- 7422,7435 ----
* Get latest RAID info and then find the DevHandle for this
* event in the configuration. If the DevHandle is not found
* just exit the event.
*/
(void) mptsas_get_raid_info(mpt);
! for (config = 0; (config < mpt->m_num_raid_configs) &&
(!found); config++) {
for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
! if (mpt->m_raidconfig[config].m_raidvol[vol].
m_raidhandle == devhandle) {
found = TRUE;
break;
}
}
*** 7376,7386 ****
switch (irVolume->ReasonCode) {
case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
{
uint32_t i;
! slots->m_raidconfig[config].m_raidvol[vol].m_settings =
state;
i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
", auto-config of hot-swap drives is %s"
--- 7440,7450 ----
switch (irVolume->ReasonCode) {
case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
{
uint32_t i;
! mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
state;
i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
", auto-config of hot-swap drives is %s"
*** 7399,7409 ****
(state >> 16) & 0xff);
break;
}
case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
{
! slots->m_raidconfig[config].m_raidvol[vol].m_state =
(uint8_t)state;
mptsas_log(mpt, CE_NOTE,
"Volume %d is now %s\n", vol,
state == MPI2_RAID_VOL_STATE_OPTIMAL
--- 7463,7473 ----
(state >> 16) & 0xff);
break;
}
case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
{
! mpt->m_raidconfig[config].m_raidvol[vol].m_state =
(uint8_t)state;
mptsas_log(mpt, CE_NOTE,
"Volume %d is now %s\n", vol,
state == MPI2_RAID_VOL_STATE_OPTIMAL
*** 7421,7431 ****
"state unknown");
break;
}
case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
{
! slots->m_raidconfig[config].m_raidvol[vol].
m_statusflags = state;
mptsas_log(mpt, CE_NOTE,
" Volume %d is now %s%s%s%s%s%s%s%s%s\n",
vol,
--- 7485,7495 ----
"state unknown");
break;
}
case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
{
! mpt->m_raidconfig[config].m_raidvol[vol].
m_statusflags = state;
mptsas_log(mpt, CE_NOTE,
" Volume %d is now %s%s%s%s%s%s%s%s%s\n",
vol,
*** 7570,7591 ****
mutex_enter(&mpt->m_mutex);
mpt->m_restart_cmd_timeid = 0;
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
if (ptgt->m_reset_delay == 0) {
if (ptgt->m_t_throttle == QFULL_THROTTLE) {
mptsas_set_throttle(mpt, ptgt,
MAX_THROTTLE);
}
}
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mptsas_restart_hba(mpt);
mutex_exit(&mpt->m_mutex);
}
--- 7634,7651 ----
mutex_enter(&mpt->m_mutex);
mpt->m_restart_cmd_timeid = 0;
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
if (ptgt->m_reset_delay == 0) {
if (ptgt->m_t_throttle == QFULL_THROTTLE) {
mptsas_set_throttle(mpt, ptgt,
MAX_THROTTLE);
}
}
}
mptsas_restart_hba(mpt);
mutex_exit(&mpt->m_mutex);
}
*** 7653,7670 ****
* out of duplicates. This should be the normal case
* for block and raw I/O.
* If no duplicates, we have to scan through tag que and
* find the longest timeout value and use it. This is
* going to take a while...
! * Add 1 to m_n_slots to account for TM request.
*/
if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
if (--(ptgt->m_dups) == 0) {
if (ptgt->m_t_ncmds) {
mptsas_cmd_t *ssp;
uint_t n = 0;
! ushort_t nslots = (slots->m_n_slots + 1);
ushort_t i;
/*
* This crude check assumes we don't do
* this too often which seems reasonable
* for block and raw I/O.
--- 7713,7730 ----
* out of duplicates. This should be the normal case
* for block and raw I/O.
* If no duplicates, we have to scan through tag que and
* find the longest timeout value and use it. This is
* going to take a while...
! * Add 1 to m_n_normal to account for TM request.
*/
if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
if (--(ptgt->m_dups) == 0) {
if (ptgt->m_t_ncmds) {
mptsas_cmd_t *ssp;
uint_t n = 0;
! ushort_t nslots = (slots->m_n_normal + 1);
ushort_t i;
/*
* This crude check assumes we don't do
* this too often which seems reasonable
* for block and raw I/O.
*** 8419,8429 ****
static int
mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
{
int rval = FALSE;
uint8_t config, disk;
- mptsas_slots_t *slots = mpt->m_active;
ASSERT(mutex_owned(&mpt->m_mutex));
if (mptsas_debug_resets) {
mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
--- 8479,8488 ----
*** 8434,8446 ****
* Issue a Target Reset message to the target specified but not to a
* disk making up a raid volume. Just look through the RAID config
* Phys Disk list of DevHandles. If the target's DevHandle is in this
* list, then don't reset this target.
*/
! for (config = 0; config < slots->m_num_raid_configs; config++) {
for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
! if (devhdl == slots->m_raidconfig[config].
m_physdisk_devhdl[disk]) {
return (TRUE);
}
}
}
--- 8493,8505 ----
* Issue a Target Reset message to the target specified but not to a
* disk making up a raid volume. Just look through the RAID config
* Phys Disk list of DevHandles. If the target's DevHandle is in this
* list, then don't reset this target.
*/
! for (config = 0; config < mpt->m_num_raid_configs; config++) {
for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
! if (devhdl == mpt->m_raidconfig[config].
m_physdisk_devhdl[disk]) {
return (TRUE);
}
}
}
*** 8532,8542 ****
* Make sure the I/O Controller has flushed all cmds
* that are associated with this target for a target reset
* and target/lun for abort task set.
* Account for TM requests, which use the last SMID.
*/
! for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
if ((cmd = slots->m_slot[slot]) == NULL)
continue;
reason = CMD_RESET;
stat = STAT_DEV_RESET;
switch (tasktype) {
--- 8591,8601 ----
* Make sure the I/O Controller has flushed all cmds
* that are associated with this target for a target reset
* and target/lun for abort task set.
* Account for TM requests, which use the last SMID.
*/
! for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
if ((cmd = slots->m_slot[slot]) == NULL)
continue;
reason = CMD_RESET;
stat = STAT_DEV_RESET;
switch (tasktype) {
*** 8664,8674 ****
* The I/O Controller should have already sent back
* all commands via the scsi I/O reply frame. Make
* sure all commands have been flushed.
* Account for TM request, which use the last SMID.
*/
! for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
if ((cmd = slots->m_slot[slot]) == NULL)
continue;
if (cmd->cmd_flags & CFLAG_CMDIOC) {
/*
--- 8723,8733 ----
* The I/O Controller should have already sent back
* all commands via the scsi I/O reply frame. Make
* sure all commands have been flushed.
* Account for TM request, which use the last SMID.
*/
! for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
if ((cmd = slots->m_slot[slot]) == NULL)
continue;
if (cmd->cmd_flags & CFLAG_CMDIOC) {
/*
*** 8779,8797 ****
static void
mptsas_setup_bus_reset_delay(mptsas_t *mpt)
{
mptsas_target_t *ptgt = NULL;
NDBG22(("mptsas_setup_bus_reset_delay"));
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mptsas_start_watch_reset_delay();
}
--- 8838,8854 ----
static void
mptsas_setup_bus_reset_delay(mptsas_t *mpt)
{
mptsas_target_t *ptgt = NULL;
+ ASSERT(MUTEX_HELD(&mpt->m_mutex));
+
NDBG22(("mptsas_setup_bus_reset_delay"));
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
}
mptsas_start_watch_reset_delay();
}
*** 8839,8851 ****
NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
ASSERT(mutex_owned(&mpt->m_mutex));
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
if (ptgt->m_reset_delay != 0) {
ptgt->m_reset_delay -=
MPTSAS_WATCH_RESET_DELAY_TICK;
if (ptgt->m_reset_delay <= 0) {
ptgt->m_reset_delay = 0;
--- 8896,8907 ----
NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
ASSERT(mutex_owned(&mpt->m_mutex));
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
if (ptgt->m_reset_delay != 0) {
ptgt->m_reset_delay -=
MPTSAS_WATCH_RESET_DELAY_TICK;
if (ptgt->m_reset_delay <= 0) {
ptgt->m_reset_delay = 0;
*** 8854,8866 ****
restart++;
} else {
done = -1;
}
}
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
if (restart > 0) {
mptsas_restart_hba(mpt);
}
--- 8910,8919 ----
*** 9160,9170 ****
mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
{
mptsas_slots_t *old_active = mpt->m_active;
mptsas_slots_t *new_active;
size_t size;
- int rval = -1, i;
/*
* if there are active commands, then we cannot
* change size of active slots array.
*/
--- 9213,9222 ----
*** 9172,9206 ****
size = MPTSAS_SLOTS_SIZE(mpt);
new_active = kmem_zalloc(size, flag);
if (new_active == NULL) {
NDBG1(("new active alloc failed"));
! return (rval);
}
/*
* Since SMID 0 is reserved and the TM slot is reserved, the
* number of slots that can be used at any one time is
* m_max_requests - 2.
*/
! new_active->m_n_slots = (mpt->m_max_requests - 2);
new_active->m_size = size;
! new_active->m_tags = 1;
! if (old_active) {
! new_active->m_tgttbl = old_active->m_tgttbl;
! new_active->m_smptbl = old_active->m_smptbl;
! new_active->m_num_raid_configs =
! old_active->m_num_raid_configs;
! for (i = 0; i < new_active->m_num_raid_configs; i++) {
! new_active->m_raidconfig[i] =
! old_active->m_raidconfig[i];
! }
mptsas_free_active_slots(mpt);
- }
mpt->m_active = new_active;
- rval = 0;
! return (rval);
}
static void
mptsas_free_active_slots(mptsas_t *mpt)
{
--- 9224,9248 ----
size = MPTSAS_SLOTS_SIZE(mpt);
new_active = kmem_zalloc(size, flag);
if (new_active == NULL) {
NDBG1(("new active alloc failed"));
! return (-1);
}
/*
* Since SMID 0 is reserved and the TM slot is reserved, the
* number of slots that can be used at any one time is
* m_max_requests - 2.
*/
! new_active->m_n_normal = (mpt->m_max_requests - 2);
new_active->m_size = size;
! new_active->m_rotor = 1;
! if (old_active)
mptsas_free_active_slots(mpt);
mpt->m_active = new_active;
! return (0);
}
static void
mptsas_free_active_slots(mptsas_t *mpt)
{
*** 9341,9350 ****
--- 9383,9394 ----
{
int i;
mptsas_cmd_t *cmd;
mptsas_target_t *ptgt = NULL;
+ ASSERT(MUTEX_HELD(&mpt->m_mutex));
+
NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
#ifdef MPTSAS_TEST
if (mptsas_enable_untagged) {
mptsas_test_untagged++;
*** 9353,9363 ****
/*
* Check for commands stuck in active slot
* Account for TM requests, which use the last SMID.
*/
! for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
cmd->cmd_active_timeout -=
mptsas_scsi_watchdog_tick;
if (cmd->cmd_active_timeout <= 0) {
--- 9397,9407 ----
/*
* Check for commands stuck in active slot
* Account for TM requests, which use the last SMID.
*/
! for (i = 0; i <= mpt->m_active->m_n_normal; i++) {
if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
cmd->cmd_active_timeout -=
mptsas_scsi_watchdog_tick;
if (cmd->cmd_active_timeout <= 0) {
*** 9387,9399 ****
}
}
}
}
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
/*
* If we were draining due to a qfull condition,
* go back to full throttle.
*/
if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
--- 9431,9442 ----
}
}
}
}
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
/*
* If we were draining due to a qfull condition,
* go back to full throttle.
*/
if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
*** 9408,9428 ****
if (ptgt->m_timebase <=
mptsas_scsi_watchdog_tick) {
ptgt->m_timebase +=
mptsas_scsi_watchdog_tick;
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
continue;
}
ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
if (ptgt->m_timeout < 0) {
mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
continue;
}
if ((ptgt->m_timeout) <=
mptsas_scsi_watchdog_tick) {
--- 9451,9467 ----
*** 9429,9441 ****
NDBG23(("pending timeout"));
mptsas_set_throttle(mpt, ptgt,
DRAIN_THROTTLE);
}
}
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
}
/*
* timeout recovery
--- 9468,9477 ----
*** 9495,9511 ****
NDBG28(("mptsas_quiesce_bus"));
mutex_enter(&mpt->m_mutex);
/* Set all the throttles to zero */
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
/* If there are any outstanding commands in the queue */
if (mpt->m_ncmds) {
mpt->m_softstate |= MPTSAS_SS_DRAINING;
--- 9531,9543 ----
NDBG28(("mptsas_quiesce_bus"));
mutex_enter(&mpt->m_mutex);
/* Set all the throttles to zero */
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
}
/* If there are any outstanding commands in the queue */
if (mpt->m_ncmds) {
mpt->m_softstate |= MPTSAS_SS_DRAINING;
*** 9514,9530 ****
if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
/*
* Quiesce has been interrupted
*/
mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(
! &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mptsas_restart_hba(mpt);
if (mpt->m_quiesce_timeid != 0) {
timeout_id_t tid = mpt->m_quiesce_timeid;
mpt->m_quiesce_timeid = 0;
--- 9546,9558 ----
if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
/*
* Quiesce has been interrupted
*/
mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
}
mptsas_restart_hba(mpt);
if (mpt->m_quiesce_timeid != 0) {
timeout_id_t tid = mpt->m_quiesce_timeid;
mpt->m_quiesce_timeid = 0;
*** 9555,9571 ****
mptsas_target_t *ptgt = NULL;
NDBG28(("mptsas_unquiesce_bus"));
mutex_enter(&mpt->m_mutex);
mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mptsas_restart_hba(mpt);
mutex_exit(&mpt->m_mutex);
return (0);
}
--- 9583,9595 ----
mptsas_target_t *ptgt = NULL;
NDBG28(("mptsas_unquiesce_bus"));
mutex_enter(&mpt->m_mutex);
mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
}
mptsas_restart_hba(mpt);
mutex_exit(&mpt->m_mutex);
return (0);
}
*** 9585,9601 ****
} else {
/*
* The throttle may have been reset because
* of a SCSI bus reset
*/
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(
! &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
mpt, (MPTSAS_QUIESCE_TIMEOUT *
drv_usectohz(1000000)));
--- 9609,9621 ----
} else {
/*
* The throttle may have been reset because
* of a SCSI bus reset
*/
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
}
mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
mpt, (MPTSAS_QUIESCE_TIMEOUT *
drv_usectohz(1000000)));
*** 11323,11342 ****
(lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
return (EACCES);
/* Locate the target we're interrogating... */
mutex_enter(&mpt->m_mutex);
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
! if (ptgt->m_enclosure == lc.Enclosure &&
! ptgt->m_slot_num == lc.Slot) {
! break;
! }
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(
! &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
! }
if (ptgt == NULL) {
/* We could not find a target for that enclosure/slot. */
mutex_exit(&mpt->m_mutex);
return (ENOENT);
}
--- 11343,11354 ----
(lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
return (EACCES);
/* Locate the target we're interrogating... */
mutex_enter(&mpt->m_mutex);
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_slot, &lc);
if (ptgt == NULL) {
/* We could not find a target for that enclosure/slot. */
mutex_exit(&mpt->m_mutex);
return (ENOENT);
}
*** 11383,11398 ****
return (EFAULT);
}
/* Find out how many targets there are. */
mutex_enter(&mpt->m_mutex);
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
count++;
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mutex_exit(&mpt->m_mutex);
/*
* If we haven't been asked to copy out information on each target,
--- 11395,11407 ----
return (EFAULT);
}
/* Find out how many targets there are. */
mutex_enter(&mpt->m_mutex);
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
count++;
}
mutex_exit(&mpt->m_mutex);
/*
* If we haven't been asked to copy out information on each target,
*** 11413,11441 ****
}
di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
mutex_enter(&mpt->m_mutex);
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
if (i >= count) {
/*
* The number of targets changed while we weren't
* looking, so give up.
*/
mutex_exit(&mpt->m_mutex);
kmem_free(di, count * sizeof (mptsas_disk_info_t));
return (EAGAIN);
}
di[i].Instance = mpt->m_instance;
di[i].Enclosure = ptgt->m_enclosure;
di[i].Slot = ptgt->m_slot_num;
! di[i].SasAddress = ptgt->m_sas_wwn;
!
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(
! &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
i++;
}
mutex_exit(&mpt->m_mutex);
STRUCT_FSET(gdi, DiskCount, i);
--- 11422,11447 ----
}
di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
mutex_enter(&mpt->m_mutex);
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
if (i >= count) {
/*
* The number of targets changed while we weren't
* looking, so give up.
*/
+ refhash_rele(mpt->m_targets, ptgt);
mutex_exit(&mpt->m_mutex);
kmem_free(di, count * sizeof (mptsas_disk_info_t));
return (EAGAIN);
}
di[i].Instance = mpt->m_instance;
di[i].Enclosure = ptgt->m_enclosure;
di[i].Slot = ptgt->m_slot_num;
! di[i].SasAddress = ptgt->m_addr.mta_wwn;
i++;
}
mutex_exit(&mpt->m_mutex);
STRUCT_FSET(gdi, DiskCount, i);
*** 11737,11753 ****
mpt->m_in_reset = TRUE;
/*
* Set all throttles to HOLD
*/
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
/*
* Disable interrupts
*/
--- 11743,11755 ----
mpt->m_in_reset = TRUE;
/*
* Set all throttles to HOLD
*/
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
}
/*
* Disable interrupts
*/
*** 11779,11795 ****
}
/*
* Reset the throttles
*/
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mptsas_doneq_empty(mpt);
mptsas_restart_hba(mpt);
--- 11781,11793 ----
}
/*
* Reset the throttles
*/
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
}
mptsas_doneq_empty(mpt);
mptsas_restart_hba(mpt);
*** 11851,11860 ****
--- 11849,11864 ----
if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
goto fail;
}
+ mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
+ mptsas_target_addr_hash, mptsas_target_addr_cmp,
+ mptsas_target_free, sizeof (mptsas_target_t),
+ offsetof(mptsas_target_t, m_link),
+ offsetof(mptsas_target_t, m_addr), KM_SLEEP);
+
if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
goto fail;
}
/*
* Allocate request message frames, reply free queue, reply descriptor
*** 12489,12499 ****
int rval;
uint32_t dev_info;
uint64_t sas_wwn;
mptsas_phymask_t phymask;
uint8_t physport, phynum, config, disk;
- mptsas_slots_t *slots = mpt->m_active;
uint64_t devicename;
uint16_t pdev_hdl;
mptsas_target_t *tmp_tgt = NULL;
uint16_t bay_num, enclosure;
--- 12493,12502 ----
*** 12516,12538 ****
/*
* Check if the dev handle is for a Phys Disk. If so, set return value
* and exit. Don't add Phys Disks to hash.
*/
! for (config = 0; config < slots->m_num_raid_configs; config++) {
for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
! if (*dev_handle == slots->m_raidconfig[config].
m_physdisk_devhdl[disk]) {
rval = DEV_INFO_PHYS_DISK;
return (rval);
}
}
}
/*
* Get SATA Device Name from SAS device page0 for
! * sata device, if device name doesn't exist, set m_sas_wwn to
* 0 for direct attached SATA. For the device behind the expander
* we still can use STP address assigned by expander.
*/
if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
--- 12519,12541 ----
/*
* Check if the dev handle is for a Phys Disk. If so, set return value
* and exit. Don't add Phys Disks to hash.
*/
! for (config = 0; config < mpt->m_num_raid_configs; config++) {
for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
! if (*dev_handle == mpt->m_raidconfig[config].
m_physdisk_devhdl[disk]) {
rval = DEV_INFO_PHYS_DISK;
return (rval);
}
}
}
/*
* Get SATA Device Name from SAS device page0 for
! * sata device, if device name doesn't exist, set mta_wwn to
* 0 for direct attached SATA. For the device behind the expander
* we still can use STP address assigned by expander.
*/
if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
*** 12555,12565 ****
sas_wwn = 0;
}
}
phymask = mptsas_physport_to_phymask(mpt, physport);
! *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
dev_info, phymask, phynum);
if (*pptgt == NULL) {
mptsas_log(mpt, CE_WARN, "Failed to allocated target"
"structure!");
rval = DEV_INFO_FAIL_ALLOC;
--- 12558,12568 ----
sas_wwn = 0;
}
}
phymask = mptsas_physport_to_phymask(mpt, physport);
! *pptgt = mptsas_tgt_alloc(mpt, *dev_handle, sas_wwn,
dev_info, phymask, phynum);
if (*pptgt == NULL) {
mptsas_log(mpt, CE_WARN, "Failed to allocated target"
"structure!");
rval = DEV_INFO_FAIL_ALLOC;
*** 12985,12995 ****
* TODO Another senario is, we hotplug the same disk
* on the same slot, the devhdl changed, is this
* possible?
* tgt_private->t_private != ptgt
*/
! if (sasaddr != ptgt->m_sas_wwn) {
/*
* The device has changed although the devhdl is the
* same (Enclosure mapping mode, change drive on the
* same slot)
*/
--- 12988,12998 ----
* TODO Another senario is, we hotplug the same disk
* on the same slot, the devhdl changed, is this
* possible?
* tgt_private->t_private != ptgt
*/
! if (sasaddr != ptgt->m_addr.mta_wwn) {
/*
* The device has changed although the devhdl is the
* same (Enclosure mapping mode, change drive on the
* same slot)
*/
*** 13014,13030 ****
mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
dev_info_t **lundip)
{
int rval;
mptsas_t *mpt = DIP2MPT(pdip);
! int phymask;
mptsas_target_t *ptgt = NULL;
/*
* Get the physical port associated to the iport
*/
! phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
"phymask", 0);
ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
if (ptgt == NULL) {
/*
--- 13017,13033 ----
mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
dev_info_t **lundip)
{
int rval;
mptsas_t *mpt = DIP2MPT(pdip);
! mptsas_phymask_t phymask;
mptsas_target_t *ptgt = NULL;
/*
* Get the physical port associated to the iport
*/
! phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
"phymask", 0);
ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
if (ptgt == NULL) {
/*
*** 13107,13117 ****
uint64_t sas_wwn = 0;
uint8_t phy = 0xFF;
uint32_t dev_info = 0;
mutex_enter(&mpt->m_mutex);
! sas_wwn = ptgt->m_sas_wwn;
phy = ptgt->m_phynum;
dev_info = ptgt->m_deviceinfo;
mutex_exit(&mpt->m_mutex);
if (sas_wwn == 0) {
--- 13110,13120 ----
uint64_t sas_wwn = 0;
uint8_t phy = 0xFF;
uint32_t dev_info = 0;
mutex_enter(&mpt->m_mutex);
! sas_wwn = ptgt->m_addr.mta_wwn;
phy = ptgt->m_phynum;
dev_info = ptgt->m_deviceinfo;
mutex_exit(&mpt->m_mutex);
if (sas_wwn == 0) {
*** 13222,13232 ****
struct scsi_inquiry *sd_inq = NULL;
mptsas_t *mpt = DIP2MPT(pdip);
mptsas_target_t *ptgt = NULL;
mutex_enter(&mpt->m_mutex);
! ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target);
mutex_exit(&mpt->m_mutex);
if (ptgt == NULL) {
mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
"not found.", target);
return (rval);
--- 13225,13236 ----
struct scsi_inquiry *sd_inq = NULL;
mptsas_t *mpt = DIP2MPT(pdip);
mptsas_target_t *ptgt = NULL;
mutex_enter(&mpt->m_mutex);
! ptgt = refhash_linear_search(mpt->m_targets,
! mptsas_target_eval_devhdl, &target);
mutex_exit(&mpt->m_mutex);
if (ptgt == NULL) {
mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
"not found.", target);
return (rval);
*** 13255,13276 ****
{
mptsas_t *mpt = DIP2MPT(pdip);
int config, vol;
int target;
dev_info_t *lundip = NULL;
- mptsas_slots_t *slots = mpt->m_active;
/*
* Get latest RAID info and search for any Volume DevHandles. If any
* are found, configure the volume.
*/
mutex_enter(&mpt->m_mutex);
! for (config = 0; config < slots->m_num_raid_configs; config++) {
for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
! if (slots->m_raidconfig[config].m_raidvol[vol].m_israid
== 1) {
! target = slots->m_raidconfig[config].
m_raidvol[vol].m_raidhandle;
mutex_exit(&mpt->m_mutex);
(void) mptsas_config_raid(pdip, target,
&lundip);
mutex_enter(&mpt->m_mutex);
--- 13259,13279 ----
{
mptsas_t *mpt = DIP2MPT(pdip);
int config, vol;
int target;
dev_info_t *lundip = NULL;
/*
* Get latest RAID info and search for any Volume DevHandles. If any
* are found, configure the volume.
*/
mutex_enter(&mpt->m_mutex);
! for (config = 0; config < mpt->m_num_raid_configs; config++) {
for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
! if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid
== 1) {
! target = mpt->m_raidconfig[config].
m_raidvol[vol].m_raidhandle;
mutex_exit(&mpt->m_mutex);
(void) mptsas_config_raid(pdip, target,
&lundip);
mutex_enter(&mpt->m_mutex);
*** 13294,13304 ****
char *addr;
char *nodename;
mptsas_t *mpt = DIP2MPT(pdip);
mutex_enter(&mpt->m_mutex);
! wwid = ptgt->m_sas_wwn;
mutex_exit(&mpt->m_mutex);
child = ddi_get_child(pdip);
while (child) {
find = 0;
--- 13297,13307 ----
char *addr;
char *nodename;
mptsas_t *mpt = DIP2MPT(pdip);
mutex_enter(&mpt->m_mutex);
! wwid = ptgt->m_addr.mta_wwn;
mutex_exit(&mpt->m_mutex);
child = ddi_get_child(pdip);
while (child) {
find = 0;
*** 13398,13408 ****
if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
!= DDI_SUCCESS) {
break;
}
mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
! (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
}
/*
* Config target devices
*/
--- 13401,13411 ----
if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
!= DDI_SUCCESS) {
break;
}
mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
! (void) mptsas_smp_alloc(mpt, &smp_node);
}
/*
* Config target devices
*/
*** 13430,13457 ****
}
}
void
- mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab)
- {
- mptsas_hash_data_t *data;
- data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
- while (data != NULL) {
- data->devhdl = MPTSAS_INVALID_DEVHDL;
- data->device_info = 0;
- /*
- * For tgttbl, clear dr_flag.
- */
- data->dr_flag = MPTSAS_DR_INACTIVE;
- data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
- }
- }
-
- void
mptsas_update_driver_data(struct mptsas *mpt)
{
/*
* TODO after hard reset, update the driver data structures
* 1. update port/phymask mapping table mpt->m_phy_info
* 2. invalid all the entries in hash table
* m_devhdl = 0xffff and m_deviceinfo = 0
--- 13433,13449 ----
}
}
void
mptsas_update_driver_data(struct mptsas *mpt)
{
+ mptsas_target_t *tp;
+ mptsas_smp_t *sp;
+
+ ASSERT(MUTEX_HELD(&mpt->m_mutex));
+
/*
* TODO after hard reset, update the driver data structures
* 1. update port/phymask mapping table mpt->m_phy_info
* 2. invalid all the entries in hash table
* m_devhdl = 0xffff and m_deviceinfo = 0
*** 13458,13470 ****
* 3. call sas_device_page/expander_page to update hash table
*/
mptsas_update_phymask(mpt);
/*
* Invalid the existing entries
*/
! mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl);
! mptsas_invalid_hashtab(&mpt->m_active->m_smptbl);
mpt->m_done_traverse_dev = 0;
mpt->m_done_traverse_smp = 0;
mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
mptsas_update_hashtab(mpt);
}
--- 13450,13477 ----
* 3. call sas_device_page/expander_page to update hash table
*/
mptsas_update_phymask(mpt);
/*
* Invalid the existing entries
+ *
+ * XXX - It seems like we should just delete everything here. We are
+ * holding the lock and are about to refresh all the targets in both
+ * hashes anyway. Given the path we're in, what outstanding async
+ * event could possibly be trying to reference one of these things
+ * without taking the lock, and how would that be useful anyway?
*/
! for (tp = refhash_first(mpt->m_targets); tp != NULL;
! tp = refhash_next(mpt->m_targets, tp)) {
! tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
! tp->m_deviceinfo = 0;
! tp->m_dr_flag = MPTSAS_DR_INACTIVE;
! }
! for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
! sp = refhash_next(mpt->m_smp_targets, sp)) {
! sp->m_devhdl = MPTSAS_INVALID_DEVHDL;
! sp->m_deviceinfo = 0;
! }
mpt->m_done_traverse_dev = 0;
mpt->m_done_traverse_smp = 0;
mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
mptsas_update_hashtab(mpt);
}
*** 13497,13532 ****
if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
mptsas_update_hashtab(mpt);
}
! psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl,
! MPTSAS_HASH_FIRST);
! while (psmp != NULL) {
! phy_mask = psmp->m_phymask;
if (phy_mask == phymask) {
smpdip = NULL;
mutex_exit(&mpt->m_mutex);
(void) mptsas_online_smp(pdip, psmp, &smpdip);
mutex_enter(&mpt->m_mutex);
}
- psmp = (mptsas_smp_t *)mptsas_hash_traverse(
- &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT);
}
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
! phy_mask = ptgt->m_phymask;
if (phy_mask == phymask) {
mutex_exit(&mpt->m_mutex);
(void) mptsas_config_target(pdip, ptgt);
mutex_enter(&mpt->m_mutex);
}
-
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
}
mutex_exit(&mpt->m_mutex);
}
static int
--- 13504,13532 ----
if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
mptsas_update_hashtab(mpt);
}
! for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL;
! psmp = refhash_next(mpt->m_smp_targets, psmp)) {
! phy_mask = psmp->m_addr.mta_phymask;
if (phy_mask == phymask) {
smpdip = NULL;
mutex_exit(&mpt->m_mutex);
(void) mptsas_online_smp(pdip, psmp, &smpdip);
mutex_enter(&mpt->m_mutex);
}
}
! for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
! ptgt = refhash_next(mpt->m_targets, ptgt)) {
! phy_mask = ptgt->m_addr.mta_phymask;
if (phy_mask == phymask) {
mutex_exit(&mpt->m_mutex);
(void) mptsas_config_target(pdip, ptgt);
mutex_enter(&mpt->m_mutex);
}
}
mutex_exit(&mpt->m_mutex);
}
static int
*** 13704,13714 ****
int rval = DDI_FAILURE;
char *devname;
char wwn_str[MPTSAS_WWN_STRLEN];
dev_info_t *cdip;
! (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
cdip = mptsas_find_smp_child(pdip, wwn_str);
if (cdip == NULL)
return (DDI_SUCCESS);
--- 13704,13714 ----
int rval = DDI_FAILURE;
char *devname;
char wwn_str[MPTSAS_WWN_STRLEN];
dev_info_t *cdip;
! (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
cdip = mptsas_find_smp_child(pdip, wwn_str);
if (cdip == NULL)
return (DDI_SUCCESS);
*** 13984,13994 ****
char pdev_wwn_str[MPTSAS_WWN_STRLEN];
uint32_t dev_info;
mutex_enter(&mpt->m_mutex);
target = ptgt->m_devhdl;
! sas_wwn = ptgt->m_sas_wwn;
devinfo = ptgt->m_deviceinfo;
phy = ptgt->m_phynum;
mutex_exit(&mpt->m_mutex);
if (sas_wwn) {
--- 13984,13994 ----
char pdev_wwn_str[MPTSAS_WWN_STRLEN];
uint32_t dev_info;
mutex_enter(&mpt->m_mutex);
target = ptgt->m_devhdl;
! sas_wwn = ptgt->m_addr.mta_wwn;
devinfo = ptgt->m_deviceinfo;
phy = ptgt->m_phynum;
mutex_exit(&mpt->m_mutex);
if (sas_wwn) {
*** 14333,14343 ****
uint32_t dev_info;
int64_t lun64 = 0;
mutex_enter(&mpt->m_mutex);
target = ptgt->m_devhdl;
! sas_wwn = ptgt->m_sas_wwn;
devinfo = ptgt->m_deviceinfo;
phy = ptgt->m_phynum;
mutex_exit(&mpt->m_mutex);
/*
--- 14333,14343 ----
uint32_t dev_info;
int64_t lun64 = 0;
mutex_enter(&mpt->m_mutex);
target = ptgt->m_devhdl;
! sas_wwn = ptgt->m_addr.mta_wwn;
devinfo = ptgt->m_deviceinfo;
phy = ptgt->m_phynum;
mutex_exit(&mpt->m_mutex);
/*
*** 14452,14462 ****
/*
* The following code is to set properties for SM-HBA support,
* it doesn't apply to RAID volumes
*/
! if (ptgt->m_phymask == 0)
goto phys_raid_lun;
mutex_enter(&mpt->m_mutex);
page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
--- 14452,14462 ----
/*
* The following code is to set properties for SM-HBA support,
* it doesn't apply to RAID volumes
*/
! if (ptgt->m_addr.mta_phymask == 0)
goto phys_raid_lun;
mutex_enter(&mpt->m_mutex);
page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
*** 14606,14616 ****
}
}
/*
* Create the phy-num property for non-raid disk
*/
! if (ptgt->m_phymask != 0) {
if (ndi_prop_update_int(DDI_DEV_T_NONE,
*lun_dip, "phy-num", ptgt->m_phynum) !=
DDI_PROP_SUCCESS) {
mptsas_log(mpt, CE_WARN, "mptsas driver "
"failed to create phy-num property for "
--- 14606,14616 ----
}
}
/*
* Create the phy-num property for non-raid disk
*/
! if (ptgt->m_addr.mta_phymask != 0) {
if (ndi_prop_update_int(DDI_DEV_T_NONE,
*lun_dip, "phy-num", ptgt->m_phynum) !=
DDI_PROP_SUCCESS) {
mptsas_log(mpt, CE_WARN, "mptsas driver "
"failed to create phy-num property for "
*** 14728,14744 ****
char *iport = NULL;
mptsas_phymask_t phy_mask = 0;
uint16_t attached_devhdl;
uint16_t bay_num, enclosure;
! (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
/*
* Probe smp device, prevent the node of removed device from being
* configured succesfully
*/
! if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) {
return (DDI_FAILURE);
}
if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
return (DDI_SUCCESS);
--- 14728,14744 ----
char *iport = NULL;
mptsas_phymask_t phy_mask = 0;
uint16_t attached_devhdl;
uint16_t bay_num, enclosure;
! (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
/*
* Probe smp device, prevent the node of removed device from being
* configured succesfully
*/
! if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) {
return (DDI_FAILURE);
}
if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
return (DDI_SUCCESS);
*** 14762,14772 ****
"property for smp device %s (sas_wwn)",
wwn_str);
ndi_rtn = NDI_FAILURE;
goto smp_create_done;
}
! (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr);
if (ndi_prop_update_string(DDI_DEV_T_NONE,
*smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
DDI_PROP_SUCCESS) {
mptsas_log(mpt, CE_WARN, "mptsas unable to create "
"property for iport target-port %s (sas_wwn)",
--- 14762,14772 ----
"property for smp device %s (sas_wwn)",
wwn_str);
ndi_rtn = NDI_FAILURE;
goto smp_create_done;
}
! (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn);
if (ndi_prop_update_string(DDI_DEV_T_NONE,
*smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
DDI_PROP_SUCCESS) {
mptsas_log(mpt, CE_WARN, "mptsas unable to create "
"property for iport target-port %s (sas_wwn)",
*** 15046,15056 ****
/*
* If we didn't get a match, we need to get sas page0 for each device, and
* untill we get a match. If failed, return NULL
*/
static mptsas_target_t *
! mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy)
{
int i, j = 0;
int rval = 0;
uint16_t cur_handle;
uint32_t page_address;
--- 15046,15056 ----
/*
* If we didn't get a match, we need to get sas page0 for each device, and
* untill we get a match. If failed, return NULL
*/
static mptsas_target_t *
! mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy)
{
int i, j = 0;
int rval = 0;
uint16_t cur_handle;
uint32_t page_address;
*** 15078,15099 ****
if (mpt->m_phy_info[phy].phy_mask != phymask)
return (NULL);
mutex_enter(&mpt->m_mutex);
! ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
! MPTSAS_HASH_FIRST);
! while (ptgt != NULL) {
! if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
mutex_exit(&mpt->m_mutex);
return (ptgt);
}
- ptgt = (mptsas_target_t *)mptsas_hash_traverse(
- &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
- }
-
if (mpt->m_done_traverse_dev) {
mutex_exit(&mpt->m_mutex);
return (NULL);
}
--- 15078,15094 ----
if (mpt->m_phy_info[phy].phy_mask != phymask)
return (NULL);
mutex_enter(&mpt->m_mutex);
! ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn,
! &phy);
! if (ptgt != NULL) {
mutex_exit(&mpt->m_mutex);
return (ptgt);
}
if (mpt->m_done_traverse_dev) {
mutex_exit(&mpt->m_mutex);
return (NULL);
}
*** 15113,15149 ****
(rval == DEV_INFO_PHYS_DISK)) {
continue;
}
mpt->m_dev_handle = cur_handle;
! if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
break;
}
}
mutex_exit(&mpt->m_mutex);
return (ptgt);
}
/*
! * The ptgt->m_sas_wwn contains the wwid for each disk.
* For Raid volumes, we need to check m_raidvol[x].m_raidwwid
* If we didn't get a match, we need to get sas page0 for each device, and
* untill we get a match
* If failed, return NULL
*/
static mptsas_target_t *
! mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid)
{
int rval = 0;
uint16_t cur_handle;
uint32_t page_address;
mptsas_target_t *tmp_tgt = NULL;
mutex_enter(&mpt->m_mutex);
! tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
! &mpt->m_active->m_tgttbl, wwid, phymask);
if (tmp_tgt != NULL) {
mutex_exit(&mpt->m_mutex);
return (tmp_tgt);
}
--- 15108,15146 ----
(rval == DEV_INFO_PHYS_DISK)) {
continue;
}
mpt->m_dev_handle = cur_handle;
! if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) {
break;
}
}
mutex_exit(&mpt->m_mutex);
return (ptgt);
}
/*
! * The ptgt->m_addr.mta_wwn contains the wwid for each disk.
* For Raid volumes, we need to check m_raidvol[x].m_raidwwid
* If we didn't get a match, we need to get sas page0 for each device, and
* untill we get a match
* If failed, return NULL
*/
static mptsas_target_t *
! mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
{
int rval = 0;
uint16_t cur_handle;
uint32_t page_address;
mptsas_target_t *tmp_tgt = NULL;
+ mptsas_target_addr_t addr;
+ addr.mta_wwn = wwid;
+ addr.mta_phymask = phymask;
mutex_enter(&mpt->m_mutex);
! tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
if (tmp_tgt != NULL) {
mutex_exit(&mpt->m_mutex);
return (tmp_tgt);
}
*** 15151,15162 ****
/*
* It's IR volume
*/
rval = mptsas_get_raid_info(mpt);
if (rval) {
! tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
! &mpt->m_active->m_tgttbl, wwid, phymask);
}
mutex_exit(&mpt->m_mutex);
return (tmp_tgt);
}
--- 15148,15158 ----
/*
* It's IR volume
*/
rval = mptsas_get_raid_info(mpt);
if (rval) {
! tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
}
mutex_exit(&mpt->m_mutex);
return (tmp_tgt);
}
*** 15165,15175 ****
return (NULL);
}
/* If didn't get a match, come here */
cur_handle = mpt->m_dev_handle;
! for (; ; ) {
tmp_tgt = NULL;
page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
rval = mptsas_get_target_device_info(mpt, page_address,
&cur_handle, &tmp_tgt);
--- 15161,15171 ----
return (NULL);
}
/* If didn't get a match, come here */
cur_handle = mpt->m_dev_handle;
! for (;;) {
tmp_tgt = NULL;
page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
rval = mptsas_get_target_device_info(mpt, page_address,
&cur_handle, &tmp_tgt);
*** 15181,15211 ****
if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
(rval == DEV_INFO_PHYS_DISK)) {
continue;
}
mpt->m_dev_handle = cur_handle;
! if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) &&
! (tmp_tgt->m_phymask == phymask)) {
break;
}
}
mutex_exit(&mpt->m_mutex);
return (tmp_tgt);
}
static mptsas_smp_t *
! mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid)
{
int rval = 0;
uint16_t cur_handle;
uint32_t page_address;
mptsas_smp_t smp_node, *psmp = NULL;
mutex_enter(&mpt->m_mutex);
! psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl,
! wwid, phymask);
if (psmp != NULL) {
mutex_exit(&mpt->m_mutex);
return (psmp);
}
--- 15177,15210 ----
if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
(rval == DEV_INFO_PHYS_DISK)) {
continue;
}
mpt->m_dev_handle = cur_handle;
! if ((tmp_tgt->m_addr.mta_wwn) &&
! (tmp_tgt->m_addr.mta_wwn == wwid) &&
! (tmp_tgt->m_addr.mta_phymask == phymask)) {
break;
}
}
mutex_exit(&mpt->m_mutex);
return (tmp_tgt);
}
static mptsas_smp_t *
! mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
{
int rval = 0;
uint16_t cur_handle;
uint32_t page_address;
mptsas_smp_t smp_node, *psmp = NULL;
+ mptsas_target_addr_t addr;
+ addr.mta_wwn = wwid;
+ addr.mta_phymask = phymask;
mutex_enter(&mpt->m_mutex);
! psmp = refhash_lookup(mpt->m_smp_targets, &addr);
if (psmp != NULL) {
mutex_exit(&mpt->m_mutex);
return (psmp);
}
*** 15214,15499 ****
return (NULL);
}
/* If didn't get a match, come here */
cur_handle = mpt->m_smp_devhdl;
! for (; ; ) {
psmp = NULL;
page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
rval = mptsas_get_sas_expander_page0(mpt, page_address,
&smp_node);
if (rval != DDI_SUCCESS) {
break;
}
mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
! psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
ASSERT(psmp);
! if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) &&
! (psmp->m_phymask == phymask)) {
break;
}
}
mutex_exit(&mpt->m_mutex);
return (psmp);
}
- /* helper functions using hash */
-
- /*
- * Can't have duplicate entries for same devhdl,
- * if there are invalid entries, the devhdl should be set to 0xffff
- */
- static void *
- mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl)
- {
- mptsas_hash_data_t *data;
-
- data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
- while (data != NULL) {
- if (data->devhdl == devhdl) {
- break;
- }
- data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
- }
- return (data);
- }
-
mptsas_target_t *
! mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
{
mptsas_target_t *tmp_tgt = NULL;
! tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
if (tmp_tgt != NULL) {
NDBG20(("Hash item already exist"));
tmp_tgt->m_deviceinfo = devinfo;
! tmp_tgt->m_devhdl = devhdl;
return (tmp_tgt);
}
tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
if (tmp_tgt == NULL) {
cmn_err(CE_WARN, "Fatal, allocated tgt failed");
return (NULL);
}
tmp_tgt->m_devhdl = devhdl;
! tmp_tgt->m_sas_wwn = wwid;
tmp_tgt->m_deviceinfo = devinfo;
! tmp_tgt->m_phymask = phymask;
tmp_tgt->m_phynum = phynum;
/* Initialized the tgt structure */
tmp_tgt->m_qfull_retries = QFULL_RETRIES;
tmp_tgt->m_qfull_retry_interval =
drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
tmp_tgt->m_t_throttle = MAX_THROTTLE;
! mptsas_hash_add(hashtab, tmp_tgt);
return (tmp_tgt);
}
static void
! mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
! mptsas_phymask_t phymask)
{
! mptsas_target_t *tmp_tgt;
! tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
! if (tmp_tgt == NULL) {
! cmn_err(CE_WARN, "Tgt not found, nothing to free");
! } else {
! kmem_free(tmp_tgt, sizeof (struct mptsas_target));
! }
}
- /*
- * Return the entry in the hash table
- */
static mptsas_smp_t *
! mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
{
! uint64_t key1 = data->m_sasaddr;
! mptsas_phymask_t key2 = data->m_phymask;
mptsas_smp_t *ret_data;
! ret_data = mptsas_hash_search(hashtab, key1, key2);
if (ret_data != NULL) {
! bcopy(data, ret_data, sizeof (mptsas_smp_t));
return (ret_data);
}
ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
bcopy(data, ret_data, sizeof (mptsas_smp_t));
! mptsas_hash_add(hashtab, ret_data);
return (ret_data);
}
- static void
- mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
- mptsas_phymask_t phymask)
- {
- mptsas_smp_t *tmp_smp;
- tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask);
- if (tmp_smp == NULL) {
- cmn_err(CE_WARN, "Smp element not found, nothing to free");
- } else {
- kmem_free(tmp_smp, sizeof (struct mptsas_smp));
- }
- }
-
/*
- * Hash operation functions
- * key1 is the sas_wwn, key2 is the phymask
- */
- static void
- mptsas_hash_init(mptsas_hash_table_t *hashtab)
- {
- if (hashtab == NULL) {
- return;
- }
- bzero(hashtab->head, sizeof (mptsas_hash_node_t) *
- MPTSAS_HASH_ARRAY_SIZE);
- hashtab->cur = NULL;
- hashtab->line = 0;
- }
-
- static void
- mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen)
- {
- uint16_t line = 0;
- mptsas_hash_node_t *cur = NULL, *last = NULL;
-
- if (hashtab == NULL) {
- return;
- }
- for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) {
- cur = hashtab->head[line];
- while (cur != NULL) {
- last = cur;
- cur = cur->next;
- kmem_free(last->data, datalen);
- kmem_free(last, sizeof (mptsas_hash_node_t));
- }
- }
- }
-
- /*
- * You must guarantee the element doesn't exist in the hash table
- * before you call mptsas_hash_add()
- */
- static void
- mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data)
- {
- uint64_t key1 = ((mptsas_hash_data_t *)data)->key1;
- mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2;
- mptsas_hash_node_t **head = NULL;
- mptsas_hash_node_t *node = NULL;
-
- if (hashtab == NULL) {
- return;
- }
- ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL);
- node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP);
- node->data = data;
-
- head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
- if (*head == NULL) {
- *head = node;
- } else {
- node->next = *head;
- *head = node;
- }
- }
-
- static void *
- mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
- mptsas_phymask_t key2)
- {
- mptsas_hash_node_t **head = NULL;
- mptsas_hash_node_t *last = NULL, *cur = NULL;
- mptsas_hash_data_t *data;
- if (hashtab == NULL) {
- return (NULL);
- }
- head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
- cur = *head;
- while (cur != NULL) {
- data = cur->data;
- if ((data->key1 == key1) && (data->key2 == key2)) {
- if (last == NULL) {
- (*head) = cur->next;
- } else {
- last->next = cur->next;
- }
- kmem_free(cur, sizeof (mptsas_hash_node_t));
- return (data);
- } else {
- last = cur;
- cur = cur->next;
- }
- }
- return (NULL);
- }
-
- static void *
- mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
- mptsas_phymask_t key2)
- {
- mptsas_hash_node_t *cur = NULL;
- mptsas_hash_data_t *data;
- if (hashtab == NULL) {
- return (NULL);
- }
- cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE];
- while (cur != NULL) {
- data = cur->data;
- if ((data->key1 == key1) && (data->key2 == key2)) {
- return (data);
- } else {
- cur = cur->next;
- }
- }
- return (NULL);
- }
-
- static void *
- mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos)
- {
- mptsas_hash_node_t *this = NULL;
-
- if (hashtab == NULL) {
- return (NULL);
- }
-
- if (pos == MPTSAS_HASH_FIRST) {
- hashtab->line = 0;
- hashtab->cur = NULL;
- this = hashtab->head[0];
- } else {
- if (hashtab->cur == NULL) {
- return (NULL);
- } else {
- this = hashtab->cur->next;
- }
- }
-
- while (this == NULL) {
- hashtab->line++;
- if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
- /* the traverse reaches the end */
- hashtab->cur = NULL;
- return (NULL);
- } else {
- this = hashtab->head[hashtab->line];
- }
- }
- hashtab->cur = this;
- return (this->data);
- }
-
- /*
* Functions for SGPIO LED support
*/
static dev_info_t *
mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
{
--- 15213,15317 ----
return (NULL);
}
/* If didn't get a match, come here */
cur_handle = mpt->m_smp_devhdl;
! for (;;) {
psmp = NULL;
page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
rval = mptsas_get_sas_expander_page0(mpt, page_address,
&smp_node);
if (rval != DDI_SUCCESS) {
break;
}
mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
! psmp = mptsas_smp_alloc(mpt, &smp_node);
ASSERT(psmp);
! if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) &&
! (psmp->m_addr.mta_phymask == phymask)) {
break;
}
}
mutex_exit(&mpt->m_mutex);
return (psmp);
}
mptsas_target_t *
! mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid,
uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
{
mptsas_target_t *tmp_tgt = NULL;
+ mptsas_target_addr_t addr;
! addr.mta_wwn = wwid;
! addr.mta_phymask = phymask;
! tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
if (tmp_tgt != NULL) {
NDBG20(("Hash item already exist"));
tmp_tgt->m_deviceinfo = devinfo;
! tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */
return (tmp_tgt);
}
tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
if (tmp_tgt == NULL) {
cmn_err(CE_WARN, "Fatal, allocated tgt failed");
return (NULL);
}
tmp_tgt->m_devhdl = devhdl;
! tmp_tgt->m_addr.mta_wwn = wwid;
tmp_tgt->m_deviceinfo = devinfo;
! tmp_tgt->m_addr.mta_phymask = phymask;
tmp_tgt->m_phynum = phynum;
/* Initialized the tgt structure */
tmp_tgt->m_qfull_retries = QFULL_RETRIES;
tmp_tgt->m_qfull_retry_interval =
drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
tmp_tgt->m_t_throttle = MAX_THROTTLE;
! refhash_insert(mpt->m_targets, tmp_tgt);
return (tmp_tgt);
}
static void
! mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
{
! dst->m_devhdl = src->m_devhdl;
! dst->m_deviceinfo = src->m_deviceinfo;
! dst->m_pdevhdl = src->m_pdevhdl;
! dst->m_pdevinfo = src->m_pdevinfo;
}
static mptsas_smp_t *
! mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
{
! mptsas_target_addr_t addr;
mptsas_smp_t *ret_data;
! addr.mta_wwn = data->m_addr.mta_wwn;
! addr.mta_phymask = data->m_addr.mta_phymask;
! ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
! /*
! * If there's already a matching SMP target, update its fields
! * in place. Since the address is not changing, it's safe to do
! * this. We cannot just bcopy() here because the structure we've
! * been given has invalid hash links.
! */
if (ret_data != NULL) {
! mptsas_smp_target_copy(data, ret_data);
return (ret_data);
}
ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
bcopy(data, ret_data, sizeof (mptsas_smp_t));
! refhash_insert(mpt->m_smp_targets, ret_data);
return (ret_data);
}
/*
* Functions for SGPIO LED support
*/
static dev_info_t *
mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
{
*** 15572,15582 ****
*
* In addition, we do not support this operation for RAID volumes,
* since there is no slot associated with them.
*/
if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
! ptgt->m_phymask == 0) {
return (ENOTTY);
}
bzero(&req, sizeof (req));
bzero(&rep, sizeof (rep));
--- 15390,15400 ----
*
* In addition, we do not support this operation for RAID volumes,
* since there is no slot associated with them.
*/
if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
! ptgt->m_addr.mta_phymask == 0) {
return (ENOTTY);
}
bzero(&req, sizeof (req));
bzero(&rep, sizeof (rep));