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));