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>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
          +++ new/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  25      - * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       25 + * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  26   26   * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
  27   27   */
  28   28  
  29   29  /*
  30   30   * Copyright (c) 2000 to 2010, LSI Corporation.
  31   31   * All rights reserved.
  32   32   *
  33   33   * Redistribution and use in source and binary forms of all code within
  34   34   * this file that is exclusively owned by LSI, with or without
  35   35   * modification, is permitted provided that, in addition to the CDDL 1.0
↓ open down ↓ 54 lines elided ↑ open up ↑
  90   90  #pragma pack()
  91   91  
  92   92  /*
  93   93   * private header files.
  94   94   *
  95   95   */
  96   96  #include <sys/scsi/impl/scsi_reset_notify.h>
  97   97  #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  98   98  #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
  99   99  #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
      100 +#include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
 100  101  #include <sys/raidioctl.h>
 101  102  
 102  103  #include <sys/fs/dv_node.h>     /* devfs_clean */
 103  104  
 104  105  /*
 105  106   * FMA header files
 106  107   */
 107  108  #include <sys/ddifm.h>
 108  109  #include <sys/fm/protocol.h>
 109  110  #include <sys/fm/util.h>
↓ open down ↓ 219 lines elided ↑ open up ↑
 329  330      int lun);
 330  331  static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
 331  332      int lun);
 332  333  static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
 333  334  static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
 334  335  
 335  336  static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
 336  337      int *lun);
 337  338  static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
 338  339  
 339      -static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask,
 340      -    uint8_t phy);
 341      -static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
 342      -    uint64_t wwid);
 343      -static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
 344      -    uint64_t wwid);
      340 +static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt,
      341 +    mptsas_phymask_t phymask, uint8_t phy);
      342 +static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt,
      343 +    mptsas_phymask_t phymask, uint64_t wwid);
      344 +static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
      345 +    mptsas_phymask_t phymask, uint64_t wwid);
 345  346  
 346  347  static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
 347  348      uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
 348  349  
 349  350  static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
 350  351      uint16_t *handle, mptsas_target_t **pptgt);
 351  352  static void mptsas_update_phymask(mptsas_t *mpt);
 352  353  
 353  354  static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
 354  355      uint32_t *status, uint8_t cmd);
↓ open down ↓ 45 lines elided ↑ open up ↑
 400  401  static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
 401  402      int mode, int *rval);
 402  403  static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
 403  404      int mode, int *rval);
 404  405  static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
 405  406      int mode, int *rval);
 406  407  static void mptsas_record_event(void *args);
 407  408  static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
 408  409      int mode);
 409  410  
 410      -static void mptsas_hash_init(mptsas_hash_table_t *hashtab);
 411      -static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen);
 412      -static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data);
 413      -static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
 414      -    mptsas_phymask_t key2);
 415      -static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
 416      -    mptsas_phymask_t key2);
 417      -static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos);
 418      -
 419      -mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t,
      411 +mptsas_target_t *mptsas_tgt_alloc(mptsas_t *, uint16_t, uint64_t,
 420  412      uint32_t, mptsas_phymask_t, uint8_t);
 421      -static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab,
 422      -    mptsas_smp_t *data);
 423      -static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
 424      -    mptsas_phymask_t phymask);
 425      -static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t);
 426      -static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t);
      413 +static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
 427  414  static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
 428  415      dev_info_t **smp_dip);
 429  416  
 430  417  /*
 431  418   * Power management functions
 432  419   */
 433  420  static int mptsas_get_pci_cap(mptsas_t *mpt);
 434  421  static int mptsas_init_pm(mptsas_t *mpt);
 435  422  
 436  423  /*
↓ open down ↓ 251 lines elided ↑ open up ↑
 688  675  int
 689  676  _info(struct modinfo *modinfop)
 690  677  {
 691  678          /* CONSTCOND */
 692  679          ASSERT(NO_COMPETING_THREADS);
 693  680          NDBG0(("mptsas _info"));
 694  681  
 695  682          return (mod_info(&modlinkage, modinfop));
 696  683  }
 697  684  
      685 +static int
      686 +mptsas_target_eval_devhdl(const void *op, void *arg)
      687 +{
      688 +        uint16_t dh = *(uint16_t *)arg;
      689 +        const mptsas_target_t *tp = op;
 698  690  
      691 +        return ((int)tp->m_devhdl - (int)dh);
      692 +}
      693 +
 699  694  static int
      695 +mptsas_target_eval_slot(const void *op, void *arg)
      696 +{
      697 +        mptsas_led_control_t *lcp = arg;
      698 +        const mptsas_target_t *tp = op;
      699 +
      700 +        if (tp->m_enclosure != lcp->Enclosure)
      701 +                return ((int)tp->m_enclosure - (int)lcp->Enclosure);
      702 +
      703 +        return ((int)tp->m_slot_num - (int)lcp->Slot);
      704 +}
      705 +
      706 +static int
      707 +mptsas_target_eval_nowwn(const void *op, void *arg)
      708 +{
      709 +        uint8_t phy = *(uint8_t *)arg;
      710 +        const mptsas_target_t *tp = op;
      711 +
      712 +        if (tp->m_addr.mta_wwn != 0)
      713 +                return (-1);
      714 +
      715 +        return ((int)tp->m_phynum - (int)phy);
      716 +}
      717 +
      718 +static int
      719 +mptsas_smp_eval_devhdl(const void *op, void *arg)
      720 +{
      721 +        uint16_t dh = *(uint16_t *)arg;
      722 +        const mptsas_smp_t *sp = op;
      723 +
      724 +        return ((int)sp->m_devhdl - (int)dh);
      725 +}
      726 +
      727 +static uint64_t
      728 +mptsas_target_addr_hash(const void *tp)
      729 +{
      730 +        const mptsas_target_addr_t *tap = tp;
      731 +
      732 +        return ((tap->mta_wwn & 0xffffffffffffULL) |
      733 +            ((uint64_t)tap->mta_phymask << 48));
      734 +}
      735 +
      736 +static int
      737 +mptsas_target_addr_cmp(const void *a, const void *b)
      738 +{
      739 +        const mptsas_target_addr_t *aap = a;
      740 +        const mptsas_target_addr_t *bap = b;
      741 +
      742 +        if (aap->mta_wwn < bap->mta_wwn)
      743 +                return (-1);
      744 +        if (aap->mta_wwn > bap->mta_wwn)
      745 +                return (1);
      746 +        return ((int)bap->mta_phymask - (int)aap->mta_phymask);
      747 +}
      748 +
      749 +static void
      750 +mptsas_target_free(void *op)
      751 +{
      752 +        kmem_free(op, sizeof (mptsas_target_t));
      753 +}
      754 +
      755 +static void
      756 +mptsas_smp_free(void *op)
      757 +{
      758 +        kmem_free(op, sizeof (mptsas_smp_t));
      759 +}
      760 +
      761 +static void
      762 +mptsas_destroy_hashes(mptsas_t *mpt)
      763 +{
      764 +        mptsas_target_t *tp;
      765 +        mptsas_smp_t *sp;
      766 +
      767 +        for (tp = refhash_first(mpt->m_targets); tp != NULL;
      768 +            tp = refhash_next(mpt->m_targets, tp)) {
      769 +                refhash_remove(mpt->m_targets, tp);
      770 +        }
      771 +        for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
      772 +            sp = refhash_next(mpt->m_smp_targets, sp)) {
      773 +                refhash_remove(mpt->m_smp_targets, sp);
      774 +        }
      775 +        refhash_destroy(mpt->m_targets);
      776 +        refhash_destroy(mpt->m_smp_targets);
      777 +        mpt->m_targets = NULL;
      778 +        mpt->m_smp_targets = NULL;
      779 +}
      780 +
      781 +static int
 700  782  mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 701  783  {
 702  784          dev_info_t              *pdip;
 703  785          mptsas_t                *mpt;
 704  786          scsi_hba_tran_t         *hba_tran;
 705  787          char                    *iport = NULL;
 706  788          char                    phymask[MPTSAS_MAX_PHYS];
 707  789          mptsas_phymask_t        phy_mask = 0;
 708  790          int                     dynamic_port = 0;
 709  791          uint32_t                page_address;
↓ open down ↓ 687 lines elided ↑ open up ↑
1397 1479                  /* deallocate in reverse order */
1398 1480                  mptsas_cache_destroy(mpt);
1399 1481  
1400 1482                  if (smp_attach_setup) {
1401 1483                          mptsas_smp_teardown(mpt);
1402 1484                  }
1403 1485                  if (hba_attach_setup) {
1404 1486                          mptsas_hba_teardown(mpt);
1405 1487                  }
1406 1488  
     1489 +                if (mpt->m_targets)
     1490 +                        refhash_destroy(mpt->m_targets);
     1491 +                if (mpt->m_smp_targets)
     1492 +                        refhash_destroy(mpt->m_smp_targets);
     1493 +
1407 1494                  if (mpt->m_active) {
1408      -                        mptsas_hash_uninit(&mpt->m_active->m_smptbl,
1409      -                            sizeof (mptsas_smp_t));
1410      -                        mptsas_hash_uninit(&mpt->m_active->m_tgttbl,
1411      -                            sizeof (mptsas_target_t));
1412 1495                          mptsas_free_active_slots(mpt);
1413 1496                  }
1414 1497                  if (intr_added) {
1415 1498                          mptsas_unregister_intrs(mpt);
1416 1499                  }
1417 1500  
1418 1501                  if (doneq_thread_create) {
1419 1502                          mutex_enter(&mpt->m_doneq_mutex);
1420 1503                          doneq_thread_num = mpt->m_doneq_thread_n;
1421 1504                          for (j = 0; j < mpt->m_doneq_thread_n; j++) {
↓ open down ↓ 412 lines elided ↑ open up ↑
1834 1917                          mutex_enter(&mptsas_global_mutex);
1835 1918                  }
1836 1919          }
1837 1920          mutex_exit(&mptsas_global_mutex);
1838 1921  
1839 1922          /*
1840 1923           * Delete Phy stats
1841 1924           */
1842 1925          mptsas_destroy_phy_stats(mpt);
1843 1926  
     1927 +        mptsas_destroy_hashes(mpt);
     1928 +
1844 1929          /*
1845 1930           * Delete nt_active.
1846 1931           */
1847 1932          mutex_enter(&mpt->m_mutex);
1848      -        mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t));
1849      -        mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t));
1850 1933          mptsas_free_active_slots(mpt);
1851 1934          mutex_exit(&mpt->m_mutex);
1852 1935  
1853 1936          /* deallocate everything that was allocated in mptsas_attach */
1854 1937          mptsas_cache_destroy(mpt);
1855 1938  
1856 1939          mptsas_hba_fini(mpt);
1857 1940          mptsas_cfg_fini(mpt);
1858 1941  
1859 1942          /* Lower the power informing PM Framework */
↓ open down ↓ 240 lines elided ↑ open up ↑
2100 2183          mpt->m_smptran->smp_tran_start = mptsas_smp_start;
2101 2184          if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) {
2102 2185                  mptsas_log(mpt, CE_WARN, "smp attach setup failed");
2103 2186                  smp_hba_tran_free(mpt->m_smptran);
2104 2187                  mpt->m_smptran = NULL;
2105 2188                  return (FALSE);
2106 2189          }
2107 2190          /*
2108 2191           * Initialize smp hash table
2109 2192           */
2110      -        mptsas_hash_init(&mpt->m_active->m_smptbl);
     2193 +        mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT,
     2194 +            mptsas_target_addr_hash, mptsas_target_addr_cmp,
     2195 +            mptsas_smp_free, sizeof (mptsas_smp_t),
     2196 +            offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr),
     2197 +            KM_SLEEP);
2111 2198          mpt->m_smp_devhdl = 0xFFFF;
2112 2199  
2113 2200          return (TRUE);
2114 2201  }
2115 2202  
2116 2203  static void
2117 2204  mptsas_smp_teardown(mptsas_t *mpt)
2118 2205  {
2119 2206          (void) smp_hba_detach(mpt->m_dip);
2120 2207          if (mpt->m_smptran != NULL) {
↓ open down ↓ 622 lines elided ↑ open up ↑
2743 2830           * if needed by this HBA.  Add revised flow-control and queue
2744 2831           * properties for child here, if desired and if you can tell they
2745 2832           * support tagged queueing by now.
2746 2833           */
2747 2834          mptsas_t                *mpt;
2748 2835          int                     lun = sd->sd_address.a_lun;
2749 2836          mdi_pathinfo_t          *pip = NULL;
2750 2837          mptsas_tgt_private_t    *tgt_private = NULL;
2751 2838          mptsas_target_t         *ptgt = NULL;
2752 2839          char                    *psas_wwn = NULL;
2753      -        int                     phymask = 0;
     2840 +        mptsas_phymask_t        phymask = 0;
2754 2841          uint64_t                sas_wwn = 0;
     2842 +        mptsas_target_addr_t    addr;
2755 2843          mpt = SDEV2MPT(sd);
2756 2844  
2757 2845          ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
2758 2846  
2759 2847          NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
2760 2848              (void *)hba_dip, (void *)tgt_dip, lun));
2761 2849  
2762 2850          if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
2763 2851                  (void) ndi_merge_node(tgt_dip, mptsas_name_child);
2764 2852                  ddi_set_name_addr(tgt_dip, NULL);
2765 2853                  return (DDI_FAILURE);
2766 2854          }
2767 2855          /*
2768 2856           * phymask is 0 means the virtual port for RAID
2769 2857           */
2770      -        phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
     2858 +        phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
2771 2859              "phymask", 0);
2772 2860          if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2773 2861                  if ((pip = (void *)(sd->sd_private)) == NULL) {
2774 2862                          /*
2775 2863                           * Very bad news if this occurs. Somehow scsi_vhci has
2776 2864                           * lost the pathinfo node for this target.
2777 2865                           */
2778 2866                          return (DDI_NOT_WELL_FORMED);
2779 2867                  }
2780 2868  
↓ open down ↓ 17 lines elided ↑ open up ↑
2798 2886                      DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
2799 2887                      DDI_PROP_SUCCESS) {
2800 2888                          if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2801 2889                                  sas_wwn = 0;
2802 2890                          }
2803 2891                          ddi_prop_free(psas_wwn);
2804 2892                  } else {
2805 2893                          sas_wwn = 0;
2806 2894                  }
2807 2895          }
     2896 +
2808 2897          ASSERT((sas_wwn != 0) || (phymask != 0));
     2898 +        addr.mta_wwn = sas_wwn;
     2899 +        addr.mta_phymask = phymask;
2809 2900          mutex_enter(&mpt->m_mutex);
2810      -        ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask);
     2901 +        ptgt = refhash_lookup(mpt->m_targets, &addr);
2811 2902          mutex_exit(&mpt->m_mutex);
2812 2903          if (ptgt == NULL) {
2813 2904                  mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
2814 2905                      "gone already! phymask:%x, saswwn %"PRIx64, phymask,
2815 2906                      sas_wwn);
2816 2907                  return (DDI_FAILURE);
2817 2908          }
2818 2909          if (hba_tran->tran_tgt_private == NULL) {
2819 2910                  tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
2820 2911                      KM_SLEEP);
↓ open down ↓ 410 lines elided ↑ open up ↑
3231 3322                                  mptsas_doneq_empty(mpt);
3232 3323                          }
3233 3324                  }
3234 3325          }
3235 3326          return (rval);
3236 3327  }
3237 3328  
3238 3329  int
3239 3330  mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3240 3331  {
3241      -        mptsas_slots_t  *slots;
3242      -        int             slot;
3243      -        mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
     3332 +        mptsas_slots_t *slots = mpt->m_active;
     3333 +        uint_t slot, start_rotor;
     3334 +        mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3244 3335  
3245      -        ASSERT(mutex_owned(&mpt->m_mutex));
3246      -        slots = mpt->m_active;
     3336 +        ASSERT(MUTEX_HELD(&mpt->m_mutex));
3247 3337  
3248 3338          /*
3249 3339           * Account for reserved TM request slot and reserved SMID of 0.
3250 3340           */
3251      -        ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2));
     3341 +        ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2));
3252 3342  
3253 3343          /*
3254      -         * m_tags is equivalent to the SMID when sending requests.  Since the
3255      -         * SMID cannot be 0, start out at one if rolling over past the size
3256      -         * of the request queue depth.  Also, don't use the last SMID, which is
3257      -         * reserved for TM requests.
     3344 +         * Find the next available slot, beginning at m_rotor.  If no slot is
     3345 +         * available, we'll return FALSE to indicate that.  This mechanism
     3346 +         * considers only the normal slots, not the reserved slot 0 nor the
     3347 +         * task management slot m_n_normal + 1.  The rotor is left to point to
     3348 +         * the normal slot after the one we select, unless we select the last
     3349 +         * normal slot in which case it returns to slot 1.
3258 3350           */
3259      -        slot = (slots->m_tags)++;
3260      -        if (slots->m_tags > slots->m_n_slots) {
3261      -                slots->m_tags = 1;
3262      -        }
     3351 +        start_rotor = slots->m_rotor;
     3352 +        do {
     3353 +                slot = slots->m_rotor++;
     3354 +                if (slots->m_rotor > slots->m_n_normal)
     3355 +                        slots->m_rotor = 1;
3263 3356  
3264      -alloc_tag:
3265      -        /* Validate tag, should never fail. */
3266      -        if (slots->m_slot[slot] == NULL) {
3267      -                /*
3268      -                 * Make sure SMID is not using reserved value of 0
3269      -                 * and the TM request slot.
3270      -                 */
3271      -                ASSERT((slot > 0) && (slot <= slots->m_n_slots));
3272      -                cmd->cmd_slot = slot;
3273      -                slots->m_slot[slot] = cmd;
3274      -                mpt->m_ncmds++;
     3357 +                if (slots->m_rotor == start_rotor)
     3358 +                        break;
     3359 +        } while (slots->m_slot[slot] != NULL);
3275 3360  
3276      -                /*
3277      -                 * only increment per target ncmds if this is not a
3278      -                 * command that has no target associated with it (i.e. a
3279      -                 * event acknoledgment)
3280      -                 */
3281      -                if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3282      -                        ptgt->m_t_ncmds++;
3283      -                }
3284      -                cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
     3361 +        if (slots->m_slot[slot] != NULL)
     3362 +                return (FALSE);
3285 3363  
3286      -                /*
3287      -                 * If initial timout is less than or equal to one tick, bump
3288      -                 * the timeout by a tick so that command doesn't timeout before
3289      -                 * its allotted time.
3290      -                 */
3291      -                if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
3292      -                        cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
3293      -                }
3294      -                return (TRUE);
3295      -        } else {
3296      -                int i;
     3364 +        ASSERT(slot != 0 && slot <= slots->m_n_normal);
3297 3365  
3298      -                /*
3299      -                 * If slot in use, scan until a free one is found. Don't use 0
3300      -                 * or final slot, which is reserved for TM requests.
3301      -                 */
3302      -                for (i = 0; i < slots->m_n_slots; i++) {
3303      -                        slot = slots->m_tags;
3304      -                        if (++(slots->m_tags) > slots->m_n_slots) {
3305      -                                slots->m_tags = 1;
3306      -                        }
3307      -                        if (slots->m_slot[slot] == NULL) {
3308      -                                NDBG22(("found free slot %d", slot));
3309      -                                goto alloc_tag;
3310      -                        }
3311      -                }
     3366 +        cmd->cmd_slot = slot;
     3367 +        slots->m_slot[slot] = cmd;
     3368 +        mpt->m_ncmds++;
     3369 +
     3370 +        /*
     3371 +         * only increment per target ncmds if this is not a
     3372 +         * command that has no target associated with it (i.e. a
     3373 +         * event acknoledgment)
     3374 +         */
     3375 +        if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
     3376 +                ptgt->m_t_ncmds++;
3312 3377          }
3313      -        return (FALSE);
     3378 +        cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
     3379 +
     3380 +        /*
     3381 +         * If initial timout is less than or equal to one tick, bump
     3382 +         * the timeout by a tick so that command doesn't timeout before
     3383 +         * its allotted time.
     3384 +         */
     3385 +        if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
     3386 +                cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
     3387 +        }
     3388 +        return (TRUE);
3314 3389  }
3315 3390  
3316 3391  /*
3317 3392   * prepare the pkt:
3318 3393   * the pkt may have been resubmitted or just reused so
3319 3394   * initialize some fields and do some checks.
3320 3395   */
3321 3396  static int
3322 3397  mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3323 3398  {
↓ open down ↓ 1320 lines elided ↑ open up ↑
4644 4719          ASSERT(mutex_owned(&mpt->m_mutex));
4645 4720  
4646 4721          scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4647 4722          SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4648 4723  
4649 4724          /*
4650 4725           * This is a success reply so just complete the IO.  First, do a sanity
4651 4726           * check on the SMID.  The final slot is used for TM requests, which
4652 4727           * would not come into this reply handler.
4653 4728           */
4654      -        if ((SMID == 0) || (SMID > slots->m_n_slots)) {
     4729 +        if ((SMID == 0) || (SMID > slots->m_n_normal)) {
4655 4730                  mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4656 4731                      SMID);
4657 4732                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4658 4733                  return;
4659 4734          }
4660 4735  
4661 4736          cmd = slots->m_slot[SMID];
4662 4737  
4663 4738          /*
4664 4739           * print warning and return if the slot is empty
↓ open down ↓ 82 lines elided ↑ open up ↑
4747 4822          /*
4748 4823           * don't get slot information and command for events since these values
4749 4824           * don't exist
4750 4825           */
4751 4826          if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
4752 4827              (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
4753 4828                  /*
4754 4829                   * This could be a TM reply, which use the last allocated SMID,
4755 4830                   * so allow for that.
4756 4831                   */
4757      -                if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) {
     4832 +                if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
4758 4833                          mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
4759 4834                              "%d\n", SMID);
4760 4835                          ddi_fm_service_impact(mpt->m_dip,
4761 4836                              DDI_SERVICE_UNAFFECTED);
4762 4837                          return;
4763 4838                  }
4764 4839  
4765 4840                  cmd = slots->m_slot[SMID];
4766 4841  
4767 4842                  /*
↓ open down ↓ 296 lines elided ↑ open up ↑
5064 5139                              sizeof (mptsas_topo_change_list_t),
5065 5140                              KM_NOSLEEP);
5066 5141                          if (topo_node == NULL) {
5067 5142                                  mptsas_log(mpt, CE_NOTE, "No memory"
5068 5143                                      "resource for handle SAS dynamic"
5069 5144                                      "reconfigure.\n");
5070 5145                                  break;
5071 5146                          }
5072 5147                          topo_node->mpt = mpt;
5073 5148                          topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5074      -                        topo_node->un.phymask = ptgt->m_phymask;
     5149 +                        topo_node->un.phymask = ptgt->m_addr.mta_phymask;
5075 5150                          topo_node->devhdl = ptgt->m_devhdl;
5076 5151                          topo_node->object = (void *)ptgt;
5077 5152                          topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5078 5153  
5079 5154                          if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5080 5155                              mptsas_handle_dr,
5081 5156                              (void *)topo_node,
5082 5157                              DDI_NOSLEEP)) != DDI_SUCCESS) {
5083 5158                                  mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5084 5159                                      "for handle SAS dynamic reconfigure"
↓ open down ↓ 45 lines elided ↑ open up ↑
5130 5205                  case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5131 5206                          pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5132 5207                          mptsas_set_pkt_reason(mpt,
5133 5208                              cmd, CMD_TERMINATED, STAT_TERMINATED);
5134 5209                          break;
5135 5210                  case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5136 5211                  case MPI2_IOCSTATUS_BUSY:
5137 5212                          /*
5138 5213                           * set throttles to drain
5139 5214                           */
5140      -                        ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5141      -                            &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
5142      -                        while (ptgt != NULL) {
     5215 +                        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     5216 +                            ptgt = refhash_next(mpt->m_targets, ptgt)) {
5143 5217                                  mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5144      -
5145      -                                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5146      -                                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
5147 5218                          }
5148 5219  
5149 5220                          /*
5150 5221                           * retry command
5151 5222                           */
5152 5223                          cmd->cmd_flags |= CFLAG_RETRY;
5153 5224                          cmd->cmd_pkt_flags |= FLAG_HEAD;
5154 5225  
5155 5226                          (void) mptsas_accept_pkt(mpt, cmd);
5156 5227                          break;
↓ open down ↓ 670 lines elided ↑ open up ↑
5827 5898          case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5828 5899          {
5829 5900                  char *phy_mask_name;
5830 5901                  mptsas_phymask_t phymask = 0;
5831 5902  
5832 5903                  if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5833 5904                          /*
5834 5905                           * Get latest RAID info.
5835 5906                           */
5836 5907                          (void) mptsas_get_raid_info(mpt);
5837      -                        ptgt = mptsas_search_by_devhdl(
5838      -                            &mpt->m_active->m_tgttbl, topo_node->devhdl);
     5908 +                        ptgt = refhash_linear_search(mpt->m_targets,
     5909 +                            mptsas_target_eval_devhdl, &topo_node->devhdl);
5839 5910                          if (ptgt == NULL)
5840 5911                                  break;
5841 5912                  } else {
5842 5913                          ptgt = (void *)topo_node->object;
5843 5914                  }
5844 5915  
5845 5916                  if (ptgt == NULL) {
5846 5917                          /*
5847 5918                           * If a Phys Disk was deleted, RAID info needs to be
5848 5919                           * updated to reflect the new topology.
↓ open down ↓ 28 lines elided ↑ open up ↑
5877 5948                                  return;
5878 5949                          }
5879 5950                  }
5880 5951  
5881 5952                  ASSERT(ptgt->m_devhdl == topo_node->devhdl);
5882 5953  
5883 5954                  mutex_exit(&mpt->m_mutex);
5884 5955                  flags = topo_node->flags;
5885 5956  
5886 5957                  if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
5887      -                        phymask = ptgt->m_phymask;
     5958 +                        phymask = ptgt->m_addr.mta_phymask;
5888 5959                          phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
5889 5960                          (void) sprintf(phy_mask_name, "%x", phymask);
5890 5961                          parent = scsi_hba_iport_find(mpt->m_dip,
5891 5962                              phy_mask_name);
5892 5963                          kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
5893 5964                          if (parent == NULL) {
5894 5965                                  mptsas_log(mpt, CE_WARN, "Failed to find a "
5895 5966                                      "iport for PD, should not happen!");
5896 5967                                  mutex_enter(&mpt->m_mutex);
5897 5968                                  break;
↓ open down ↓ 18 lines elided ↑ open up ↑
5916 5987                          ndi_devi_exit(parent, circ1);
5917 5988                          ndi_devi_exit(scsi_vhci_dip, circ);
5918 5989  
5919 5990                          /*
5920 5991                           * Add parent's props for SMHBA support
5921 5992                           */
5922 5993                          if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
5923 5994                                  bzero(attached_wwnstr,
5924 5995                                      sizeof (attached_wwnstr));
5925 5996                                  (void) sprintf(attached_wwnstr, "w%016"PRIx64,
5926      -                                    ptgt->m_sas_wwn);
     5997 +                                    ptgt->m_addr.mta_wwn);
5927 5998                                  if (ddi_prop_update_string(DDI_DEV_T_NONE,
5928 5999                                      parent,
5929 6000                                      SCSI_ADDR_PROP_ATTACHED_PORT,
5930 6001                                      attached_wwnstr)
5931 6002                                      != DDI_PROP_SUCCESS) {
5932 6003                                          (void) ddi_prop_remove(DDI_DEV_T_NONE,
5933 6004                                              parent,
5934 6005                                              SCSI_ADDR_PROP_ATTACHED_PORT);
5935 6006                                          mptsas_log(mpt, CE_WARN, "Failed to"
5936 6007                                              "attached-port props");
↓ open down ↓ 37 lines elided ↑ open up ↑
5974 6045                                              "mptsas virtual-port"
5975 6046                                              "port prop update failed");
5976 6047                                          return;
5977 6048                                  }
5978 6049                          }
5979 6050                  }
5980 6051                  mutex_enter(&mpt->m_mutex);
5981 6052  
5982 6053                  NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
5983 6054                      "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
5984      -                    ptgt->m_phymask));
     6055 +                    ptgt->m_addr.mta_phymask));
5985 6056                  break;
5986 6057          }
5987 6058          case MPTSAS_DR_EVENT_OFFLINE_TARGET:
5988 6059          {
5989      -                mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl;
5990 6060                  devhdl = topo_node->devhdl;
5991      -                ptgt = mptsas_search_by_devhdl(tgttbl, devhdl);
     6061 +                ptgt = refhash_linear_search(mpt->m_targets,
     6062 +                    mptsas_target_eval_devhdl, &devhdl);
5992 6063                  if (ptgt == NULL)
5993 6064                          break;
5994 6065  
5995      -                sas_wwn = ptgt->m_sas_wwn;
     6066 +                sas_wwn = ptgt->m_addr.mta_wwn;
5996 6067                  phy = ptgt->m_phynum;
5997 6068  
5998 6069                  addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
5999 6070  
6000 6071                  if (sas_wwn) {
6001 6072                          (void) sprintf(addr, "w%016"PRIx64, sas_wwn);
6002 6073                  } else {
6003 6074                          (void) sprintf(addr, "p%x", phy);
6004 6075                  }
6005 6076                  ASSERT(ptgt->m_devhdl == devhdl);
↓ open down ↓ 7 lines elided ↑ open up ↑
6013 6084                           */
6014 6085                          (void) mptsas_get_raid_info(mpt);
6015 6086                  }
6016 6087                  /*
6017 6088                   * Abort all outstanding command on the device
6018 6089                   */
6019 6090                  rval = mptsas_do_scsi_reset(mpt, devhdl);
6020 6091                  if (rval) {
6021 6092                          NDBG20(("mptsas%d handle_topo_change to reset target "
6022 6093                              "before offline devhdl:%x, phymask:%x, rval:%x",
6023      -                            mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask,
6024      -                            rval));
     6094 +                            mpt->m_instance, ptgt->m_devhdl,
     6095 +                            ptgt->m_addr.mta_phymask, rval));
6025 6096                  }
6026 6097  
6027 6098                  mutex_exit(&mpt->m_mutex);
6028 6099  
6029 6100                  ndi_devi_enter(scsi_vhci_dip, &circ);
6030 6101                  ndi_devi_enter(parent, &circ1);
6031 6102                  rval = mptsas_offline_target(parent, addr);
6032 6103                  ndi_devi_exit(parent, circ1);
6033 6104                  ndi_devi_exit(scsi_vhci_dip, circ);
6034 6105                  NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
6035 6106                      "phymask:%x, rval:%x", mpt->m_instance,
6036      -                    ptgt->m_devhdl, ptgt->m_phymask, rval));
     6107 +                    ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval));
6037 6108  
6038 6109                  kmem_free(addr, SCSI_MAXNAMELEN);
6039 6110  
6040 6111                  /*
6041 6112                   * Clear parent's props for SMHBA support
6042 6113                   */
6043 6114                  flags = topo_node->flags;
6044 6115                  if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6045 6116                          bzero(attached_wwnstr, sizeof (attached_wwnstr));
6046 6117                          if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
↓ open down ↓ 22 lines elided ↑ open up ↑
6069 6140                                  mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6070 6141                                      "prop update failed");
6071 6142                                  break;
6072 6143                          }
6073 6144                  }
6074 6145  
6075 6146                  mutex_enter(&mpt->m_mutex);
6076 6147                  ptgt->m_led_status = 0;
6077 6148                  (void) mptsas_flush_led_status(mpt, ptgt);
6078 6149                  if (rval == DDI_SUCCESS) {
6079      -                        mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6080      -                            ptgt->m_sas_wwn, ptgt->m_phymask);
     6150 +                        refhash_remove(mpt->m_targets, ptgt);
6081 6151                          ptgt = NULL;
6082 6152                  } else {
6083 6153                          /*
6084 6154                           * clean DR_INTRANSITION flag to allow I/O down to
6085 6155                           * PHCI driver since failover finished.
6086 6156                           * Invalidate the devhdl
6087 6157                           */
6088 6158                          ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6089 6159                          ptgt->m_tgt_unconfigured = 0;
6090 6160                          mutex_enter(&mpt->m_tx_waitq_mutex);
↓ open down ↓ 36 lines elided ↑ open up ↑
6127 6197                  rval = mptsas_free_devhdl(mpt, devhdl);
6128 6198                  NDBG20(("mptsas%d handle_topo_change to remove "
6129 6199                      "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6130 6200                      rval));
6131 6201                  break;
6132 6202          }
6133 6203          case MPTSAS_DR_EVENT_RECONFIG_SMP:
6134 6204          {
6135 6205                  mptsas_smp_t smp;
6136 6206                  dev_info_t *smpdip;
6137      -                mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6138 6207  
6139 6208                  devhdl = topo_node->devhdl;
6140 6209  
6141 6210                  page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6142 6211                      MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6143 6212                  rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6144 6213                  if (rval != DDI_SUCCESS) {
6145 6214                          mptsas_log(mpt, CE_WARN, "failed to online smp, "
6146 6215                              "handle %x", devhdl);
6147 6216                          return;
6148 6217                  }
6149 6218  
6150      -                psmp = mptsas_smp_alloc(smptbl, &smp);
     6219 +                psmp = mptsas_smp_alloc(mpt, &smp);
6151 6220                  if (psmp == NULL) {
6152 6221                          return;
6153 6222                  }
6154 6223  
6155 6224                  mutex_exit(&mpt->m_mutex);
6156 6225                  ndi_devi_enter(parent, &circ1);
6157 6226                  (void) mptsas_online_smp(parent, psmp, &smpdip);
6158 6227                  ndi_devi_exit(parent, circ1);
6159 6228  
6160 6229                  mutex_enter(&mpt->m_mutex);
6161 6230                  break;
6162 6231          }
6163 6232          case MPTSAS_DR_EVENT_OFFLINE_SMP:
6164 6233          {
6165      -                mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6166 6234                  devhdl = topo_node->devhdl;
6167 6235                  uint32_t dev_info;
6168 6236  
6169      -                psmp = mptsas_search_by_devhdl(smptbl, devhdl);
     6237 +                psmp = refhash_linear_search(mpt->m_smp_targets,
     6238 +                    mptsas_smp_eval_devhdl, &devhdl);
6170 6239                  if (psmp == NULL)
6171 6240                          break;
6172 6241                  /*
6173 6242                   * The mptsas_smp_t data is released only if the dip is offlined
6174 6243                   * successfully.
6175 6244                   */
6176 6245                  mutex_exit(&mpt->m_mutex);
6177 6246  
6178 6247                  ndi_devi_enter(parent, &circ1);
6179 6248                  rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
↓ open down ↓ 35 lines elided ↑ open up ↑
6215 6284                                  mptsas_log(mpt, CE_WARN, "mptsas attached port "
6216 6285                                      "prop update failed");
6217 6286                                  return;
6218 6287                          }
6219 6288                  }
6220 6289  
6221 6290                  mutex_enter(&mpt->m_mutex);
6222 6291                  NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6223 6292                      "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6224 6293                  if (rval == DDI_SUCCESS) {
6225      -                        mptsas_smp_free(smptbl, psmp->m_sasaddr,
6226      -                            psmp->m_phymask);
     6294 +                        refhash_remove(mpt->m_smp_targets, psmp);
6227 6295                  } else {
6228 6296                          psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6229 6297                  }
6230 6298  
6231 6299                  bzero(attached_wwnstr, sizeof (attached_wwnstr));
6232 6300  
6233 6301                  break;
6234 6302          }
6235 6303          default:
6236 6304                  return;
↓ open down ↓ 138 lines elided ↑ open up ↑
6375 6443                  uint8_t                         phystatus, physport, state, i;
6376 6444                  uint8_t                         start_phy_num, link_rate;
6377 6445                  uint16_t                        dev_handle, reason_code;
6378 6446                  uint16_t                        enc_handle, expd_handle;
6379 6447                  char                            string[80], curr[80], prev[80];
6380 6448                  mptsas_topo_change_list_t       *topo_head = NULL;
6381 6449                  mptsas_topo_change_list_t       *topo_tail = NULL;
6382 6450                  mptsas_topo_change_list_t       *topo_node = NULL;
6383 6451                  mptsas_target_t                 *ptgt;
6384 6452                  mptsas_smp_t                    *psmp;
6385      -                mptsas_hash_table_t             *tgttbl, *smptbl;
6386 6453                  uint8_t                         flags = 0, exp_flag;
6387 6454                  smhba_info_t                    *pSmhba = NULL;
6388 6455  
6389 6456                  NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6390 6457  
6391      -                tgttbl = &mpt->m_active->m_tgttbl;
6392      -                smptbl = &mpt->m_active->m_smptbl;
6393      -
6394 6458                  sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6395 6459                      eventreply->EventData;
6396 6460  
6397 6461                  enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6398 6462                      &sas_topo_change_list->EnclosureHandle);
6399 6463                  expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6400 6464                      &sas_topo_change_list->ExpanderDevHandle);
6401 6465                  num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6402 6466                      &sas_topo_change_list->NumEntries);
6403 6467                  start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
↓ open down ↓ 25 lines elided ↑ open up ↑
6429 6493                                  if (topo_head == NULL) {
6430 6494                                          topo_head = topo_tail = topo_node;
6431 6495                                  } else {
6432 6496                                          topo_tail->next = topo_node;
6433 6497                                          topo_tail = topo_node;
6434 6498                                  }
6435 6499                                  break;
6436 6500                          case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6437 6501                                  (void) sprintf(string, " not responding, "
6438 6502                                      "removed");
6439      -                                psmp = mptsas_search_by_devhdl(smptbl,
6440      -                                    expd_handle);
     6503 +                                psmp = refhash_linear_search(mpt->m_smp_targets,
     6504 +                                    mptsas_smp_eval_devhdl, &expd_handle);
6441 6505                                  if (psmp == NULL)
6442 6506                                          break;
6443 6507  
6444 6508                                  topo_node = kmem_zalloc(
6445 6509                                      sizeof (mptsas_topo_change_list_t),
6446 6510                                      KM_SLEEP);
6447 6511                                  topo_node->mpt = mpt;
6448      -                                topo_node->un.phymask = psmp->m_phymask;
     6512 +                                topo_node->un.phymask =
     6513 +                                    psmp->m_addr.mta_phymask;
6449 6514                                  topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6450 6515                                  topo_node->devhdl = expd_handle;
6451 6516                                  topo_node->flags = flags;
6452 6517                                  topo_node->object = NULL;
6453 6518                                  if (topo_head == NULL) {
6454 6519                                          topo_head = topo_tail = topo_node;
6455 6520                                  } else {
6456 6521                                          topo_tail->next = topo_node;
6457 6522                                          topo_tail = topo_node;
6458 6523                                  }
↓ open down ↓ 130 lines elided ↑ open up ↑
6589 6654                                      MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6590 6655                                  if (flags ==
6591 6656                                      MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6592 6657                                          flags = exp_flag;
6593 6658                                  }
6594 6659                                  /*
6595 6660                                   * Target device is removed from the system
6596 6661                                   * Before the device is really offline from
6597 6662                                   * from system.
6598 6663                                   */
6599      -                                ptgt = mptsas_search_by_devhdl(tgttbl,
6600      -                                    dev_handle);
     6664 +                                ptgt = refhash_linear_search(mpt->m_targets,
     6665 +                                    mptsas_target_eval_devhdl, &dev_handle);
6601 6666                                  /*
6602 6667                                   * If ptgt is NULL here, it means that the
6603 6668                                   * DevHandle is not in the hash table.  This is
6604 6669                                   * reasonable sometimes.  For example, if a
6605 6670                                   * disk was pulled, then added, then pulled
6606 6671                                   * again, the disk will not have been put into
6607 6672                                   * the hash table because the add event will
6608 6673                                   * have an invalid phymask.  BUT, this does not
6609 6674                                   * mean that the DevHandle is invalid.  The
6610 6675                                   * controller will still have a valid DevHandle
↓ open down ↓ 31 lines elided ↑ open up ↑
6642 6707                                   * context.
6643 6708                                   */
6644 6709                                  mutex_enter(&mpt->m_tx_waitq_mutex);
6645 6710                                  ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6646 6711                                  mutex_exit(&mpt->m_tx_waitq_mutex);
6647 6712  
6648 6713                                  topo_node = kmem_zalloc(
6649 6714                                      sizeof (mptsas_topo_change_list_t),
6650 6715                                      KM_SLEEP);
6651 6716                                  topo_node->mpt = mpt;
6652      -                                topo_node->un.phymask = ptgt->m_phymask;
     6717 +                                topo_node->un.phymask =
     6718 +                                    ptgt->m_addr.mta_phymask;
6653 6719                                  topo_node->event =
6654 6720                                      MPTSAS_DR_EVENT_OFFLINE_TARGET;
6655 6721                                  topo_node->devhdl = dev_handle;
6656 6722                                  topo_node->flags = flags;
6657 6723                                  topo_node->object = NULL;
6658 6724                                  if (topo_head == NULL) {
6659 6725                                          topo_head = topo_tail = topo_node;
6660 6726                                  } else {
6661 6727                                          topo_tail->next = topo_node;
6662 6728                                          topo_tail = topo_node;
↓ open down ↓ 139 lines elided ↑ open up ↑
6802 6868                  }
6803 6869                  break;
6804 6870          }
6805 6871          case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6806 6872          {
6807 6873                  Mpi2EventDataIrConfigChangeList_t       *irChangeList;
6808 6874                  mptsas_topo_change_list_t               *topo_head = NULL;
6809 6875                  mptsas_topo_change_list_t               *topo_tail = NULL;
6810 6876                  mptsas_topo_change_list_t               *topo_node = NULL;
6811 6877                  mptsas_target_t                         *ptgt;
6812      -                mptsas_hash_table_t                     *tgttbl;
6813 6878                  uint8_t                                 num_entries, i, reason;
6814 6879                  uint16_t                                volhandle, diskhandle;
6815 6880  
6816 6881                  irChangeList = (pMpi2EventDataIrConfigChangeList_t)
6817 6882                      eventreply->EventData;
6818 6883                  num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6819 6884                      &irChangeList->NumElements);
6820 6885  
6821      -                tgttbl = &mpt->m_active->m_tgttbl;
6822      -
6823 6886                  NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
6824 6887                      mpt->m_instance));
6825 6888  
6826 6889                  for (i = 0; i < num_entries; i++) {
6827 6890                          reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
6828 6891                              &irChangeList->ConfigElement[i].ReasonCode);
6829 6892                          volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6830 6893                              &irChangeList->ConfigElement[i].VolDevHandle);
6831 6894                          diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6832 6895                              &irChangeList->ConfigElement[i].PhysDiskDevHandle);
↓ open down ↓ 23 lines elided ↑ open up ↑
6856 6919                                          topo_tail->next = topo_node;
6857 6920                                          topo_tail = topo_node;
6858 6921                                  }
6859 6922                                  break;
6860 6923                          }
6861 6924                          case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6862 6925                          case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6863 6926                          {
6864 6927                                  NDBG20(("mptsas %d volume deleted\n",
6865 6928                                      mpt->m_instance));
6866      -                                ptgt = mptsas_search_by_devhdl(tgttbl,
6867      -                                    volhandle);
     6929 +                                ptgt = refhash_linear_search(mpt->m_targets,
     6930 +                                    mptsas_target_eval_devhdl, &volhandle);
6868 6931                                  if (ptgt == NULL)
6869 6932                                          break;
6870 6933  
6871 6934                                  /*
6872 6935                                   * Clear any flags related to volume
6873 6936                                   */
6874 6937                                  (void) mptsas_delete_volume(mpt, volhandle);
6875 6938  
6876 6939                                  /*
6877 6940                                   * Update DR flag immediately avoid I/O failure
6878 6941                                   */
6879 6942                                  mutex_enter(&mpt->m_tx_waitq_mutex);
6880 6943                                  ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6881 6944                                  mutex_exit(&mpt->m_tx_waitq_mutex);
6882 6945  
6883 6946                                  topo_node = kmem_zalloc(
6884 6947                                      sizeof (mptsas_topo_change_list_t),
6885 6948                                      KM_SLEEP);
6886 6949                                  topo_node->mpt = mpt;
6887      -                                topo_node->un.phymask = ptgt->m_phymask;
     6950 +                                topo_node->un.phymask =
     6951 +                                    ptgt->m_addr.mta_phymask;
6888 6952                                  topo_node->event =
6889 6953                                      MPTSAS_DR_EVENT_OFFLINE_TARGET;
6890 6954                                  topo_node->devhdl = volhandle;
6891 6955                                  topo_node->flags =
6892 6956                                      MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6893 6957                                  topo_node->object = (void *)ptgt;
6894 6958                                  if (topo_head == NULL) {
6895 6959                                          topo_head = topo_tail = topo_node;
6896 6960                                  } else {
6897 6961                                          topo_tail->next = topo_node;
6898 6962                                          topo_tail = topo_node;
6899 6963                                  }
6900 6964                                  break;
6901 6965                          }
6902 6966                          case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6903 6967                          case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6904 6968                          {
6905      -                                ptgt = mptsas_search_by_devhdl(tgttbl,
6906      -                                    diskhandle);
     6969 +                                ptgt = refhash_linear_search(mpt->m_targets,
     6970 +                                    mptsas_target_eval_devhdl, &diskhandle);
6907 6971                                  if (ptgt == NULL)
6908 6972                                          break;
6909 6973  
6910 6974                                  /*
6911 6975                                   * Update DR flag immediately avoid I/O failure
6912 6976                                   */
6913 6977                                  mutex_enter(&mpt->m_tx_waitq_mutex);
6914 6978                                  ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6915 6979                                  mutex_exit(&mpt->m_tx_waitq_mutex);
6916 6980  
6917 6981                                  topo_node = kmem_zalloc(
6918 6982                                      sizeof (mptsas_topo_change_list_t),
6919 6983                                      KM_SLEEP);
6920 6984                                  topo_node->mpt = mpt;
6921      -                                topo_node->un.phymask = ptgt->m_phymask;
     6985 +                                topo_node->un.phymask =
     6986 +                                    ptgt->m_addr.mta_phymask;
6922 6987                                  topo_node->event =
6923 6988                                      MPTSAS_DR_EVENT_OFFLINE_TARGET;
6924 6989                                  topo_node->devhdl = diskhandle;
6925 6990                                  topo_node->flags =
6926 6991                                      MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6927 6992                                  topo_node->object = (void *)ptgt;
6928 6993                                  if (topo_head == NULL) {
6929 6994                                          topo_head = topo_tail = topo_node;
6930 6995                                  } else {
6931 6996                                          topo_tail->next = topo_node;
↓ open down ↓ 404 lines elided ↑ open up ↑
7336 7401                      "\tprimitive(0x%04x), phy(%d) complete\n",
7337 7402                      mpt->m_instance, primitive, phy_num));
7338 7403                  break;
7339 7404          }
7340 7405          case MPI2_EVENT_IR_VOLUME:
7341 7406          {
7342 7407                  Mpi2EventDataIrVolume_t         *irVolume;
7343 7408                  uint16_t                        devhandle;
7344 7409                  uint32_t                        state;
7345 7410                  int                             config, vol;
7346      -                mptsas_slots_t                  *slots = mpt->m_active;
7347 7411                  uint8_t                         found = FALSE;
7348 7412  
7349 7413                  irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
7350 7414                  state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7351 7415                      &irVolume->NewValue);
7352 7416                  devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7353 7417                      &irVolume->VolDevHandle);
7354 7418  
7355 7419                  NDBG20(("EVENT_IR_VOLUME event is received"));
7356 7420  
7357 7421                  /*
7358 7422                   * Get latest RAID info and then find the DevHandle for this
7359 7423                   * event in the configuration.  If the DevHandle is not found
7360 7424                   * just exit the event.
7361 7425                   */
7362 7426                  (void) mptsas_get_raid_info(mpt);
7363      -                for (config = 0; (config < slots->m_num_raid_configs) &&
     7427 +                for (config = 0; (config < mpt->m_num_raid_configs) &&
7364 7428                      (!found); config++) {
7365 7429                          for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
7366      -                                if (slots->m_raidconfig[config].m_raidvol[vol].
     7430 +                                if (mpt->m_raidconfig[config].m_raidvol[vol].
7367 7431                                      m_raidhandle == devhandle) {
7368 7432                                          found = TRUE;
7369 7433                                          break;
7370 7434                                  }
7371 7435                          }
7372 7436                  }
7373 7437                  if (!found) {
7374 7438                          break;
7375 7439                  }
7376 7440  
7377 7441                  switch (irVolume->ReasonCode) {
7378 7442                  case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
7379 7443                  {
7380 7444                          uint32_t i;
7381      -                        slots->m_raidconfig[config].m_raidvol[vol].m_settings =
     7445 +                        mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
7382 7446                              state;
7383 7447  
7384 7448                          i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
7385 7449                          mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
7386 7450                              ", auto-config of hot-swap drives is %s"
7387 7451                              ", write caching is %s"
7388 7452                              ", hot-spare pool mask is %02x\n",
7389 7453                              vol, state &
7390 7454                              MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
7391 7455                              ? "disabled" : "enabled",
↓ open down ↓ 2 lines elided ↑ open up ↑
7394 7458                              i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7395 7459                              ? "disabled" :
7396 7460                              i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7397 7461                              ? "enabled" :
7398 7462                              "incorrectly set",
7399 7463                              (state >> 16) & 0xff);
7400 7464                                  break;
7401 7465                  }
7402 7466                  case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7403 7467                  {
7404      -                        slots->m_raidconfig[config].m_raidvol[vol].m_state =
     7468 +                        mpt->m_raidconfig[config].m_raidvol[vol].m_state =
7405 7469                              (uint8_t)state;
7406 7470  
7407 7471                          mptsas_log(mpt, CE_NOTE,
7408 7472                              "Volume %d is now %s\n", vol,
7409 7473                              state == MPI2_RAID_VOL_STATE_OPTIMAL
7410 7474                              ? "optimal" :
7411 7475                              state == MPI2_RAID_VOL_STATE_DEGRADED
7412 7476                              ? "degraded" :
7413 7477                              state == MPI2_RAID_VOL_STATE_ONLINE
7414 7478                              ? "online" :
↓ open down ↓ 1 lines elided ↑ open up ↑
7416 7480                              ? "initializing" :
7417 7481                              state == MPI2_RAID_VOL_STATE_FAILED
7418 7482                              ? "failed" :
7419 7483                              state == MPI2_RAID_VOL_STATE_MISSING
7420 7484                              ? "missing" :
7421 7485                              "state unknown");
7422 7486                          break;
7423 7487                  }
7424 7488                  case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7425 7489                  {
7426      -                        slots->m_raidconfig[config].m_raidvol[vol].
     7490 +                        mpt->m_raidconfig[config].m_raidvol[vol].
7427 7491                              m_statusflags = state;
7428 7492  
7429 7493                          mptsas_log(mpt, CE_NOTE,
7430 7494                              " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7431 7495                              vol,
7432 7496                              state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7433 7497                              ? ", enabled" : ", disabled",
7434 7498                              state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7435 7499                              ? ", quiesced" : "",
7436 7500                              state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
↓ open down ↓ 128 lines elided ↑ open up ↑
7565 7629  static void
7566 7630  mptsas_restart_cmd(void *arg)
7567 7631  {
7568 7632          mptsas_t        *mpt = arg;
7569 7633          mptsas_target_t *ptgt = NULL;
7570 7634  
7571 7635          mutex_enter(&mpt->m_mutex);
7572 7636  
7573 7637          mpt->m_restart_cmd_timeid = 0;
7574 7638  
7575      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
7576      -            MPTSAS_HASH_FIRST);
7577      -        while (ptgt != NULL) {
     7639 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     7640 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
7578 7641                  if (ptgt->m_reset_delay == 0) {
7579 7642                          if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7580 7643                                  mptsas_set_throttle(mpt, ptgt,
7581 7644                                      MAX_THROTTLE);
7582 7645                          }
7583 7646                  }
7584      -
7585      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
7586      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
7587 7647          }
7588 7648          mptsas_restart_hba(mpt);
7589 7649          mutex_exit(&mpt->m_mutex);
7590 7650  }
7591 7651  
7592 7652  void
7593 7653  mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7594 7654  {
7595 7655          int             slot;
7596 7656          mptsas_slots_t  *slots = mpt->m_active;
↓ open down ↓ 51 lines elided ↑ open up ↑
7648 7708          /*
7649 7709           * Figure out what to set tag Q timeout for...
7650 7710           *
7651 7711           * Optimize: If we have duplicate's of same timeout
7652 7712           * we're using, then we'll use it again until we run
7653 7713           * out of duplicates.  This should be the normal case
7654 7714           * for block and raw I/O.
7655 7715           * If no duplicates, we have to scan through tag que and
7656 7716           * find the longest timeout value and use it.  This is
7657 7717           * going to take a while...
7658      -         * Add 1 to m_n_slots to account for TM request.
     7718 +         * Add 1 to m_n_normal to account for TM request.
7659 7719           */
7660 7720          if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
7661 7721                  if (--(ptgt->m_dups) == 0) {
7662 7722                          if (ptgt->m_t_ncmds) {
7663 7723                                  mptsas_cmd_t *ssp;
7664 7724                                  uint_t n = 0;
7665      -                                ushort_t nslots = (slots->m_n_slots + 1);
     7725 +                                ushort_t nslots = (slots->m_n_normal + 1);
7666 7726                                  ushort_t i;
7667 7727                                  /*
7668 7728                                   * This crude check assumes we don't do
7669 7729                                   * this too often which seems reasonable
7670 7730                                   * for block and raw I/O.
7671 7731                                   */
7672 7732                                  for (i = 0; i < nslots; i++) {
7673 7733                                          ssp = slots->m_slot[i];
7674 7734                                          if (ssp && (Tgt(ssp) == t) &&
7675 7735                                              (ssp->cmd_pkt->pkt_time > n)) {
↓ open down ↓ 738 lines elided ↑ open up ↑
8414 8474          if (rval == FAILED)
8415 8475                  rval = FALSE;
8416 8476          return (rval);
8417 8477  }
8418 8478  
8419 8479  static int
8420 8480  mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8421 8481  {
8422 8482          int             rval = FALSE;
8423 8483          uint8_t         config, disk;
8424      -        mptsas_slots_t  *slots = mpt->m_active;
8425 8484  
8426 8485          ASSERT(mutex_owned(&mpt->m_mutex));
8427 8486  
8428 8487          if (mptsas_debug_resets) {
8429 8488                  mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8430 8489                      devhdl);
8431 8490          }
8432 8491  
8433 8492          /*
8434 8493           * Issue a Target Reset message to the target specified but not to a
8435 8494           * disk making up a raid volume.  Just look through the RAID config
8436 8495           * Phys Disk list of DevHandles.  If the target's DevHandle is in this
8437 8496           * list, then don't reset this target.
8438 8497           */
8439      -        for (config = 0; config < slots->m_num_raid_configs; config++) {
     8498 +        for (config = 0; config < mpt->m_num_raid_configs; config++) {
8440 8499                  for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8441      -                        if (devhdl == slots->m_raidconfig[config].
     8500 +                        if (devhdl == mpt->m_raidconfig[config].
8442 8501                              m_physdisk_devhdl[disk]) {
8443 8502                                  return (TRUE);
8444 8503                          }
8445 8504                  }
8446 8505          }
8447 8506  
8448 8507          rval = mptsas_ioc_task_management(mpt,
8449 8508              MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0);
8450 8509  
8451 8510          mptsas_doneq_empty(mpt);
↓ open down ↓ 75 lines elided ↑ open up ↑
8527 8586          uint_t          stat;
8528 8587  
8529 8588          NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8530 8589  
8531 8590          /*
8532 8591           * Make sure the I/O Controller has flushed all cmds
8533 8592           * that are associated with this target for a target reset
8534 8593           * and target/lun for abort task set.
8535 8594           * Account for TM requests, which use the last SMID.
8536 8595           */
8537      -        for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
     8596 +        for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
8538 8597                  if ((cmd = slots->m_slot[slot]) == NULL)
8539 8598                          continue;
8540 8599                  reason = CMD_RESET;
8541 8600                  stat = STAT_DEV_RESET;
8542 8601                  switch (tasktype) {
8543 8602                  case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8544 8603                          if (Tgt(cmd) == target) {
8545 8604                                  NDBG25(("mptsas_flush_target discovered non-"
8546 8605                                      "NULL cmd in slot %d, tasktype 0x%x", slot,
8547 8606                                      tasktype));
↓ open down ↓ 111 lines elided ↑ open up ↑
8659 8718          int             slot;
8660 8719  
8661 8720          NDBG25(("mptsas_flush_hba"));
8662 8721  
8663 8722          /*
8664 8723           * The I/O Controller should have already sent back
8665 8724           * all commands via the scsi I/O reply frame.  Make
8666 8725           * sure all commands have been flushed.
8667 8726           * Account for TM request, which use the last SMID.
8668 8727           */
8669      -        for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
     8728 +        for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
8670 8729                  if ((cmd = slots->m_slot[slot]) == NULL)
8671 8730                          continue;
8672 8731  
8673 8732                  if (cmd->cmd_flags & CFLAG_CMDIOC) {
8674 8733                          /*
8675 8734                           * Need to make sure to tell everyone that might be
8676 8735                           * waiting on this command that it's going to fail.  If
8677 8736                           * we get here, this command will never timeout because
8678 8737                           * the active command table is going to be re-allocated,
8679 8738                           * so there will be nothing to check against a time out.
↓ open down ↓ 94 lines elided ↑ open up ↑
8774 8833                  ASSERT(mptsas_reset_watch != NULL);
8775 8834          }
8776 8835          mutex_exit(&mptsas_global_mutex);
8777 8836  }
8778 8837  
8779 8838  static void
8780 8839  mptsas_setup_bus_reset_delay(mptsas_t *mpt)
8781 8840  {
8782 8841          mptsas_target_t *ptgt = NULL;
8783 8842  
     8843 +        ASSERT(MUTEX_HELD(&mpt->m_mutex));
     8844 +
8784 8845          NDBG22(("mptsas_setup_bus_reset_delay"));
8785      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8786      -            MPTSAS_HASH_FIRST);
8787      -        while (ptgt != NULL) {
     8846 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     8847 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
8788 8848                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
8789 8849                  ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
8790      -
8791      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8792      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8793 8850          }
8794 8851  
8795 8852          mptsas_start_watch_reset_delay();
8796 8853  }
8797 8854  
8798 8855  /*
8799 8856   * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
8800 8857   * mpt instance for active reset delays
8801 8858   */
8802 8859  static void
↓ open down ↓ 31 lines elided ↑ open up ↑
8834 8891  mptsas_watch_reset_delay_subr(mptsas_t *mpt)
8835 8892  {
8836 8893          int             done = 0;
8837 8894          int             restart = 0;
8838 8895          mptsas_target_t *ptgt = NULL;
8839 8896  
8840 8897          NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
8841 8898  
8842 8899          ASSERT(mutex_owned(&mpt->m_mutex));
8843 8900  
8844      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8845      -            MPTSAS_HASH_FIRST);
8846      -        while (ptgt != NULL) {
     8901 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     8902 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
8847 8903                  if (ptgt->m_reset_delay != 0) {
8848 8904                          ptgt->m_reset_delay -=
8849 8905                              MPTSAS_WATCH_RESET_DELAY_TICK;
8850 8906                          if (ptgt->m_reset_delay <= 0) {
8851 8907                                  ptgt->m_reset_delay = 0;
8852 8908                                  mptsas_set_throttle(mpt, ptgt,
8853 8909                                      MAX_THROTTLE);
8854 8910                                  restart++;
8855 8911                          } else {
8856 8912                                  done = -1;
8857 8913                          }
8858 8914                  }
8859      -
8860      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8861      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8862 8915          }
8863 8916  
8864 8917          if (restart > 0) {
8865 8918                  mptsas_restart_hba(mpt);
8866 8919          }
8867 8920          return (done);
8868 8921  }
8869 8922  
8870 8923  #ifdef MPTSAS_TEST
8871 8924  static void
↓ open down ↓ 283 lines elided ↑ open up ↑
9155 9208          *cidxp = scsi_hba_lookup_capstr(cap);
9156 9209          return (TRUE);
9157 9210  }
9158 9211  
9159 9212  static int
9160 9213  mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
9161 9214  {
9162 9215          mptsas_slots_t  *old_active = mpt->m_active;
9163 9216          mptsas_slots_t  *new_active;
9164 9217          size_t          size;
9165      -        int             rval = -1, i;
9166 9218  
9167 9219          /*
9168 9220           * if there are active commands, then we cannot
9169 9221           * change size of active slots array.
9170 9222           */
9171 9223          ASSERT(mpt->m_ncmds == 0);
9172 9224  
9173 9225          size = MPTSAS_SLOTS_SIZE(mpt);
9174 9226          new_active = kmem_zalloc(size, flag);
9175 9227          if (new_active == NULL) {
9176 9228                  NDBG1(("new active alloc failed"));
9177      -                return (rval);
     9229 +                return (-1);
9178 9230          }
9179 9231          /*
9180 9232           * Since SMID 0 is reserved and the TM slot is reserved, the
9181 9233           * number of slots that can be used at any one time is
9182 9234           * m_max_requests - 2.
9183 9235           */
9184      -        new_active->m_n_slots = (mpt->m_max_requests - 2);
     9236 +        new_active->m_n_normal = (mpt->m_max_requests - 2);
9185 9237          new_active->m_size = size;
9186      -        new_active->m_tags = 1;
9187      -        if (old_active) {
9188      -                new_active->m_tgttbl = old_active->m_tgttbl;
9189      -                new_active->m_smptbl = old_active->m_smptbl;
9190      -                new_active->m_num_raid_configs =
9191      -                    old_active->m_num_raid_configs;
9192      -                for (i = 0; i < new_active->m_num_raid_configs; i++) {
9193      -                        new_active->m_raidconfig[i] =
9194      -                            old_active->m_raidconfig[i];
9195      -                }
     9238 +        new_active->m_rotor = 1;
     9239 +        if (old_active)
9196 9240                  mptsas_free_active_slots(mpt);
9197      -        }
9198 9241          mpt->m_active = new_active;
9199      -        rval = 0;
9200 9242  
9201      -        return (rval);
     9243 +        return (0);
9202 9244  }
9203 9245  
9204 9246  static void
9205 9247  mptsas_free_active_slots(mptsas_t *mpt)
9206 9248  {
9207 9249          mptsas_slots_t  *active = mpt->m_active;
9208 9250          size_t          size;
9209 9251  
9210 9252          if (active == NULL)
9211 9253                  return;
↓ open down ↓ 124 lines elided ↑ open up ↑
9336 9378          mutex_exit(&mptsas_global_mutex);
9337 9379  }
9338 9380  
9339 9381  static void
9340 9382  mptsas_watchsubr(mptsas_t *mpt)
9341 9383  {
9342 9384          int             i;
9343 9385          mptsas_cmd_t    *cmd;
9344 9386          mptsas_target_t *ptgt = NULL;
9345 9387  
     9388 +        ASSERT(MUTEX_HELD(&mpt->m_mutex));
     9389 +
9346 9390          NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
9347 9391  
9348 9392  #ifdef MPTSAS_TEST
9349 9393          if (mptsas_enable_untagged) {
9350 9394                  mptsas_test_untagged++;
9351 9395          }
9352 9396  #endif
9353 9397  
9354 9398          /*
9355 9399           * Check for commands stuck in active slot
9356 9400           * Account for TM requests, which use the last SMID.
9357 9401           */
9358      -        for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
     9402 +        for (i = 0; i <= mpt->m_active->m_n_normal; i++) {
9359 9403                  if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9360 9404                          if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9361 9405                                  cmd->cmd_active_timeout -=
9362 9406                                      mptsas_scsi_watchdog_tick;
9363 9407                                  if (cmd->cmd_active_timeout <= 0) {
9364 9408                                          /*
9365 9409                                           * There seems to be a command stuck
9366 9410                                           * in the active slot.  Drain throttle.
9367 9411                                           */
9368 9412                                          mptsas_set_throttle(mpt,
↓ open down ↓ 13 lines elided ↑ open up ↑
9382 9426                                          cmd->cmd_flags |= (CFLAG_FINISHED |
9383 9427                                              CFLAG_TIMEOUT);
9384 9428                                          cv_broadcast(&mpt->m_passthru_cv);
9385 9429                                          cv_broadcast(&mpt->m_config_cv);
9386 9430                                          cv_broadcast(&mpt->m_fw_diag_cv);
9387 9431                                  }
9388 9432                          }
9389 9433                  }
9390 9434          }
9391 9435  
9392      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9393      -            MPTSAS_HASH_FIRST);
9394      -        while (ptgt != NULL) {
     9436 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     9437 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
9395 9438                  /*
9396 9439                   * If we were draining due to a qfull condition,
9397 9440                   * go back to full throttle.
9398 9441                   */
9399 9442                  if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
9400 9443                      (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9401 9444                      (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9402 9445                          mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9403 9446                          mptsas_restart_hba(mpt);
9404 9447                  }
9405 9448  
9406 9449                  if ((ptgt->m_t_ncmds > 0) &&
9407 9450                      (ptgt->m_timebase)) {
9408 9451  
9409 9452                          if (ptgt->m_timebase <=
9410 9453                              mptsas_scsi_watchdog_tick) {
9411 9454                                  ptgt->m_timebase +=
9412 9455                                      mptsas_scsi_watchdog_tick;
9413      -                                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9414      -                                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9415 9456                                  continue;
9416 9457                          }
9417 9458  
9418 9459                          ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9419 9460  
9420 9461                          if (ptgt->m_timeout < 0) {
9421 9462                                  mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
9422      -                                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9423      -                                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9424 9463                                  continue;
9425 9464                          }
9426 9465  
9427 9466                          if ((ptgt->m_timeout) <=
9428 9467                              mptsas_scsi_watchdog_tick) {
9429 9468                                  NDBG23(("pending timeout"));
9430 9469                                  mptsas_set_throttle(mpt, ptgt,
9431 9470                                      DRAIN_THROTTLE);
9432 9471                          }
9433 9472                  }
9434      -
9435      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9436      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9437 9473          }
9438 9474  }
9439 9475  
9440 9476  /*
9441 9477   * timeout recovery
9442 9478   */
9443 9479  static void
9444 9480  mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9445 9481  {
9446 9482  
↓ open down ↓ 43 lines elided ↑ open up ↑
9490 9526  
9491 9527  static int
9492 9528  mptsas_quiesce_bus(mptsas_t *mpt)
9493 9529  {
9494 9530          mptsas_target_t *ptgt = NULL;
9495 9531  
9496 9532          NDBG28(("mptsas_quiesce_bus"));
9497 9533          mutex_enter(&mpt->m_mutex);
9498 9534  
9499 9535          /* Set all the throttles to zero */
9500      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9501      -            MPTSAS_HASH_FIRST);
9502      -        while (ptgt != NULL) {
     9536 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     9537 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
9503 9538                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9504      -
9505      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9506      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9507 9539          }
9508 9540  
9509 9541          /* If there are any outstanding commands in the queue */
9510 9542          if (mpt->m_ncmds) {
9511 9543                  mpt->m_softstate |= MPTSAS_SS_DRAINING;
9512 9544                  mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9513 9545                      mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9514 9546                  if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9515 9547                          /*
9516 9548                           * Quiesce has been interrupted
9517 9549                           */
9518 9550                          mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9519      -                        ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9520      -                            &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9521      -                        while (ptgt != NULL) {
     9551 +                        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     9552 +                            ptgt = refhash_next(mpt->m_targets, ptgt)) {
9522 9553                                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9523      -
9524      -                                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9525      -                                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9526 9554                          }
9527 9555                          mptsas_restart_hba(mpt);
9528 9556                          if (mpt->m_quiesce_timeid != 0) {
9529 9557                                  timeout_id_t tid = mpt->m_quiesce_timeid;
9530 9558                                  mpt->m_quiesce_timeid = 0;
9531 9559                                  mutex_exit(&mpt->m_mutex);
9532 9560                                  (void) untimeout(tid);
9533 9561                                  return (-1);
9534 9562                          }
9535 9563                          mutex_exit(&mpt->m_mutex);
↓ open down ↓ 14 lines elided ↑ open up ↑
9550 9578  }
9551 9579  
9552 9580  static int
9553 9581  mptsas_unquiesce_bus(mptsas_t *mpt)
9554 9582  {
9555 9583          mptsas_target_t *ptgt = NULL;
9556 9584  
9557 9585          NDBG28(("mptsas_unquiesce_bus"));
9558 9586          mutex_enter(&mpt->m_mutex);
9559 9587          mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
9560      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9561      -            MPTSAS_HASH_FIRST);
9562      -        while (ptgt != NULL) {
     9588 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     9589 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
9563 9590                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9564      -
9565      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9566      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9567 9591          }
9568 9592          mptsas_restart_hba(mpt);
9569 9593          mutex_exit(&mpt->m_mutex);
9570 9594          return (0);
9571 9595  }
9572 9596  
9573 9597  static void
9574 9598  mptsas_ncmds_checkdrain(void *arg)
9575 9599  {
9576 9600          mptsas_t        *mpt = arg;
↓ open down ↓ 3 lines elided ↑ open up ↑
9580 9604          if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
9581 9605                  mpt->m_quiesce_timeid = 0;
9582 9606                  if (mpt->m_ncmds == 0) {
9583 9607                          /* Command queue has been drained */
9584 9608                          cv_signal(&mpt->m_cv);
9585 9609                  } else {
9586 9610                          /*
9587 9611                           * The throttle may have been reset because
9588 9612                           * of a SCSI bus reset
9589 9613                           */
9590      -                        ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9591      -                            &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9592      -                        while (ptgt != NULL) {
     9614 +                        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     9615 +                            ptgt = refhash_next(mpt->m_targets, ptgt)) {
9593 9616                                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9594      -
9595      -                                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9596      -                                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9597 9617                          }
9598 9618  
9599 9619                          mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9600 9620                              mpt, (MPTSAS_QUIESCE_TIMEOUT *
9601 9621                              drv_usectohz(1000000)));
9602 9622                  }
9603 9623          }
9604 9624          mutex_exit(&mpt->m_mutex);
9605 9625  }
9606 9626  
↓ open down ↓ 1711 lines elided ↑ open up ↑
11318 11338              lc.LedStatus != 1)) {
11319 11339                  return (EINVAL);
11320 11340          }
11321 11341  
11322 11342          if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
11323 11343              (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
11324 11344                  return (EACCES);
11325 11345  
11326 11346          /* Locate the target we're interrogating... */
11327 11347          mutex_enter(&mpt->m_mutex);
11328      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11329      -            MPTSAS_HASH_FIRST);
11330      -        while (ptgt != NULL) {
11331      -                if (ptgt->m_enclosure == lc.Enclosure &&
11332      -                    ptgt->m_slot_num == lc.Slot) {
11333      -                        break;
11334      -                }
11335      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11336      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11337      -        }
     11348 +        ptgt = refhash_linear_search(mpt->m_targets,
     11349 +            mptsas_target_eval_slot, &lc);
11338 11350          if (ptgt == NULL) {
11339 11351                  /* We could not find a target for that enclosure/slot. */
11340 11352                  mutex_exit(&mpt->m_mutex);
11341 11353                  return (ENOENT);
11342 11354          }
11343 11355  
11344 11356          if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
11345 11357                  /* Update our internal LED state. */
11346 11358                  ptgt->m_led_status &= ~(1 << (lc.Led - 1));
11347 11359                  ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
↓ open down ↓ 30 lines elided ↑ open up ↑
11378 11390  
11379 11391          STRUCT_INIT(gdi, get_udatamodel());
11380 11392  
11381 11393          if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
11382 11394              mode) != 0) {
11383 11395                  return (EFAULT);
11384 11396          }
11385 11397  
11386 11398          /* Find out how many targets there are. */
11387 11399          mutex_enter(&mpt->m_mutex);
11388      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11389      -            MPTSAS_HASH_FIRST);
11390      -        while (ptgt != NULL) {
     11400 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     11401 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
11391 11402                  count++;
11392      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11393      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11394 11403          }
11395 11404          mutex_exit(&mpt->m_mutex);
11396 11405  
11397 11406          /*
11398 11407           * If we haven't been asked to copy out information on each target,
11399 11408           * then just return the count.
11400 11409           */
11401 11410          STRUCT_FSET(gdi, DiskCount, count);
11402 11411          if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
11403 11412                  goto copy_out;
↓ open down ↓ 4 lines elided ↑ open up ↑
11408 11417           */
11409 11418          if (STRUCT_FGET(gdi, DiskInfoArraySize) <
11410 11419              count * sizeof (mptsas_disk_info_t)) {
11411 11420                  ret = ENOSPC;
11412 11421                  goto copy_out;
11413 11422          }
11414 11423  
11415 11424          di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
11416 11425  
11417 11426          mutex_enter(&mpt->m_mutex);
11418      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11419      -            MPTSAS_HASH_FIRST);
11420      -        while (ptgt != NULL) {
     11427 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     11428 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
11421 11429                  if (i >= count) {
11422 11430                          /*
11423 11431                           * The number of targets changed while we weren't
11424 11432                           * looking, so give up.
11425 11433                           */
     11434 +                        refhash_rele(mpt->m_targets, ptgt);
11426 11435                          mutex_exit(&mpt->m_mutex);
11427 11436                          kmem_free(di, count * sizeof (mptsas_disk_info_t));
11428 11437                          return (EAGAIN);
11429 11438                  }
11430 11439                  di[i].Instance = mpt->m_instance;
11431 11440                  di[i].Enclosure = ptgt->m_enclosure;
11432 11441                  di[i].Slot = ptgt->m_slot_num;
11433      -                di[i].SasAddress = ptgt->m_sas_wwn;
11434      -
11435      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11436      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
     11442 +                di[i].SasAddress = ptgt->m_addr.mta_wwn;
11437 11443                  i++;
11438 11444          }
11439 11445          mutex_exit(&mpt->m_mutex);
11440 11446          STRUCT_FSET(gdi, DiskCount, i);
11441 11447  
11442 11448          /* Copy out the disk information to the caller. */
11443 11449          if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
11444 11450              i * sizeof (mptsas_disk_info_t), mode) != 0) {
11445 11451                  ret = EFAULT;
11446 11452          }
↓ open down ↓ 285 lines elided ↑ open up ↑
11732 11738           * needed because after the reset is complete, the hash table still
11733 11739           * needs to be rebuilt.  If I/Os are started before the hash table is
11734 11740           * rebuilt, I/O errors will occur.  This flag allows I/Os to be marked
11735 11741           * so that they can be retried.
11736 11742           */
11737 11743          mpt->m_in_reset = TRUE;
11738 11744  
11739 11745          /*
11740 11746           * Set all throttles to HOLD
11741 11747           */
11742      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11743      -            MPTSAS_HASH_FIRST);
11744      -        while (ptgt != NULL) {
     11748 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     11749 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
11745 11750                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
11746      -
11747      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11748      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11749 11751          }
11750 11752  
11751 11753          /*
11752 11754           * Disable interrupts
11753 11755           */
11754 11756          MPTSAS_DISABLE_INTR(mpt);
11755 11757  
11756 11758          /*
11757 11759           * Abort all commands: outstanding commands, commands in waitq and
11758 11760           * tx_waitq.
↓ open down ↓ 15 lines elided ↑ open up ↑
11774 11776          /*
11775 11777           * If mptsas_init_chip was successful, update the driver data.
11776 11778           */
11777 11779          if (rval == DDI_SUCCESS) {
11778 11780                  mptsas_update_driver_data(mpt);
11779 11781          }
11780 11782  
11781 11783          /*
11782 11784           * Reset the throttles
11783 11785           */
11784      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11785      -            MPTSAS_HASH_FIRST);
11786      -        while (ptgt != NULL) {
     11786 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     11787 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
11787 11788                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
11788      -
11789      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11790      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11791 11789          }
11792 11790  
11793 11791          mptsas_doneq_empty(mpt);
11794 11792          mptsas_restart_hba(mpt);
11795 11793  
11796 11794          if (rval != DDI_SUCCESS) {
11797 11795                  mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
11798 11796                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
11799 11797          }
11800 11798  
↓ open down ↓ 45 lines elided ↑ open up ↑
11846 11844          /*
11847 11845           * IOC facts can change after a diag reset so all buffers that are
11848 11846           * based on these numbers must be de-allocated and re-allocated.  Get
11849 11847           * new IOC facts each time chip is initialized.
11850 11848           */
11851 11849          if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
11852 11850                  mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
11853 11851                  goto fail;
11854 11852          }
11855 11853  
     11854 +        mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
     11855 +            mptsas_target_addr_hash, mptsas_target_addr_cmp,
     11856 +            mptsas_target_free, sizeof (mptsas_target_t),
     11857 +            offsetof(mptsas_target_t, m_link),
     11858 +            offsetof(mptsas_target_t, m_addr), KM_SLEEP);
     11859 +
11856 11860          if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
11857 11861                  goto fail;
11858 11862          }
11859 11863          /*
11860 11864           * Allocate request message frames, reply free queue, reply descriptor
11861 11865           * post queue, and reply message frames using latest IOC facts.
11862 11866           */
11863 11867          if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
11864 11868                  mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
11865 11869                  goto fail;
↓ open down ↓ 618 lines elided ↑ open up ↑
12484 12488  
12485 12489  static int
12486 12490  mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
12487 12491      uint16_t *dev_handle, mptsas_target_t **pptgt)
12488 12492  {
12489 12493          int             rval;
12490 12494          uint32_t        dev_info;
12491 12495          uint64_t        sas_wwn;
12492 12496          mptsas_phymask_t phymask;
12493 12497          uint8_t         physport, phynum, config, disk;
12494      -        mptsas_slots_t  *slots = mpt->m_active;
12495 12498          uint64_t        devicename;
12496 12499          uint16_t        pdev_hdl;
12497 12500          mptsas_target_t *tmp_tgt = NULL;
12498 12501          uint16_t        bay_num, enclosure;
12499 12502  
12500 12503          ASSERT(*pptgt == NULL);
12501 12504  
12502 12505          rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
12503 12506              &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl,
12504 12507              &bay_num, &enclosure);
↓ open down ↓ 6 lines elided ↑ open up ↑
12511 12514              MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12512 12515              MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
12513 12516                  rval = DEV_INFO_WRONG_DEVICE_TYPE;
12514 12517                  return (rval);
12515 12518          }
12516 12519  
12517 12520          /*
12518 12521           * Check if the dev handle is for a Phys Disk. If so, set return value
12519 12522           * and exit.  Don't add Phys Disks to hash.
12520 12523           */
12521      -        for (config = 0; config < slots->m_num_raid_configs; config++) {
     12524 +        for (config = 0; config < mpt->m_num_raid_configs; config++) {
12522 12525                  for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
12523      -                        if (*dev_handle == slots->m_raidconfig[config].
     12526 +                        if (*dev_handle == mpt->m_raidconfig[config].
12524 12527                              m_physdisk_devhdl[disk]) {
12525 12528                                  rval = DEV_INFO_PHYS_DISK;
12526 12529                                  return (rval);
12527 12530                          }
12528 12531                  }
12529 12532          }
12530 12533  
12531 12534          /*
12532 12535           * Get SATA Device Name from SAS device page0 for
12533      -         * sata device, if device name doesn't exist, set m_sas_wwn to
     12536 +         * sata device, if device name doesn't exist, set mta_wwn to
12534 12537           * 0 for direct attached SATA. For the device behind the expander
12535 12538           * we still can use STP address assigned by expander.
12536 12539           */
12537 12540          if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12538 12541              MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12539 12542                  mutex_exit(&mpt->m_mutex);
12540 12543                  /* alloc a tmp_tgt to send the cmd */
12541 12544                  tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
12542 12545                      KM_SLEEP);
12543 12546                  tmp_tgt->m_devhdl = *dev_handle;
↓ open down ↓ 6 lines elided ↑ open up ↑
12550 12553                  kmem_free(tmp_tgt, sizeof (struct mptsas_target));
12551 12554                  mutex_enter(&mpt->m_mutex);
12552 12555                  if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
12553 12556                          sas_wwn = devicename;
12554 12557                  } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
12555 12558                          sas_wwn = 0;
12556 12559                  }
12557 12560          }
12558 12561  
12559 12562          phymask = mptsas_physport_to_phymask(mpt, physport);
12560      -        *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
     12563 +        *pptgt = mptsas_tgt_alloc(mpt, *dev_handle, sas_wwn,
12561 12564              dev_info, phymask, phynum);
12562 12565          if (*pptgt == NULL) {
12563 12566                  mptsas_log(mpt, CE_WARN, "Failed to allocated target"
12564 12567                      "structure!");
12565 12568                  rval = DEV_INFO_FAIL_ALLOC;
12566 12569                  return (rval);
12567 12570          }
12568 12571          (*pptgt)->m_enclosure = enclosure;
12569 12572          (*pptgt)->m_slot_num = bay_num;
12570 12573          return (DEV_INFO_SUCCESS);
↓ open down ↓ 409 lines elided ↑ open up ↑
12980 12983           */
12981 12984  
12982 12985          *lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
12983 12986          if (*lundip != NULL) {
12984 12987                  /*
12985 12988                   * TODO Another senario is, we hotplug the same disk
12986 12989                   * on the same slot, the devhdl changed, is this
12987 12990                   * possible?
12988 12991                   * tgt_private->t_private != ptgt
12989 12992                   */
12990      -                if (sasaddr != ptgt->m_sas_wwn) {
     12993 +                if (sasaddr != ptgt->m_addr.mta_wwn) {
12991 12994                          /*
12992 12995                           * The device has changed although the devhdl is the
12993 12996                           * same (Enclosure mapping mode, change drive on the
12994 12997                           * same slot)
12995 12998                           */
12996 12999                          return (DDI_FAILURE);
12997 13000                  }
12998 13001                  return (DDI_SUCCESS);
12999 13002          }
13000 13003  
↓ open down ↓ 8 lines elided ↑ open up ↑
13009 13012  
13010 13013          return (rval);
13011 13014  }
13012 13015  
13013 13016  static int
13014 13017  mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
13015 13018      dev_info_t **lundip)
13016 13019  {
13017 13020          int             rval;
13018 13021          mptsas_t        *mpt = DIP2MPT(pdip);
13019      -        int             phymask;
     13022 +        mptsas_phymask_t phymask;
13020 13023          mptsas_target_t *ptgt = NULL;
13021 13024  
13022 13025          /*
13023 13026           * Get the physical port associated to the iport
13024 13027           */
13025      -        phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
     13028 +        phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13026 13029              "phymask", 0);
13027 13030  
13028 13031          ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
13029 13032          if (ptgt == NULL) {
13030 13033                  /*
13031 13034                   * didn't match any device by searching
13032 13035                   */
13033 13036                  return (DDI_FAILURE);
13034 13037          }
13035 13038  
↓ open down ↓ 66 lines elided ↑ open up ↑
13102 13105          dev_info_t              *cdip = NULL;
13103 13106          uint16_t                *saved_repluns = NULL;
13104 13107          char                    *buffer = NULL;
13105 13108          int                     buf_len = 128;
13106 13109          mptsas_t                *mpt = DIP2MPT(pdip);
13107 13110          uint64_t                sas_wwn = 0;
13108 13111          uint8_t                 phy = 0xFF;
13109 13112          uint32_t                dev_info = 0;
13110 13113  
13111 13114          mutex_enter(&mpt->m_mutex);
13112      -        sas_wwn = ptgt->m_sas_wwn;
     13115 +        sas_wwn = ptgt->m_addr.mta_wwn;
13113 13116          phy = ptgt->m_phynum;
13114 13117          dev_info = ptgt->m_deviceinfo;
13115 13118          mutex_exit(&mpt->m_mutex);
13116 13119  
13117 13120          if (sas_wwn == 0) {
13118 13121                  /*
13119 13122                   * It's a SATA without Device Name
13120 13123                   * So don't try multi-LUNs
13121 13124                   */
13122 13125                  if (mptsas_find_child_phy(pdip, phy)) {
↓ open down ↓ 94 lines elided ↑ open up ↑
13217 13220  
13218 13221  static int
13219 13222  mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
13220 13223  {
13221 13224          int                     rval = DDI_FAILURE;
13222 13225          struct scsi_inquiry     *sd_inq = NULL;
13223 13226          mptsas_t                *mpt = DIP2MPT(pdip);
13224 13227          mptsas_target_t         *ptgt = NULL;
13225 13228  
13226 13229          mutex_enter(&mpt->m_mutex);
13227      -        ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target);
     13230 +        ptgt = refhash_linear_search(mpt->m_targets,
     13231 +            mptsas_target_eval_devhdl, &target);
13228 13232          mutex_exit(&mpt->m_mutex);
13229 13233          if (ptgt == NULL) {
13230 13234                  mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
13231 13235                      "not found.", target);
13232 13236                  return (rval);
13233 13237          }
13234 13238  
13235 13239          sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
13236 13240          rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
13237 13241              SUN_INQSIZE, 0, (uchar_t)0);
↓ open down ↓ 12 lines elided ↑ open up ↑
13250 13254  /*
13251 13255   * configure all RAID volumes for virtual iport
13252 13256   */
13253 13257  static void
13254 13258  mptsas_config_all_viport(dev_info_t *pdip)
13255 13259  {
13256 13260          mptsas_t        *mpt = DIP2MPT(pdip);
13257 13261          int             config, vol;
13258 13262          int             target;
13259 13263          dev_info_t      *lundip = NULL;
13260      -        mptsas_slots_t  *slots = mpt->m_active;
13261 13264  
13262 13265          /*
13263 13266           * Get latest RAID info and search for any Volume DevHandles.  If any
13264 13267           * are found, configure the volume.
13265 13268           */
13266 13269          mutex_enter(&mpt->m_mutex);
13267      -        for (config = 0; config < slots->m_num_raid_configs; config++) {
     13270 +        for (config = 0; config < mpt->m_num_raid_configs; config++) {
13268 13271                  for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
13269      -                        if (slots->m_raidconfig[config].m_raidvol[vol].m_israid
     13272 +                        if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid
13270 13273                              == 1) {
13271      -                                target = slots->m_raidconfig[config].
     13274 +                                target = mpt->m_raidconfig[config].
13272 13275                                      m_raidvol[vol].m_raidhandle;
13273 13276                                  mutex_exit(&mpt->m_mutex);
13274 13277                                  (void) mptsas_config_raid(pdip, target,
13275 13278                                      &lundip);
13276 13279                                  mutex_enter(&mpt->m_mutex);
13277 13280                          }
13278 13281                  }
13279 13282          }
13280 13283          mutex_exit(&mpt->m_mutex);
13281 13284  }
↓ open down ↓ 7 lines elided ↑ open up ↑
13289 13292          uint64_t        sas_wwn, wwid;
13290 13293          uint8_t         phy;
13291 13294          int             lun;
13292 13295          int             i;
13293 13296          int             find;
13294 13297          char            *addr;
13295 13298          char            *nodename;
13296 13299          mptsas_t        *mpt = DIP2MPT(pdip);
13297 13300  
13298 13301          mutex_enter(&mpt->m_mutex);
13299      -        wwid = ptgt->m_sas_wwn;
     13302 +        wwid = ptgt->m_addr.mta_wwn;
13300 13303          mutex_exit(&mpt->m_mutex);
13301 13304  
13302 13305          child = ddi_get_child(pdip);
13303 13306          while (child) {
13304 13307                  find = 0;
13305 13308                  savechild = child;
13306 13309                  child = ddi_get_next_sibling(child);
13307 13310  
13308 13311                  nodename = ddi_node_name(savechild);
13309 13312                  if (strcmp(nodename, "smp") == 0) {
↓ open down ↓ 83 lines elided ↑ open up ↑
13393 13396  
13394 13397          dev_handle = mpt->m_smp_devhdl;
13395 13398          for (; mpt->m_done_traverse_smp == 0; ) {
13396 13399                  page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
13397 13400                      MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
13398 13401                  if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
13399 13402                      != DDI_SUCCESS) {
13400 13403                          break;
13401 13404                  }
13402 13405                  mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
13403      -                (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
     13406 +                (void) mptsas_smp_alloc(mpt, &smp_node);
13404 13407          }
13405 13408  
13406 13409          /*
13407 13410           * Config target devices
13408 13411           */
13409 13412          dev_handle = mpt->m_dev_handle;
13410 13413  
13411 13414          /*
13412 13415           * Do loop to get sas device page 0 by GetNextHandle till the
13413 13416           * the last handle. If the sas device is a SATA/SSP target,
↓ open down ↓ 11 lines elided ↑ open up ↑
13425 13428                      (rval == DEV_INFO_FAIL_ALLOC)) {
13426 13429                          break;
13427 13430                  }
13428 13431  
13429 13432                  mpt->m_dev_handle = dev_handle;
13430 13433          }
13431 13434  
13432 13435  }
13433 13436  
13434 13437  void
13435      -mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab)
13436      -{
13437      -        mptsas_hash_data_t *data;
13438      -        data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
13439      -        while (data != NULL) {
13440      -                data->devhdl = MPTSAS_INVALID_DEVHDL;
13441      -                data->device_info = 0;
13442      -                /*
13443      -                 * For tgttbl, clear dr_flag.
13444      -                 */
13445      -                data->dr_flag = MPTSAS_DR_INACTIVE;
13446      -                data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
13447      -        }
13448      -}
13449      -
13450      -void
13451 13438  mptsas_update_driver_data(struct mptsas *mpt)
13452 13439  {
     13440 +        mptsas_target_t *tp;
     13441 +        mptsas_smp_t *sp;
     13442 +
     13443 +        ASSERT(MUTEX_HELD(&mpt->m_mutex));
     13444 +
13453 13445          /*
13454 13446           * TODO after hard reset, update the driver data structures
13455 13447           * 1. update port/phymask mapping table mpt->m_phy_info
13456 13448           * 2. invalid all the entries in hash table
13457 13449           *    m_devhdl = 0xffff and m_deviceinfo = 0
13458 13450           * 3. call sas_device_page/expander_page to update hash table
13459 13451           */
13460 13452          mptsas_update_phymask(mpt);
13461 13453          /*
13462 13454           * Invalid the existing entries
     13455 +         *
     13456 +         * XXX - It seems like we should just delete everything here.  We are
     13457 +         * holding the lock and are about to refresh all the targets in both
     13458 +         * hashes anyway.  Given the path we're in, what outstanding async
     13459 +         * event could possibly be trying to reference one of these things
     13460 +         * without taking the lock, and how would that be useful anyway?
13463 13461           */
13464      -        mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl);
13465      -        mptsas_invalid_hashtab(&mpt->m_active->m_smptbl);
     13462 +        for (tp = refhash_first(mpt->m_targets); tp != NULL;
     13463 +            tp = refhash_next(mpt->m_targets, tp)) {
     13464 +                tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
     13465 +                tp->m_deviceinfo = 0;
     13466 +                tp->m_dr_flag = MPTSAS_DR_INACTIVE;
     13467 +        }
     13468 +        for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
     13469 +            sp = refhash_next(mpt->m_smp_targets, sp)) {
     13470 +                sp->m_devhdl = MPTSAS_INVALID_DEVHDL;
     13471 +                sp->m_deviceinfo = 0;
     13472 +        }
13466 13473          mpt->m_done_traverse_dev = 0;
13467 13474          mpt->m_done_traverse_smp = 0;
13468 13475          mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
13469 13476          mptsas_update_hashtab(mpt);
13470 13477  }
13471 13478  
13472 13479  static void
13473 13480  mptsas_config_all(dev_info_t *pdip)
13474 13481  {
13475 13482          dev_info_t      *smpdip = NULL;
↓ open down ↓ 16 lines elided ↑ open up ↑
13492 13499                  mptsas_config_all_viport(pdip);
13493 13500                  return;
13494 13501          }
13495 13502  
13496 13503          mutex_enter(&mpt->m_mutex);
13497 13504  
13498 13505          if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
13499 13506                  mptsas_update_hashtab(mpt);
13500 13507          }
13501 13508  
13502      -        psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl,
13503      -            MPTSAS_HASH_FIRST);
13504      -        while (psmp != NULL) {
13505      -                phy_mask = psmp->m_phymask;
     13509 +        for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL;
     13510 +            psmp = refhash_next(mpt->m_smp_targets, psmp)) {
     13511 +                phy_mask = psmp->m_addr.mta_phymask;
13506 13512                  if (phy_mask == phymask) {
13507 13513                          smpdip = NULL;
13508 13514                          mutex_exit(&mpt->m_mutex);
13509 13515                          (void) mptsas_online_smp(pdip, psmp, &smpdip);
13510 13516                          mutex_enter(&mpt->m_mutex);
13511 13517                  }
13512      -                psmp = (mptsas_smp_t *)mptsas_hash_traverse(
13513      -                    &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT);
13514 13518          }
13515 13519  
13516      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
13517      -            MPTSAS_HASH_FIRST);
13518      -        while (ptgt != NULL) {
13519      -                phy_mask = ptgt->m_phymask;
     13520 +        for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
     13521 +            ptgt = refhash_next(mpt->m_targets, ptgt)) {
     13522 +                phy_mask = ptgt->m_addr.mta_phymask;
13520 13523                  if (phy_mask == phymask) {
13521 13524                          mutex_exit(&mpt->m_mutex);
13522 13525                          (void) mptsas_config_target(pdip, ptgt);
13523 13526                          mutex_enter(&mpt->m_mutex);
13524 13527                  }
13525      -
13526      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
13527      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
13528 13528          }
13529 13529          mutex_exit(&mpt->m_mutex);
13530 13530  }
13531 13531  
13532 13532  static int
13533 13533  mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
13534 13534  {
13535 13535          int             rval = DDI_FAILURE;
13536 13536          dev_info_t      *tdip;
13537 13537  
↓ open down ↓ 161 lines elided ↑ open up ↑
13699 13699  }
13700 13700  
13701 13701  static int
13702 13702  mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
13703 13703  {
13704 13704          int             rval = DDI_FAILURE;
13705 13705          char            *devname;
13706 13706          char            wwn_str[MPTSAS_WWN_STRLEN];
13707 13707          dev_info_t      *cdip;
13708 13708  
13709      -        (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
     13709 +        (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
13710 13710  
13711 13711          cdip = mptsas_find_smp_child(pdip, wwn_str);
13712 13712  
13713 13713          if (cdip == NULL)
13714 13714                  return (DDI_SUCCESS);
13715 13715  
13716 13716          /*
13717 13717           * Make sure node is attached otherwise
13718 13718           * it won't have related cache nodes to
13719 13719           * clean up.  i_ddi_devi_attached is
↓ open down ↓ 259 lines elided ↑ open up ↑
13979 13979          uint32_t                pdev_info;
13980 13980          uint8_t                 physport;
13981 13981          uint8_t                 phy_id;
13982 13982          uint32_t                page_address;
13983 13983          uint16_t                bay_num, enclosure;
13984 13984          char                    pdev_wwn_str[MPTSAS_WWN_STRLEN];
13985 13985          uint32_t                dev_info;
13986 13986  
13987 13987          mutex_enter(&mpt->m_mutex);
13988 13988          target = ptgt->m_devhdl;
13989      -        sas_wwn = ptgt->m_sas_wwn;
     13989 +        sas_wwn = ptgt->m_addr.mta_wwn;
13990 13990          devinfo = ptgt->m_deviceinfo;
13991 13991          phy = ptgt->m_phynum;
13992 13992          mutex_exit(&mpt->m_mutex);
13993 13993  
13994 13994          if (sas_wwn) {
13995 13995                  *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13996 13996          } else {
13997 13997                  *pip = mptsas_find_path_phy(pdip, phy);
13998 13998          }
13999 13999  
↓ open down ↓ 328 lines elided ↑ open up ↑
14328 14328          uint8_t                 physport;
14329 14329          uint8_t                 phy_id;
14330 14330          uint32_t                page_address;
14331 14331          uint16_t                bay_num, enclosure;
14332 14332          char                    pdev_wwn_str[MPTSAS_WWN_STRLEN];
14333 14333          uint32_t                dev_info;
14334 14334          int64_t                 lun64 = 0;
14335 14335  
14336 14336          mutex_enter(&mpt->m_mutex);
14337 14337          target = ptgt->m_devhdl;
14338      -        sas_wwn = ptgt->m_sas_wwn;
     14338 +        sas_wwn = ptgt->m_addr.mta_wwn;
14339 14339          devinfo = ptgt->m_deviceinfo;
14340 14340          phy = ptgt->m_phynum;
14341 14341          mutex_exit(&mpt->m_mutex);
14342 14342  
14343 14343          /*
14344 14344           * generate compatible property with binding-set "mpt"
14345 14345           */
14346 14346          scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
14347 14347              &nodename, &compatible, &ncompatible);
14348 14348  
↓ open down ↓ 98 lines elided ↑ open up ↑
14447 14447                              "to create guid property for target %d "
14448 14448                              "lun %d", target, lun);
14449 14449                          ndi_rtn = NDI_FAILURE;
14450 14450                          goto phys_create_done;
14451 14451                  }
14452 14452  
14453 14453                  /*
14454 14454                   * The following code is to set properties for SM-HBA support,
14455 14455                   * it doesn't apply to RAID volumes
14456 14456                   */
14457      -                if (ptgt->m_phymask == 0)
     14457 +                if (ptgt->m_addr.mta_phymask == 0)
14458 14458                          goto phys_raid_lun;
14459 14459  
14460 14460                  mutex_enter(&mpt->m_mutex);
14461 14461  
14462 14462                  page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
14463 14463                      MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
14464 14464                      (uint32_t)ptgt->m_devhdl;
14465 14465                  rval = mptsas_get_sas_device_page0(mpt, page_address,
14466 14466                      &dev_hdl, &dev_sas_wwn, &dev_info,
14467 14467                      &physport, &phy_id, &pdev_hdl,
↓ open down ↓ 133 lines elided ↑ open up ↑
14601 14601                                  mptsas_log(mpt, CE_WARN, "mpt_sas driver "
14602 14602                                      "unable to set obp-path for SAS "
14603 14603                                      "object %s", component);
14604 14604                                  ndi_rtn = NDI_FAILURE;
14605 14605                                  goto phys_create_done;
14606 14606                          }
14607 14607                  }
14608 14608                  /*
14609 14609                   * Create the phy-num property for non-raid disk
14610 14610                   */
14611      -                if (ptgt->m_phymask != 0) {
     14611 +                if (ptgt->m_addr.mta_phymask != 0) {
14612 14612                          if (ndi_prop_update_int(DDI_DEV_T_NONE,
14613 14613                              *lun_dip, "phy-num", ptgt->m_phynum) !=
14614 14614                              DDI_PROP_SUCCESS) {
14615 14615                                  mptsas_log(mpt, CE_WARN, "mptsas driver "
14616 14616                                      "failed to create phy-num property for "
14617 14617                                      "target %d", target);
14618 14618                                  ndi_rtn = NDI_FAILURE;
14619 14619                                  goto phys_create_done;
14620 14620                          }
14621 14621                  }
↓ open down ↓ 101 lines elided ↑ open up ↑
14723 14723          uint8_t         phy_id;
14724 14724          uint16_t        pdev_hdl;
14725 14725          uint8_t         numphys = 0;
14726 14726          uint16_t        i = 0;
14727 14727          char            phymask[MPTSAS_MAX_PHYS];
14728 14728          char            *iport = NULL;
14729 14729          mptsas_phymask_t        phy_mask = 0;
14730 14730          uint16_t        attached_devhdl;
14731 14731          uint16_t        bay_num, enclosure;
14732 14732  
14733      -        (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
     14733 +        (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
14734 14734  
14735 14735          /*
14736 14736           * Probe smp device, prevent the node of removed device from being
14737 14737           * configured succesfully
14738 14738           */
14739      -        if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) {
     14739 +        if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) {
14740 14740                  return (DDI_FAILURE);
14741 14741          }
14742 14742  
14743 14743          if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
14744 14744                  return (DDI_SUCCESS);
14745 14745          }
14746 14746  
14747 14747          ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
14748 14748  
14749 14749          /*
↓ open down ↓ 7 lines elided ↑ open up ↑
14757 14757  
14758 14758                  if (ndi_prop_update_string(DDI_DEV_T_NONE,
14759 14759                      *smp_dip, SMP_WWN, wwn_str) !=
14760 14760                      DDI_PROP_SUCCESS) {
14761 14761                          mptsas_log(mpt, CE_WARN, "mptsas unable to create "
14762 14762                              "property for smp device %s (sas_wwn)",
14763 14763                              wwn_str);
14764 14764                          ndi_rtn = NDI_FAILURE;
14765 14765                          goto smp_create_done;
14766 14766                  }
14767      -                (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr);
     14767 +                (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn);
14768 14768                  if (ndi_prop_update_string(DDI_DEV_T_NONE,
14769 14769                      *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
14770 14770                      DDI_PROP_SUCCESS) {
14771 14771                          mptsas_log(mpt, CE_WARN, "mptsas unable to create "
14772 14772                              "property for iport target-port %s (sas_wwn)",
14773 14773                              wwn_str);
14774 14774                          ndi_rtn = NDI_FAILURE;
14775 14775                          goto smp_create_done;
14776 14776                  }
14777 14777  
↓ open down ↓ 263 lines elided ↑ open up ↑
15041 15041          }
15042 15042  
15043 15043          return (DDI_SUCCESS);
15044 15044  }
15045 15045  
15046 15046  /*
15047 15047   * If we didn't get a match, we need to get sas page0 for each device, and
15048 15048   * untill we get a match. If failed, return NULL
15049 15049   */
15050 15050  static mptsas_target_t *
15051      -mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy)
     15051 +mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy)
15052 15052  {
15053 15053          int             i, j = 0;
15054 15054          int             rval = 0;
15055 15055          uint16_t        cur_handle;
15056 15056          uint32_t        page_address;
15057 15057          mptsas_target_t *ptgt = NULL;
15058 15058  
15059 15059          /*
15060 15060           * PHY named device must be direct attached and attaches to
15061 15061           * narrow port, if the iport is not parent of the device which
↓ open down ↓ 11 lines elided ↑ open up ↑
15073 15073           * Must be a narrow port and single device attached to the narrow port
15074 15074           * So the physical port num of device  which is equal to the iport's
15075 15075           * port num is the device what we are looking for.
15076 15076           */
15077 15077  
15078 15078          if (mpt->m_phy_info[phy].phy_mask != phymask)
15079 15079                  return (NULL);
15080 15080  
15081 15081          mutex_enter(&mpt->m_mutex);
15082 15082  
15083      -        ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
15084      -            MPTSAS_HASH_FIRST);
15085      -        while (ptgt != NULL) {
15086      -                        if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
15087      -                        mutex_exit(&mpt->m_mutex);
15088      -                        return (ptgt);
15089      -                }
15090      -
15091      -                ptgt = (mptsas_target_t *)mptsas_hash_traverse(
15092      -                    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
     15083 +        ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn,
     15084 +            &phy);
     15085 +        if (ptgt != NULL) {
     15086 +                mutex_exit(&mpt->m_mutex);
     15087 +                return (ptgt);
15093 15088          }
15094 15089  
15095 15090          if (mpt->m_done_traverse_dev) {
15096 15091                  mutex_exit(&mpt->m_mutex);
15097 15092                  return (NULL);
15098 15093          }
15099 15094  
15100 15095          /* If didn't get a match, come here */
15101 15096          cur_handle = mpt->m_dev_handle;
15102 15097          for (; ; ) {
↓ open down ↓ 5 lines elided ↑ open up ↑
15108 15103                  if ((rval == DEV_INFO_FAIL_PAGE0) ||
15109 15104                      (rval == DEV_INFO_FAIL_ALLOC)) {
15110 15105                          break;
15111 15106                  }
15112 15107                  if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15113 15108                      (rval == DEV_INFO_PHYS_DISK)) {
15114 15109                          continue;
15115 15110                  }
15116 15111                  mpt->m_dev_handle = cur_handle;
15117 15112  
15118      -                if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
     15113 +                if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) {
15119 15114                          break;
15120 15115                  }
15121 15116          }
15122 15117  
15123 15118          mutex_exit(&mpt->m_mutex);
15124 15119          return (ptgt);
15125 15120  }
15126 15121  
15127 15122  /*
15128      - * The ptgt->m_sas_wwn contains the wwid for each disk.
     15123 + * The ptgt->m_addr.mta_wwn contains the wwid for each disk.
15129 15124   * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
15130 15125   * If we didn't get a match, we need to get sas page0 for each device, and
15131 15126   * untill we get a match
15132 15127   * If failed, return NULL
15133 15128   */
15134 15129  static mptsas_target_t *
15135      -mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid)
     15130 +mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
15136 15131  {
15137 15132          int             rval = 0;
15138 15133          uint16_t        cur_handle;
15139 15134          uint32_t        page_address;
15140 15135          mptsas_target_t *tmp_tgt = NULL;
     15136 +        mptsas_target_addr_t addr;
15141 15137  
     15138 +        addr.mta_wwn = wwid;
     15139 +        addr.mta_phymask = phymask;
15142 15140          mutex_enter(&mpt->m_mutex);
15143      -        tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
15144      -            &mpt->m_active->m_tgttbl, wwid, phymask);
     15141 +        tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
15145 15142          if (tmp_tgt != NULL) {
15146 15143                  mutex_exit(&mpt->m_mutex);
15147 15144                  return (tmp_tgt);
15148 15145          }
15149 15146  
15150 15147          if (phymask == 0) {
15151 15148                  /*
15152 15149                   * It's IR volume
15153 15150                   */
15154 15151                  rval = mptsas_get_raid_info(mpt);
15155 15152                  if (rval) {
15156      -                        tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
15157      -                            &mpt->m_active->m_tgttbl, wwid, phymask);
     15153 +                        tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
15158 15154                  }
15159 15155                  mutex_exit(&mpt->m_mutex);
15160 15156                  return (tmp_tgt);
15161 15157          }
15162 15158  
15163 15159          if (mpt->m_done_traverse_dev) {
15164 15160                  mutex_exit(&mpt->m_mutex);
15165 15161                  return (NULL);
15166 15162          }
15167 15163  
15168 15164          /* If didn't get a match, come here */
15169 15165          cur_handle = mpt->m_dev_handle;
15170      -        for (; ; ) {
     15166 +        for (;;) {
15171 15167                  tmp_tgt = NULL;
15172 15168                  page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
15173 15169                      MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
15174 15170                  rval = mptsas_get_target_device_info(mpt, page_address,
15175 15171                      &cur_handle, &tmp_tgt);
15176 15172                  if ((rval == DEV_INFO_FAIL_PAGE0) ||
15177 15173                      (rval == DEV_INFO_FAIL_ALLOC)) {
15178 15174                          tmp_tgt = NULL;
15179 15175                          break;
15180 15176                  }
15181 15177                  if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15182 15178                      (rval == DEV_INFO_PHYS_DISK)) {
15183 15179                          continue;
15184 15180                  }
15185 15181                  mpt->m_dev_handle = cur_handle;
15186      -                if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) &&
15187      -                    (tmp_tgt->m_phymask == phymask)) {
     15182 +                if ((tmp_tgt->m_addr.mta_wwn) &&
     15183 +                    (tmp_tgt->m_addr.mta_wwn == wwid) &&
     15184 +                    (tmp_tgt->m_addr.mta_phymask == phymask)) {
15188 15185                          break;
15189 15186                  }
15190 15187          }
15191 15188  
15192 15189          mutex_exit(&mpt->m_mutex);
15193 15190          return (tmp_tgt);
15194 15191  }
15195 15192  
15196 15193  static mptsas_smp_t *
15197      -mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid)
     15194 +mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
15198 15195  {
15199 15196          int             rval = 0;
15200 15197          uint16_t        cur_handle;
15201 15198          uint32_t        page_address;
15202 15199          mptsas_smp_t    smp_node, *psmp = NULL;
     15200 +        mptsas_target_addr_t addr;
15203 15201  
     15202 +        addr.mta_wwn = wwid;
     15203 +        addr.mta_phymask = phymask;
15204 15204          mutex_enter(&mpt->m_mutex);
15205      -        psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl,
15206      -            wwid, phymask);
     15205 +        psmp = refhash_lookup(mpt->m_smp_targets, &addr);
15207 15206          if (psmp != NULL) {
15208 15207                  mutex_exit(&mpt->m_mutex);
15209 15208                  return (psmp);
15210 15209          }
15211 15210  
15212 15211          if (mpt->m_done_traverse_smp) {
15213 15212                  mutex_exit(&mpt->m_mutex);
15214 15213                  return (NULL);
15215 15214          }
15216 15215  
15217 15216          /* If didn't get a match, come here */
15218 15217          cur_handle = mpt->m_smp_devhdl;
15219      -        for (; ; ) {
     15218 +        for (;;) {
15220 15219                  psmp = NULL;
15221 15220                  page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
15222 15221                      MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
15223 15222                  rval = mptsas_get_sas_expander_page0(mpt, page_address,
15224 15223                      &smp_node);
15225 15224                  if (rval != DDI_SUCCESS) {
15226 15225                          break;
15227 15226                  }
15228 15227                  mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
15229      -                psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
     15228 +                psmp = mptsas_smp_alloc(mpt, &smp_node);
15230 15229                  ASSERT(psmp);
15231      -                if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) &&
15232      -                    (psmp->m_phymask == phymask)) {
     15230 +                if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) &&
     15231 +                    (psmp->m_addr.mta_phymask == phymask)) {
15233 15232                          break;
15234 15233                  }
15235 15234          }
15236 15235  
15237 15236          mutex_exit(&mpt->m_mutex);
15238 15237          return (psmp);
15239 15238  }
15240 15239  
15241      -/* helper functions using hash */
15242      -
15243      -/*
15244      - * Can't have duplicate entries for same devhdl,
15245      - * if there are invalid entries, the devhdl should be set to 0xffff
15246      - */
15247      -static void *
15248      -mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl)
15249      -{
15250      -        mptsas_hash_data_t *data;
15251      -
15252      -        data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
15253      -        while (data != NULL) {
15254      -                if (data->devhdl == devhdl) {
15255      -                        break;
15256      -                }
15257      -                data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
15258      -        }
15259      -        return (data);
15260      -}
15261      -
15262 15240  mptsas_target_t *
15263      -mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
     15241 +mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid,
15264 15242      uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
15265 15243  {
15266 15244          mptsas_target_t *tmp_tgt = NULL;
     15245 +        mptsas_target_addr_t addr;
15267 15246  
15268      -        tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
     15247 +        addr.mta_wwn = wwid;
     15248 +        addr.mta_phymask = phymask;
     15249 +        tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
15269 15250          if (tmp_tgt != NULL) {
15270 15251                  NDBG20(("Hash item already exist"));
15271 15252                  tmp_tgt->m_deviceinfo = devinfo;
15272      -                tmp_tgt->m_devhdl = devhdl;
     15253 +                tmp_tgt->m_devhdl = devhdl;     /* XXX - duplicate? */
15273 15254                  return (tmp_tgt);
15274 15255          }
15275 15256          tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
15276 15257          if (tmp_tgt == NULL) {
15277 15258                  cmn_err(CE_WARN, "Fatal, allocated tgt failed");
15278 15259                  return (NULL);
15279 15260          }
15280 15261          tmp_tgt->m_devhdl = devhdl;
15281      -        tmp_tgt->m_sas_wwn = wwid;
     15262 +        tmp_tgt->m_addr.mta_wwn = wwid;
15282 15263          tmp_tgt->m_deviceinfo = devinfo;
15283      -        tmp_tgt->m_phymask = phymask;
     15264 +        tmp_tgt->m_addr.mta_phymask = phymask;
15284 15265          tmp_tgt->m_phynum = phynum;
15285 15266          /* Initialized the tgt structure */
15286 15267          tmp_tgt->m_qfull_retries = QFULL_RETRIES;
15287 15268          tmp_tgt->m_qfull_retry_interval =
15288 15269              drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
15289 15270          tmp_tgt->m_t_throttle = MAX_THROTTLE;
15290 15271  
15291      -        mptsas_hash_add(hashtab, tmp_tgt);
     15272 +        refhash_insert(mpt->m_targets, tmp_tgt);
15292 15273  
15293 15274          return (tmp_tgt);
15294 15275  }
15295 15276  
15296 15277  static void
15297      -mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
15298      -    mptsas_phymask_t phymask)
     15278 +mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
15299 15279  {
15300      -        mptsas_target_t *tmp_tgt;
15301      -        tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
15302      -        if (tmp_tgt == NULL) {
15303      -                cmn_err(CE_WARN, "Tgt not found, nothing to free");
15304      -        } else {
15305      -                kmem_free(tmp_tgt, sizeof (struct mptsas_target));
15306      -        }
     15280 +        dst->m_devhdl = src->m_devhdl;
     15281 +        dst->m_deviceinfo = src->m_deviceinfo;
     15282 +        dst->m_pdevhdl = src->m_pdevhdl;
     15283 +        dst->m_pdevinfo = src->m_pdevinfo;
15307 15284  }
15308 15285  
15309      -/*
15310      - * Return the entry in the hash table
15311      - */
15312 15286  static mptsas_smp_t *
15313      -mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
     15287 +mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
15314 15288  {
15315      -        uint64_t key1 = data->m_sasaddr;
15316      -        mptsas_phymask_t key2 = data->m_phymask;
     15289 +        mptsas_target_addr_t addr;
15317 15290          mptsas_smp_t *ret_data;
15318 15291  
15319      -        ret_data = mptsas_hash_search(hashtab, key1, key2);
     15292 +        addr.mta_wwn = data->m_addr.mta_wwn;
     15293 +        addr.mta_phymask = data->m_addr.mta_phymask;
     15294 +        ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
     15295 +        /*
     15296 +         * If there's already a matching SMP target, update its fields
     15297 +         * in place.  Since the address is not changing, it's safe to do
     15298 +         * this.  We cannot just bcopy() here because the structure we've
     15299 +         * been given has invalid hash links.
     15300 +         */
15320 15301          if (ret_data != NULL) {
15321      -                bcopy(data, ret_data, sizeof (mptsas_smp_t));
     15302 +                mptsas_smp_target_copy(data, ret_data);
15322 15303                  return (ret_data);
15323 15304          }
15324 15305  
15325 15306          ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
15326 15307          bcopy(data, ret_data, sizeof (mptsas_smp_t));
15327      -        mptsas_hash_add(hashtab, ret_data);
     15308 +        refhash_insert(mpt->m_smp_targets, ret_data);
15328 15309          return (ret_data);
15329 15310  }
15330 15311  
15331      -static void
15332      -mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
15333      -    mptsas_phymask_t phymask)
15334      -{
15335      -        mptsas_smp_t *tmp_smp;
15336      -        tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask);
15337      -        if (tmp_smp == NULL) {
15338      -                cmn_err(CE_WARN, "Smp element not found, nothing to free");
15339      -        } else {
15340      -                kmem_free(tmp_smp, sizeof (struct mptsas_smp));
15341      -        }
15342      -}
15343      -
15344 15312  /*
15345      - * Hash operation functions
15346      - * key1 is the sas_wwn, key2 is the phymask
15347      - */
15348      -static void
15349      -mptsas_hash_init(mptsas_hash_table_t *hashtab)
15350      -{
15351      -        if (hashtab == NULL) {
15352      -                return;
15353      -        }
15354      -        bzero(hashtab->head, sizeof (mptsas_hash_node_t) *
15355      -            MPTSAS_HASH_ARRAY_SIZE);
15356      -        hashtab->cur = NULL;
15357      -        hashtab->line = 0;
15358      -}
15359      -
15360      -static void
15361      -mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen)
15362      -{
15363      -        uint16_t line = 0;
15364      -        mptsas_hash_node_t *cur = NULL, *last = NULL;
15365      -
15366      -        if (hashtab == NULL) {
15367      -                return;
15368      -        }
15369      -        for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) {
15370      -                cur = hashtab->head[line];
15371      -                while (cur != NULL) {
15372      -                        last = cur;
15373      -                        cur = cur->next;
15374      -                        kmem_free(last->data, datalen);
15375      -                        kmem_free(last, sizeof (mptsas_hash_node_t));
15376      -                }
15377      -        }
15378      -}
15379      -
15380      -/*
15381      - * You must guarantee the element doesn't exist in the hash table
15382      - * before you call mptsas_hash_add()
15383      - */
15384      -static void
15385      -mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data)
15386      -{
15387      -        uint64_t key1 = ((mptsas_hash_data_t *)data)->key1;
15388      -        mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2;
15389      -        mptsas_hash_node_t **head = NULL;
15390      -        mptsas_hash_node_t *node = NULL;
15391      -
15392      -        if (hashtab == NULL) {
15393      -                return;
15394      -        }
15395      -        ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL);
15396      -        node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP);
15397      -        node->data = data;
15398      -
15399      -        head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
15400      -        if (*head == NULL) {
15401      -                *head = node;
15402      -        } else {
15403      -                node->next = *head;
15404      -                *head = node;
15405      -        }
15406      -}
15407      -
15408      -static void *
15409      -mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
15410      -    mptsas_phymask_t key2)
15411      -{
15412      -        mptsas_hash_node_t **head = NULL;
15413      -        mptsas_hash_node_t *last = NULL, *cur = NULL;
15414      -        mptsas_hash_data_t *data;
15415      -        if (hashtab == NULL) {
15416      -                return (NULL);
15417      -        }
15418      -        head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
15419      -        cur = *head;
15420      -        while (cur != NULL) {
15421      -                data = cur->data;
15422      -                if ((data->key1 == key1) && (data->key2 == key2)) {
15423      -                        if (last == NULL) {
15424      -                                (*head) = cur->next;
15425      -                        } else {
15426      -                                last->next = cur->next;
15427      -                        }
15428      -                        kmem_free(cur, sizeof (mptsas_hash_node_t));
15429      -                        return (data);
15430      -                } else {
15431      -                        last = cur;
15432      -                        cur = cur->next;
15433      -                }
15434      -        }
15435      -        return (NULL);
15436      -}
15437      -
15438      -static void *
15439      -mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
15440      -    mptsas_phymask_t key2)
15441      -{
15442      -        mptsas_hash_node_t *cur = NULL;
15443      -        mptsas_hash_data_t *data;
15444      -        if (hashtab == NULL) {
15445      -                return (NULL);
15446      -        }
15447      -        cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE];
15448      -        while (cur != NULL) {
15449      -                data = cur->data;
15450      -                if ((data->key1 == key1) && (data->key2 == key2)) {
15451      -                        return (data);
15452      -                } else {
15453      -                        cur = cur->next;
15454      -                }
15455      -        }
15456      -        return (NULL);
15457      -}
15458      -
15459      -static void *
15460      -mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos)
15461      -{
15462      -        mptsas_hash_node_t *this = NULL;
15463      -
15464      -        if (hashtab == NULL) {
15465      -                return (NULL);
15466      -        }
15467      -
15468      -        if (pos == MPTSAS_HASH_FIRST) {
15469      -                hashtab->line = 0;
15470      -                hashtab->cur = NULL;
15471      -                this = hashtab->head[0];
15472      -        } else {
15473      -                if (hashtab->cur == NULL) {
15474      -                        return (NULL);
15475      -                } else {
15476      -                        this = hashtab->cur->next;
15477      -                }
15478      -        }
15479      -
15480      -        while (this == NULL) {
15481      -                hashtab->line++;
15482      -                if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
15483      -                        /* the traverse reaches the end */
15484      -                        hashtab->cur = NULL;
15485      -                        return (NULL);
15486      -                } else {
15487      -                        this = hashtab->head[hashtab->line];
15488      -                }
15489      -        }
15490      -        hashtab->cur = this;
15491      -        return (this->data);
15492      -}
15493      -
15494      -/*
15495 15313   * Functions for SGPIO LED support
15496 15314   */
15497 15315  static dev_info_t *
15498 15316  mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
15499 15317  {
15500 15318          dev_info_t      *dip;
15501 15319          int             prop;
15502 15320          dip = e_ddi_hold_devi_by_dev(dev, 0);
15503 15321          if (dip == NULL)
15504 15322                  return (dip);
↓ open down ↓ 62 lines elided ↑ open up ↑
15567 15385           * no other mechanism for LED control.  Targets for which a separate
15568 15386           * enclosure service processor exists should be controlled via ses(7d)
15569 15387           * or sgen(7d).  Furthermore, since such requests can time out, they
15570 15388           * should be made in user context rather than in response to
15571 15389           * asynchronous fabric changes.
15572 15390           *
15573 15391           * In addition, we do not support this operation for RAID volumes,
15574 15392           * since there is no slot associated with them.
15575 15393           */
15576 15394          if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
15577      -            ptgt->m_phymask == 0) {
     15395 +            ptgt->m_addr.mta_phymask == 0) {
15578 15396                  return (ENOTTY);
15579 15397          }
15580 15398  
15581 15399          bzero(&req, sizeof (req));
15582 15400          bzero(&rep, sizeof (rep));
15583 15401  
15584 15402          req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
15585 15403          req.Action = act;
15586 15404          req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
15587 15405          req.EnclosureHandle = LE_16(ptgt->m_enclosure);
↓ open down ↓ 91 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX