Print this page
NEX-19691 Unsuccessful mpt_sas IOC reset leads to the panic in no I/O to the pool - days later
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-20282 Add disk target queue depth tunable to mpt_sas
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-19821 All SAS paths down sometimes does not cause panic and trigger automatic HA failover
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
9048 mpt_sas should not require targets to send SEP messages
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Gordon Ross <gwr@nexenta.com>
NEX-17446 cleanup of hot unplugged disks fails intermittently
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-17944 HBA drivers don't need the redundant devfs_clean step
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-17006 backport mpt_sas tri-mode parts support change
9044 Need support for mpt_sas tri-mode parts
9045 Clean up mpt_sas compiler warnings
9046 mptsas_handle_topo_change can return without its locks held
9047 workaround SAS3408 firmware issue
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com>
Reviewed by: Albert Lee <trisk@forkgnu.org>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-16174 scsi error messages should go to system log only
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-2100 vmem_hash_delete(ffffff5b5dee0000, 0, 1): bad free
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Marcel Telka <marcel@telka.sk>
NEX-6064 Son of single bad device causes outage a.k.a one disk fault
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-4418 SATA inquiry property generation doesn't work as advertised
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3988 Single bad device causes outage a.k.a one disk fault
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3717 mptsas doesn't handle timeouts in mptsas_get_sata_guid()
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-2103 12G mpt_sas needs additional minor enhancements
Revert OS-73 do not do IO complettions in the ISR
NEX-1889 mpt_sas should support 12G HBAs
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>
backout 4500 mptsas_hash_traverse() is unsafe, leads to missing devices
4403 mpt_sas panic when pulling a drive
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Andy Giles <illumos@ang.homedns.org>
Approved by: Robert Mustacchi <rm@joyent.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>
NEX-1052 mptsas_do_passthru() does triggers assertion
OS-126 Creating a LUN for retired device results in sysevent loop
OS-91 mptsas does inquiry without setting pkt_time
OS-73 do not do IO complettions in the ISR
OS-61 Need ability for fault injection in mptsas
OS-87 pkt_reason not set accordingly when mpt_sas times out commands
OS-84 slow-io changes cause assertion failure
OS-62 slow io error detector is needed.
OS-59 remove automated target removal mechanism from mpt_sas.
Fix up some merges where we wanted the upstream version.
re #12927 rb4203 LSI 2008 mpt_sas
re #9517 rb4120 After single disk fault patch installed single disk fault still causes process hangs (fix gcc build)
re #9517 rb4120 After single disk fault patch installed single disk fault still causes process hangs
re #8346 rb2639 KT disk failures (fix lint/cstyle)
re #10443 rb3479 3.1.3 crash: BAD TRAP: type=e (#pf Page fault)
re #8346 rb2639 KT disk failures
re #7364 rb2201 "hddisco" hangs after unplugging both cables from JBOD (and NMS too)
re #8346 rb2639 KT disk failures
re #9636 rb2836 - mpt_sas should attempt an MUR reset at attach time.
--HG--
branch : stable-4.0
re #9636 rb2836 - mpt_sas should attempt an MUR reset at attach time.
re #7550 rb2134 lint-clean nza-kernel
re #6530 mpt_sas crash when more than 1 Initiator involved - ie HA
re #6834 rb1773 less verbosity in nfs4_rnode
re #6833 rb1771 less verbosity in mptsas

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 ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  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      - * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
       24 + * Copyright 2019 Nexenta Systems, Inc.
  25   25   * Copyright (c) 2017, Joyent, Inc.
  26   26   * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
  27   27   * Copyright (c) 2014, Tegile Systems Inc. All rights reserved.
  28   28   */
  29   29  
  30   30  /*
  31   31   * Copyright (c) 2000 to 2010, LSI Corporation.
  32   32   * All rights reserved.
  33   33   *
  34   34   * Redistribution and use in source and binary forms of all code within
↓ open down ↓ 37 lines elided ↑ open up ↑
  72   72  #include <sys/file.h>
  73   73  #include <sys/policy.h>
  74   74  #include <sys/model.h>
  75   75  #include <sys/sysevent.h>
  76   76  #include <sys/sysevent/eventdefs.h>
  77   77  #include <sys/sysevent/dr.h>
  78   78  #include <sys/sata/sata_defs.h>
  79   79  #include <sys/sata/sata_hba.h>
  80   80  #include <sys/scsi/generic/sas.h>
  81   81  #include <sys/scsi/impl/scsi_sas.h>
       82 +#include <sys/sdt.h>
       83 +#include <sys/mdi_impldefs.h>
  82   84  
  83   85  #pragma pack(1)
  84   86  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
  85   87  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  86   88  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  87   89  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  88   90  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  89   91  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  90   92  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
  91   93  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
↓ open down ↓ 3 lines elided ↑ open up ↑
  95   97   * private header files.
  96   98   *
  97   99   */
  98  100  #include <sys/scsi/impl/scsi_reset_notify.h>
  99  101  #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
 100  102  #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
 101  103  #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
 102  104  #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
 103  105  #include <sys/raidioctl.h>
 104  106  
 105      -#include <sys/fs/dv_node.h>     /* devfs_clean */
 106      -
 107  107  /*
 108  108   * FMA header files
 109  109   */
 110  110  #include <sys/ddifm.h>
 111  111  #include <sys/fm/protocol.h>
 112  112  #include <sys/fm/util.h>
 113  113  #include <sys/fm/io/ddi.h>
 114  114  
 115  115  /*
 116  116   * autoconfiguration data and routines.
↓ open down ↓ 233 lines elided ↑ open up ↑
 350  350  static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
 351  351      mptsas_phymask_t phymask, uint64_t wwid);
 352  352  
 353  353  static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
 354  354      uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
 355  355  
 356  356  static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
 357  357      uint16_t *handle, mptsas_target_t **pptgt);
 358  358  static void mptsas_update_phymask(mptsas_t *mpt);
 359  359  
 360      -static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
      360 +static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_enclosure_t *mep,
      361 +    uint16_t idx);
      362 +static int mptsas_send_sep(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx,
 361  363      uint32_t *status, uint8_t cmd);
 362  364  static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
 363  365      mptsas_phymask_t *phymask);
 364  366  static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
 365  367      mptsas_phymask_t phymask);
 366      -static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
 367  368  
 368  369  
 369  370  /*
 370  371   * Enumeration / DR functions
 371  372   */
 372  373  static void mptsas_config_all(dev_info_t *pdip);
 373  374  static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
 374  375      dev_info_t **lundip);
 375  376  static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
 376  377      dev_info_t **lundip);
↓ open down ↓ 12 lines elided ↑ open up ↑
 389  390      dev_info_t **dip, mptsas_target_t *ptgt, int lun);
 390  391  
 391  392  static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
 392  393      char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
 393  394  static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
 394  395      char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
 395  396      int lun);
 396  397  
 397  398  static void mptsas_offline_missed_luns(dev_info_t *pdip,
 398  399      uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
 399      -static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
 400      -    mdi_pathinfo_t *rpip, uint_t flags);
      400 +static int mptsas_offline_lun(dev_info_t *rdip, mdi_pathinfo_t *rpip);
 401  401  
 402  402  static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
 403  403      dev_info_t **smp_dip);
 404      -static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
 405      -    uint_t flags);
      404 +static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node);
 406  405  
 407  406  static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
 408  407      int mode, int *rval);
 409  408  static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
 410  409      int mode, int *rval);
 411  410  static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
 412  411      int mode, int *rval);
 413  412  static void mptsas_record_event(void *args);
 414  413  static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
 415  414      int mode);
↓ open down ↓ 46 lines elided ↑ open up ↑
 462  461   */
 463  462  extern dev_info_t       *scsi_vhci_dip;
 464  463  
 465  464  /*
 466  465   * Tunable timeout value for Inquiry VPD page 0x83
 467  466   * By default the value is 30 seconds.
 468  467   */
 469  468  int mptsas_inq83_retry_timeout = 30;
 470  469  
 471  470  /*
      471 + * Tunable for default SCSI pkt timeout. Defaults to 5 seconds, which should
      472 + * be plenty for INQUIRY and REPORT_LUNS, which are the only commands currently
      473 + * issued by mptsas directly.
      474 + */
      475 +int mptsas_scsi_pkt_time = 5;
      476 +
      477 +/*
 472  478   * This is used to allocate memory for message frame storage, not for
 473  479   * data I/O DMA. All message frames must be stored in the first 4G of
 474  480   * physical memory.
 475  481   */
 476  482  ddi_dma_attr_t mptsas_dma_attrs = {
 477  483          DMA_ATTR_V0,    /* attribute layout version             */
 478  484          0x0ull,         /* address low - should be 0 (longlong) */
 479  485          0xffffffffull,  /* address high - 32-bit max range      */
 480  486          0x00ffffffull,  /* count max - max DMA object size      */
 481  487          4,              /* allocation alignment requirements    */
↓ open down ↓ 243 lines elided ↑ open up ↑
 725  731  static int
 726  732  mptsas_target_eval_devhdl(const void *op, void *arg)
 727  733  {
 728  734          uint16_t dh = *(uint16_t *)arg;
 729  735          const mptsas_target_t *tp = op;
 730  736  
 731  737          return ((int)tp->m_devhdl - (int)dh);
 732  738  }
 733  739  
 734  740  static int
 735      -mptsas_target_eval_slot(const void *op, void *arg)
 736      -{
 737      -        mptsas_led_control_t *lcp = arg;
 738      -        const mptsas_target_t *tp = op;
 739      -
 740      -        if (tp->m_enclosure != lcp->Enclosure)
 741      -                return ((int)tp->m_enclosure - (int)lcp->Enclosure);
 742      -
 743      -        return ((int)tp->m_slot_num - (int)lcp->Slot);
 744      -}
 745      -
 746      -static int
 747  741  mptsas_target_eval_nowwn(const void *op, void *arg)
 748  742  {
 749  743          uint8_t phy = *(uint8_t *)arg;
 750  744          const mptsas_target_t *tp = op;
 751  745  
 752  746          if (tp->m_addr.mta_wwn != 0)
 753  747                  return (-1);
 754  748  
 755  749          return ((int)tp->m_phynum - (int)phy);
 756  750  }
↓ open down ↓ 440 lines elided ↑ open up ↑
1197 1191                  return (DDI_FAILURE);
1198 1192  
1199 1193          }
1200 1194  
1201 1195          instance = ddi_get_instance(dip);
1202 1196  
1203 1197          /*
1204 1198           * Allocate softc information.
1205 1199           */
1206 1200          if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) {
1207      -                mptsas_log(NULL, CE_WARN,
1208      -                    "mptsas%d: cannot allocate soft state", instance);
     1201 +                mptsas_log(NULL, CE_WARN, "cannot allocate soft state");
1209 1202                  goto fail;
1210 1203          }
1211 1204  
1212 1205          mpt = ddi_get_soft_state(mptsas_state, instance);
1213 1206  
1214 1207          if (mpt == NULL) {
1215      -                mptsas_log(NULL, CE_WARN,
1216      -                    "mptsas%d: cannot get soft state", instance);
     1208 +                mptsas_log(NULL, CE_WARN, "cannot get soft state");
1217 1209                  goto fail;
1218 1210          }
1219 1211  
1220 1212          /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
1221 1213          scsi_size_clean(dip);
1222 1214  
1223 1215          mpt->m_dip = dip;
1224 1216          mpt->m_instance = instance;
1225 1217  
1226 1218          /* Make a per-instance copy of the structures */
↓ open down ↓ 64 lines elided ↑ open up ↑
1291 1283                  goto fail;
1292 1284          }
1293 1285          dr_taskq_create++;
1294 1286  
1295 1287          mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1296 1288              0, "mptsas_doneq_thread_threshold_prop", 10);
1297 1289          mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1298 1290              0, "mptsas_doneq_length_threshold_prop", 8);
1299 1291          mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1300 1292              0, "mptsas_doneq_thread_n_prop", 8);
     1293 +        mpt->m_max_tune_throttle = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
     1294 +            0, "mptsas_max_throttle", MAX_THROTTLE);
1301 1295  
     1296 +        /*
     1297 +         *  Error check to make sure value is withing range. If nothing
     1298 +         *  is set default to original design value.
     1299 +         */
     1300 +        if (mpt->m_max_tune_throttle < THROTTLE_LO) {
     1301 +                mpt->m_max_tune_throttle = MAX_THROTTLE;
     1302 +        } else if (mpt->m_max_tune_throttle > THROTTLE_HI) {
     1303 +                mpt->m_max_tune_throttle = THROTTLE_HI;
     1304 +        }
     1305 +
1302 1306          if (mpt->m_doneq_thread_n) {
1303 1307                  cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL);
1304 1308                  mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL);
1305 1309  
1306 1310                  mutex_enter(&mpt->m_doneq_mutex);
1307 1311                  mpt->m_doneq_thread_id =
1308 1312                      kmem_zalloc(sizeof (mptsas_doneq_thread_list_t)
1309 1313                      * mpt->m_doneq_thread_n, KM_SLEEP);
1310 1314  
1311 1315                  for (j = 0; j < mpt->m_doneq_thread_n; j++) {
↓ open down ↓ 37 lines elided ↑ open up ↑
1349 1353                  mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1350 1354                      NULL, MUTEX_DRIVER,
1351 1355                      DDI_INTR_PRI(mpt->m_intr_pri));
1352 1356          }
1353 1357  
1354 1358          cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1355 1359          cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1356 1360          cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1357 1361          cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1358 1362          cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1359      -        cv_init(&mpt->m_extreq_sense_refcount_cv, NULL, CV_DRIVER, NULL);
1360 1363          mutex_init_done++;
1361 1364  
     1365 +#ifdef MPTSAS_FAULTINJECTION
     1366 +        TAILQ_INIT(&mpt->m_fminj_cmdq);
     1367 +#endif
     1368 +
1362 1369          mutex_enter(&mpt->m_mutex);
1363 1370          /*
1364 1371           * Initialize power management component
1365 1372           */
1366 1373          if (mpt->m_options & MPTSAS_OPT_PM) {
1367 1374                  if (mptsas_init_pm(mpt)) {
1368 1375                          mutex_exit(&mpt->m_mutex);
1369 1376                          mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1370 1377                              "failed");
1371 1378                          goto fail;
↓ open down ↓ 70 lines elided ↑ open up ↑
1442 1449          enc_attach_setup++;
1443 1450  
1444 1451          if (mptsas_cache_create(mpt) == FALSE)
1445 1452                  goto fail;
1446 1453  
1447 1454          mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
1448 1455              dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY);
1449 1456          if (mpt->m_scsi_reset_delay == 0) {
1450 1457                  mptsas_log(mpt, CE_NOTE,
1451 1458                      "scsi_reset_delay of 0 is not recommended,"
1452      -                    " resetting to SCSI_DEFAULT_RESET_DELAY\n");
     1459 +                    " resetting to SCSI_DEFAULT_RESET_DELAY");
1453 1460                  mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1454 1461          }
1455 1462  
1456 1463          /*
1457 1464           * Initialize the wait and done FIFO queue
1458 1465           */
1459 1466          mpt->m_donetail = &mpt->m_doneq;
1460 1467          mpt->m_waitqtail = &mpt->m_waitq;
1461 1468          mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
1462 1469          mpt->m_tx_draining = 0;
↓ open down ↓ 179 lines elided ↑ open up ↑
1642 1649                          mutex_destroy(&mpt->m_mutex);
1643 1650                          for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1644 1651                                  mutex_destroy(
1645 1652                                      &mpt->m_phy_info[i].smhba_info.phy_mutex);
1646 1653                          }
1647 1654                          cv_destroy(&mpt->m_cv);
1648 1655                          cv_destroy(&mpt->m_passthru_cv);
1649 1656                          cv_destroy(&mpt->m_fw_cv);
1650 1657                          cv_destroy(&mpt->m_config_cv);
1651 1658                          cv_destroy(&mpt->m_fw_diag_cv);
1652      -                        cv_destroy(&mpt->m_extreq_sense_refcount_cv);
1653 1659                  }
1654 1660  
1655 1661                  if (map_setup) {
1656 1662                          mptsas_cfg_fini(mpt);
1657 1663                  }
1658 1664                  if (config_setup) {
1659 1665                          mptsas_config_space_fini(mpt);
1660 1666                  }
1661 1667                  mptsas_free_handshake_msg(mpt);
1662 1668                  mptsas_hba_fini(mpt);
↓ open down ↓ 227 lines elided ↑ open up ↑
1890 1896          /*
1891 1897           * Still have pathinfo child, should not detach mpt driver
1892 1898           */
1893 1899          if (scsi_hba_iport_unit_address(dip)) {
1894 1900                  if (mpt->m_mpxio_enable) {
1895 1901                          /*
1896 1902                           * MPxIO enabled for the iport
1897 1903                           */
1898 1904                          ndi_devi_enter(scsi_vhci_dip, &circ1);
1899 1905                          ndi_devi_enter(dip, &circ);
1900      -                        while (pip = mdi_get_next_client_path(dip, NULL)) {
     1906 +                        while ((pip = mdi_get_next_client_path(dip, NULL)) !=
     1907 +                            NULL) {
1901 1908                                  if (mdi_pi_free(pip, 0) == MDI_SUCCESS) {
1902 1909                                          continue;
1903 1910                                  }
1904 1911                                  ndi_devi_exit(dip, circ);
1905 1912                                  ndi_devi_exit(scsi_vhci_dip, circ1);
1906 1913                                  NDBG12(("detach failed because of "
1907 1914                                      "outstanding path info"));
1908 1915                                  return (DDI_FAILURE);
1909 1916                          }
1910 1917                          ndi_devi_exit(dip, circ);
↓ open down ↓ 6 lines elided ↑ open up ↑
1917 1924                  return (DDI_SUCCESS);
1918 1925          }
1919 1926  
1920 1927          /* Make sure power level is D0 before accessing registers */
1921 1928          if (mpt->m_options & MPTSAS_OPT_PM) {
1922 1929                  (void) pm_busy_component(dip, 0);
1923 1930                  if (mpt->m_power_level != PM_LEVEL_D0) {
1924 1931                          if (pm_raise_power(dip, 0, PM_LEVEL_D0) !=
1925 1932                              DDI_SUCCESS) {
1926 1933                                  mptsas_log(mpt, CE_WARN,
1927      -                                    "mptsas%d: Raise power request failed.",
1928      -                                    mpt->m_instance);
     1934 +                                    "raise power request failed");
1929 1935                                  (void) pm_idle_component(dip, 0);
1930 1936                                  return (DDI_FAILURE);
1931 1937                          }
1932 1938                  }
1933 1939          }
1934 1940  
1935 1941          /*
1936 1942           * Send RAID action system shutdown to sync IR.  After action, send a
1937 1943           * Message Unit Reset. Since after that DMA resource will be freed,
1938 1944           * set ioc to READY state will avoid HBA initiated DMA operation.
↓ open down ↓ 105 lines elided ↑ open up ↑
2044 2050          /* deallocate everything that was allocated in mptsas_attach */
2045 2051          mptsas_cache_destroy(mpt);
2046 2052  
2047 2053          mptsas_hba_fini(mpt);
2048 2054          mptsas_cfg_fini(mpt);
2049 2055  
2050 2056          /* Lower the power informing PM Framework */
2051 2057          if (mpt->m_options & MPTSAS_OPT_PM) {
2052 2058                  if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
2053 2059                          mptsas_log(mpt, CE_WARN,
2054      -                            "!mptsas%d: Lower power request failed "
2055      -                            "during detach, ignoring.",
2056      -                            mpt->m_instance);
     2060 +                            "lower power request failed during detach, "
     2061 +                            "ignoring");
2057 2062          }
2058 2063  
2059 2064          mutex_destroy(&mpt->m_tx_waitq_mutex);
2060 2065          mutex_destroy(&mpt->m_passthru_mutex);
2061 2066          mutex_destroy(&mpt->m_mutex);
2062 2067          for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
2063 2068                  mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex);
2064 2069          }
2065 2070          cv_destroy(&mpt->m_cv);
2066 2071          cv_destroy(&mpt->m_passthru_cv);
2067 2072          cv_destroy(&mpt->m_fw_cv);
2068 2073          cv_destroy(&mpt->m_config_cv);
2069 2074          cv_destroy(&mpt->m_fw_diag_cv);
2070      -        cv_destroy(&mpt->m_extreq_sense_refcount_cv);
2071 2075  
     2076 +#ifdef MPTSAS_FAULTINJECTION
     2077 +        ASSERT(TAILQ_EMPTY(&mpt->m_fminj_cmdq));
     2078 +#endif
     2079 +
2072 2080          mptsas_smp_teardown(mpt);
2073 2081          mptsas_enc_teardown(mpt);
2074 2082          mptsas_hba_teardown(mpt);
2075 2083  
2076 2084          mptsas_config_space_fini(mpt);
2077 2085  
2078 2086          mptsas_free_handshake_msg(mpt);
2079 2087  
2080 2088          mptsas_fm_fini(mpt);
2081 2089          ddi_soft_state_free(mptsas_state, ddi_get_instance(dip));
↓ open down ↓ 240 lines elided ↑ open up ↑
2322 2330  
2323 2331  static int
2324 2332  mptsas_enc_setup(mptsas_t *mpt)
2325 2333  {
2326 2334          list_create(&mpt->m_enclosures, sizeof (mptsas_enclosure_t),
2327 2335              offsetof(mptsas_enclosure_t, me_link));
2328 2336          return (TRUE);
2329 2337  }
2330 2338  
2331 2339  static void
     2340 +mptsas_enc_free(mptsas_enclosure_t *mep)
     2341 +{
     2342 +        if (mep == NULL)
     2343 +                return;
     2344 +        if (mep->me_slotleds != NULL) {
     2345 +                VERIFY3U(mep->me_nslots, >, 0);
     2346 +                kmem_free(mep->me_slotleds, sizeof (uint8_t) * mep->me_nslots);
     2347 +        }
     2348 +        kmem_free(mep, sizeof (mptsas_enclosure_t));
     2349 +}
     2350 +
     2351 +static void
2332 2352  mptsas_enc_teardown(mptsas_t *mpt)
2333 2353  {
2334 2354          mptsas_enclosure_t *mep;
2335 2355  
2336 2356          while ((mep = list_remove_head(&mpt->m_enclosures)) != NULL) {
2337      -                kmem_free(mep, sizeof (mptsas_enclosure_t));
     2357 +                mptsas_enc_free(mep);
2338 2358          }
2339 2359          list_destroy(&mpt->m_enclosures);
2340 2360  }
2341 2361  
2342 2362  static mptsas_enclosure_t *
2343 2363  mptsas_enc_lookup(mptsas_t *mpt, uint16_t hdl)
2344 2364  {
2345 2365          mptsas_enclosure_t *mep;
2346 2366  
2347 2367          ASSERT(MUTEX_HELD(&mpt->m_mutex));
↓ open down ↓ 116 lines elided ↑ open up ↑
2464 2484                                  return (DDI_FAILURE);
2465 2485                          }
2466 2486                  }
2467 2487                  mpt->m_power_level = PM_LEVEL_D0;
2468 2488                  break;
2469 2489          case PM_LEVEL_D3:
2470 2490                  NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2471 2491                  MPTSAS_POWER_OFF(mpt);
2472 2492                  break;
2473 2493          default:
2474      -                mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2475      -                    mpt->m_instance, level);
     2494 +                mptsas_log(mpt, CE_WARN, "unknown power level <%x>", level);
2476 2495                  rval = DDI_FAILURE;
2477 2496                  break;
2478 2497          }
2479 2498          mutex_exit(&mpt->m_mutex);
2480 2499          return (rval);
2481 2500  }
2482 2501  
2483 2502  /*
2484 2503   * Initialize configuration space and figure out which
2485 2504   * chip and revison of the chip the mpt driver is using.
↓ open down ↓ 208 lines elided ↑ open up ↑
2694 2713  
2695 2714  static int
2696 2715  mptsas_alloc_sense_bufs(mptsas_t *mpt)
2697 2716  {
2698 2717          ddi_dma_attr_t          sense_dma_attrs;
2699 2718          caddr_t                 memp;
2700 2719          ddi_dma_cookie_t        cookie;
2701 2720          size_t                  mem_size;
2702 2721          int                     num_extrqsense_bufs;
2703 2722  
2704      -        ASSERT(mpt->m_extreq_sense_refcount == 0);
2705      -
2706 2723          /*
2707 2724           * re-alloc when it has already alloced
2708 2725           */
2709 2726          if (mpt->m_dma_req_sense_hdl) {
2710 2727                  rmfreemap(mpt->m_erqsense_map);
2711 2728                  mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl,
2712 2729                      &mpt->m_acc_req_sense_hdl);
2713 2730          }
2714 2731  
2715 2732          /*
↓ open down ↓ 322 lines elided ↑ open up ↑
3038 3055                   * Stick in the address of the form "wWWN,LUN"
3039 3056                   */
3040 3057                  reallen = snprintf(name, len, "%s,%x", sas_wwn, lun);
3041 3058                  ddi_prop_free(sas_wwn);
3042 3059          } else {
3043 3060                  return (DDI_FAILURE);
3044 3061          }
3045 3062  
3046 3063          ASSERT(reallen < len);
3047 3064          if (reallen >= len) {
3048      -                mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter "
     3065 +                mptsas_log(0, CE_WARN, "mptsas_get_name: name parameter "
3049 3066                      "length too small, it needs to be %d bytes", reallen + 1);
3050 3067          }
3051 3068          return (DDI_SUCCESS);
3052 3069  }
3053 3070  
3054 3071  /*
3055 3072   * tran_tgt_init(9E) - target device instance initialization
3056 3073   */
3057 3074  static int
3058 3075  mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
↓ open down ↓ 26 lines elided ↑ open up ↑
3085 3102          ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
3086 3103  
3087 3104          NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
3088 3105              (void *)hba_dip, (void *)tgt_dip, lun));
3089 3106  
3090 3107          if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
3091 3108                  (void) ndi_merge_node(tgt_dip, mptsas_name_child);
3092 3109                  ddi_set_name_addr(tgt_dip, NULL);
3093 3110                  return (DDI_FAILURE);
3094 3111          }
     3112 +
3095 3113          /*
3096      -         * phymask is 0 means the virtual port for RAID
     3114 +         * The phymask exists if the port is active, otherwise
     3115 +         * nothing to do.
3097 3116           */
     3117 +        if (ddi_prop_exists(DDI_DEV_T_ANY, hba_dip,
     3118 +            DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "phymask") == 0)
     3119 +                return (DDI_FAILURE);
     3120 +
3098 3121          phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
3099 3122              "phymask", 0);
     3123 +
3100 3124          if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
3101 3125                  if ((pip = (void *)(sd->sd_private)) == NULL) {
3102 3126                          /*
3103 3127                           * Very bad news if this occurs. Somehow scsi_vhci has
3104 3128                           * lost the pathinfo node for this target.
3105 3129                           */
3106 3130                          return (DDI_NOT_WELL_FORMED);
3107 3131                  }
3108 3132  
3109 3133                  if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
3110 3134                      DDI_PROP_SUCCESS) {
3111      -                        mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
     3135 +                        mptsas_log(mpt, CE_WARN, "Get lun property failed");
3112 3136                          return (DDI_FAILURE);
3113 3137                  }
3114 3138  
3115 3139                  if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
3116 3140                      &psas_wwn) == MDI_SUCCESS) {
3117 3141                          if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
3118 3142                                  sas_wwn = 0;
3119 3143                          }
3120 3144                          (void) mdi_prop_free(psas_wwn);
3121 3145                  }
↓ open down ↓ 12 lines elided ↑ open up ↑
3134 3158                  }
3135 3159          }
3136 3160  
3137 3161          ASSERT((sas_wwn != 0) || (phymask != 0));
3138 3162          addr.mta_wwn = sas_wwn;
3139 3163          addr.mta_phymask = phymask;
3140 3164          mutex_enter(&mpt->m_mutex);
3141 3165          ptgt = refhash_lookup(mpt->m_targets, &addr);
3142 3166          mutex_exit(&mpt->m_mutex);
3143 3167          if (ptgt == NULL) {
3144      -                mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
     3168 +                mptsas_log(mpt, CE_WARN, "tgt_init: target doesn't exist or "
3145 3169                      "gone already! phymask:%x, saswwn %"PRIx64, phymask,
3146 3170                      sas_wwn);
3147 3171                  return (DDI_FAILURE);
3148 3172          }
3149 3173          if (hba_tran->tran_tgt_private == NULL) {
3150 3174                  tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
3151 3175                      KM_SLEEP);
3152 3176                  tgt_private->t_lun = lun;
3153 3177                  tgt_private->t_private = ptgt;
3154 3178                  hba_tran->tran_tgt_private = tgt_private;
↓ open down ↓ 24 lines elided ↑ open up ↑
3179 3203                   */
3180 3204                  inq89 = kmem_zalloc(inq89_len, KM_SLEEP);
3181 3205                  rval = mptsas_inquiry(mpt, ptgt, 0, 0x89,
3182 3206                      inq89, inq89_len, &reallen, 1);
3183 3207  
3184 3208                  if (rval != 0) {
3185 3209                          if (inq89 != NULL) {
3186 3210                                  kmem_free(inq89, inq89_len);
3187 3211                          }
3188 3212  
3189      -                        mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
     3213 +                        mptsas_log(mpt, CE_WARN, "mptsas request inquiry page "
3190 3214                              "0x89 for SATA target:%x failed!", ptgt->m_devhdl);
3191 3215                          return (DDI_SUCCESS);
3192 3216                  }
3193 3217                  sid = (void *)(&inq89[60]);
3194 3218  
3195 3219                  swab(sid->ai_model, model, SATA_ID_MODEL_LEN);
3196 3220                  swab(sid->ai_fw, fw, SATA_ID_FW_LEN);
3197 3221  
3198 3222                  model[SATA_ID_MODEL_LEN] = 0;
3199 3223                  fw[SATA_ID_FW_LEN] = 0;
↓ open down ↓ 232 lines elided ↑ open up ↑
3432 3456                           * return TRAN_FATAL_ERROR.
3433 3457                           */
3434 3458                          return (TRAN_FATAL_ERROR);
3435 3459                  }
3436 3460          }
3437 3461          rval = mptsas_accept_pkt(mpt, cmd);
3438 3462  
3439 3463          return (rval);
3440 3464  }
3441 3465  
     3466 +#ifdef MPTSAS_FAULTINJECTION
     3467 +static void
     3468 +mptsas_fminj_move_cmd_to_doneq(mptsas_t *mpt, mptsas_cmd_t *cmd,
     3469 +    uchar_t reason, uint_t stat)
     3470 +{
     3471 +        struct scsi_pkt *pkt = cmd->cmd_pkt;
     3472 +
     3473 +        TAILQ_REMOVE(&mpt->m_fminj_cmdq, cmd, cmd_active_link);
     3474 +
     3475 +        /* Setup reason/statistics. */
     3476 +        pkt->pkt_reason = reason;
     3477 +        pkt->pkt_statistics = stat;
     3478 +
     3479 +        cmd->cmd_active_expiration = 0;
     3480 +
     3481 +        /* Move command to doneque. */
     3482 +        cmd->cmd_linkp = NULL;
     3483 +        cmd->cmd_flags |= CFLAG_FINISHED;
     3484 +        cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
     3485 +
     3486 +        *mpt->m_donetail = cmd;
     3487 +        mpt->m_donetail = &cmd->cmd_linkp;
     3488 +        mpt->m_doneq_len++;
     3489 +}
     3490 +
     3491 +static void
     3492 +mptsas_fminj_move_tgt_to_doneq(mptsas_t *mpt, ushort_t target,
     3493 +    uchar_t reason, uint_t stat)
     3494 +{
     3495 +        mptsas_cmd_t *cmd;
     3496 +
     3497 +        ASSERT(mutex_owned(&mpt->m_mutex));
     3498 +
     3499 +        if (!TAILQ_EMPTY(&mpt->m_fminj_cmdq)) {
     3500 +                cmd = TAILQ_FIRST(&mpt->m_fminj_cmdq);
     3501 +                ASSERT(cmd != NULL);
     3502 +
     3503 +                while (cmd != NULL) {
     3504 +                        mptsas_cmd_t *next = TAILQ_NEXT(cmd, cmd_active_link);
     3505 +
     3506 +                        if (Tgt(cmd) == target) {
     3507 +                                mptsas_fminj_move_cmd_to_doneq(mpt, cmd,
     3508 +                                    reason, stat);
     3509 +                        }
     3510 +                        cmd = next;
     3511 +                }
     3512 +        }
     3513 +}
     3514 +
     3515 +static void
     3516 +mptsas_fminj_watchsubr(mptsas_t *mpt,
     3517 +    struct mptsas_active_cmdq *expired)
     3518 +{
     3519 +        mptsas_cmd_t *cmd;
     3520 +
     3521 +        ASSERT(mutex_owned(&mpt->m_mutex));
     3522 +
     3523 +        if (!TAILQ_EMPTY(&mpt->m_fminj_cmdq)) {
     3524 +                hrtime_t timestamp = gethrtime();
     3525 +
     3526 +                cmd = TAILQ_FIRST(&mpt->m_fminj_cmdq);
     3527 +                ASSERT(cmd != NULL);
     3528 +
     3529 +                while (cmd != NULL) {
     3530 +                        mptsas_cmd_t *next = TAILQ_NEXT(cmd, cmd_active_link);
     3531 +
     3532 +                        if (cmd->cmd_active_expiration <= timestamp) {
     3533 +                                struct scsi_pkt *pkt = cmd->cmd_pkt;
     3534 +
     3535 +                                DTRACE_PROBE1(mptsas__command__timeout,
     3536 +                                    struct scsi_pkt *, pkt);
     3537 +
     3538 +                                /* Setup proper flags. */
     3539 +                                pkt->pkt_reason = CMD_TIMEOUT;
     3540 +                                pkt->pkt_statistics = (STAT_TIMEOUT |
     3541 +                                    STAT_DEV_RESET);
     3542 +                                cmd->cmd_active_expiration = 0;
     3543 +
     3544 +                                TAILQ_REMOVE(&mpt->m_fminj_cmdq, cmd,
     3545 +                                    cmd_active_link);
     3546 +                                TAILQ_INSERT_TAIL(expired, cmd,
     3547 +                                    cmd_active_link);
     3548 +                        }
     3549 +                        cmd = next;
     3550 +                }
     3551 +        }
     3552 +}
     3553 +
3442 3554  static int
     3555 +mptsas_fminject(mptsas_t *mpt, mptsas_cmd_t *cmd)
     3556 +{
     3557 +        struct scsi_pkt *pkt = cmd->cmd_pkt;
     3558 +
     3559 +        ASSERT(mutex_owned(&mpt->m_mutex));
     3560 +
     3561 +        if (pkt->pkt_flags & FLAG_PKT_TIMEOUT) {
     3562 +                if (((pkt->pkt_flags & FLAG_NOINTR) == 0) &&
     3563 +                    (pkt->pkt_comp != NULL)) {
     3564 +                        pkt->pkt_state = (STATE_GOT_BUS|STATE_GOT_TARGET|
     3565 +                            STATE_SENT_CMD);
     3566 +                        cmd->cmd_active_expiration =
     3567 +                            gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC;
     3568 +                        TAILQ_INSERT_TAIL(&mpt->m_fminj_cmdq,
     3569 +                            cmd, cmd_active_link);
     3570 +                        return (0);
     3571 +                }
     3572 +        }
     3573 +        return (-1);
     3574 +}
     3575 +#endif /* MPTSAS_FAULTINJECTION */
     3576 +
     3577 +static int
3443 3578  mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3444 3579  {
3445 3580          int             rval = TRAN_ACCEPT;
3446 3581          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3447 3582  
3448 3583          NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3449 3584  
3450 3585          ASSERT(mutex_owned(&mpt->m_mutex));
3451 3586  
3452 3587          if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
↓ open down ↓ 8 lines elided ↑ open up ↑
3461 3596           * reset the throttle if we were draining
3462 3597           */
3463 3598          if ((ptgt->m_t_ncmds == 0) &&
3464 3599              (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3465 3600                  NDBG23(("reset throttle"));
3466 3601                  ASSERT(ptgt->m_reset_delay == 0);
3467 3602                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3468 3603          }
3469 3604  
3470 3605          /*
3471      -         * If HBA is being reset, the DevHandles are being re-initialized,
3472      -         * which means that they could be invalid even if the target is still
3473      -         * attached.  Check if being reset and if DevHandle is being
3474      -         * re-initialized.  If this is the case, return BUSY so the I/O can be
3475      -         * retried later.
     3606 +         * If HBA is being reset, the device handles will be invalidated.
     3607 +         * This is temporary and, if target is still attached, the device
     3608 +         * handles will be re-assigned when firmware reset completes.
     3609 +         * Then, if command was already waiting, complete the command
     3610 +         * otherwise return BUSY and expect transport retry.
3476 3611           */
3477 3612          if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) {
     3613 +                NDBG20(("retry command, invalid devhdl, during FW reset."));
3478 3614                  mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
3479 3615                  if (cmd->cmd_flags & CFLAG_TXQ) {
3480 3616                          mptsas_doneq_add(mpt, cmd);
3481 3617                          mptsas_doneq_empty(mpt);
3482 3618                          return (rval);
3483 3619                  } else {
3484 3620                          return (TRAN_BUSY);
3485 3621                  }
3486 3622          }
3487 3623  
3488 3624          /*
3489      -         * If device handle has already been invalidated, just
3490      -         * fail the command. In theory, command from scsi_vhci
3491      -         * client is impossible send down command with invalid
3492      -         * devhdl since devhdl is set after path offline, target
3493      -         * driver is not suppose to select a offlined path.
     3625 +         * If the device handle has been invalidated, set the response
     3626 +         * reason to indicate the device is gone. Then add the
     3627 +         * command to the done queue and run the completion routine
     3628 +         * so the initiator of the command can clean up.
3494 3629           */
3495 3630          if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3496      -                NDBG3(("rejecting command, it might because invalid devhdl "
3497      -                    "request."));
     3631 +                NDBG20(("rejecting command, invalid devhdl because "
     3632 +                    "device gone."));
3498 3633                  mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3499 3634                  if (cmd->cmd_flags & CFLAG_TXQ) {
3500 3635                          mptsas_doneq_add(mpt, cmd);
3501 3636                          mptsas_doneq_empty(mpt);
3502 3637                          return (rval);
3503 3638                  } else {
3504 3639                          return (TRAN_FATAL_ERROR);
3505 3640                  }
3506 3641          }
     3642 +
3507 3643          /*
     3644 +         * Do fault injecttion before transmitting command.
     3645 +         * FLAG_NOINTR commands are skipped.
     3646 +         */
     3647 +#ifdef MPTSAS_FAULTINJECTION
     3648 +        if (!mptsas_fminject(mpt, cmd)) {
     3649 +                return (TRAN_ACCEPT);
     3650 +        }
     3651 +#endif
     3652 +
     3653 +        /*
3508 3654           * The first case is the normal case.  mpt gets a command from the
3509 3655           * target driver and starts it.
3510 3656           * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3511 3657           * commands is m_max_requests - 2.
3512 3658           */
3513 3659          if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
3514 3660              (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3515 3661              (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3516 3662              (ptgt->m_reset_delay == 0) &&
3517 3663              (ptgt->m_t_nwait == 0) &&
↓ open down ↓ 92 lines elided ↑ open up ↑
3610 3756   * the pkt may have been resubmitted or just reused so
3611 3757   * initialize some fields and do some checks.
3612 3758   */
3613 3759  static int
3614 3760  mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3615 3761  {
3616 3762          struct scsi_pkt *pkt = CMD2PKT(cmd);
3617 3763  
3618 3764          NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3619 3765  
     3766 +#ifdef MPTSAS_FAULTINJECTION
     3767 +        /* Check for fault flags prior to perform actual initialization. */
     3768 +        if (pkt->pkt_flags & FLAG_PKT_BUSY) {
     3769 +                return (TRAN_BUSY);
     3770 +        }
     3771 +#endif
     3772 +
3620 3773          /*
3621 3774           * Reinitialize some fields that need it; the packet may
3622 3775           * have been resubmitted
3623 3776           */
3624 3777          pkt->pkt_reason = CMD_CMPLT;
3625 3778          pkt->pkt_state = 0;
3626 3779          pkt->pkt_statistics = 0;
3627 3780          pkt->pkt_resid = 0;
3628 3781          cmd->cmd_age = 0;
3629 3782          cmd->cmd_pkt_flags = pkt->pkt_flags;
↓ open down ↓ 92 lines elided ↑ open up ↑
3722 3875                  pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3723 3876                  cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3724 3877                  cmd->cmd_cdblen = (uchar_t)cmdlen;
3725 3878                  cmd->cmd_scblen = statuslen;
3726 3879                  cmd->cmd_rqslen = SENSE_LENGTH;
3727 3880                  cmd->cmd_tgt_addr = ptgt;
3728 3881  
3729 3882                  if ((cmdlen > sizeof (cmd->cmd_cdb)) ||
3730 3883                      (tgtlen > PKT_PRIV_LEN) ||
3731 3884                      (statuslen > EXTCMDS_STATUS_SIZE)) {
3732      -                        int failure;
3733      -
3734      -                        /*
3735      -                         * We are going to allocate external packet space which
3736      -                         * might include the sense data buffer for DMA so we
3737      -                         * need to increase the reference counter here.  In a
3738      -                         * case the HBA is in reset we just simply free the
3739      -                         * allocated packet and bail out.
3740      -                         */
3741      -                        mutex_enter(&mpt->m_mutex);
3742      -                        if (mpt->m_in_reset) {
3743      -                                mutex_exit(&mpt->m_mutex);
3744      -
3745      -                                cmd->cmd_flags = CFLAG_FREE;
3746      -                                kmem_cache_free(mpt->m_kmem_cache, cmd);
3747      -                                return (NULL);
3748      -                        }
3749      -                        mpt->m_extreq_sense_refcount++;
3750      -                        ASSERT(mpt->m_extreq_sense_refcount > 0);
3751      -                        mutex_exit(&mpt->m_mutex);
3752      -
3753      -                        /*
3754      -                         * if extern alloc fails, all will be
3755      -                         * deallocated, including cmd
3756      -                         */
3757      -                        failure = mptsas_pkt_alloc_extern(mpt, cmd,
3758      -                            cmdlen, tgtlen, statuslen, kf);
3759      -
3760      -                        if (failure != 0 || cmd->cmd_extrqslen == 0) {
     3885 +                        if (mptsas_pkt_alloc_extern(mpt, cmd,
     3886 +                            cmdlen, tgtlen, statuslen, kf)) {
3761 3887                                  /*
3762      -                                 * If the external packet space allocation
3763      -                                 * failed, or we didn't allocate the sense
3764      -                                 * data buffer for DMA we need to decrease the
3765      -                                 * reference counter.
     3888 +                                 * if extern allocation fails, it will
     3889 +                                 * deallocate the new pkt as well
3766 3890                                   */
3767      -                                mutex_enter(&mpt->m_mutex);
3768      -                                ASSERT(mpt->m_extreq_sense_refcount > 0);
3769      -                                mpt->m_extreq_sense_refcount--;
3770      -                                if (mpt->m_extreq_sense_refcount == 0)
3771      -                                        cv_broadcast(
3772      -                                            &mpt->m_extreq_sense_refcount_cv);
3773      -                                mutex_exit(&mpt->m_mutex);
3774      -
3775      -                                if (failure != 0) {
3776      -                                        /*
3777      -                                         * if extern allocation fails, it will
3778      -                                         * deallocate the new pkt as well
3779      -                                         */
3780      -                                        return (NULL);
3781      -                                }
     3891 +                                return (NULL);
3782 3892                          }
3783 3893                  }
3784 3894                  new_cmd = cmd;
3785 3895  
3786 3896          } else {
3787 3897                  cmd = PKT2CMD(pkt);
     3898 +                pkt->pkt_start = 0;
     3899 +                pkt->pkt_stop = 0;
3788 3900                  new_cmd = NULL;
3789 3901          }
3790 3902  
3791 3903  
3792 3904          /* grab cmd->cmd_cookiec here as oldcookiec */
3793 3905  
3794 3906          oldcookiec = cmd->cmd_cookiec;
3795 3907  
3796 3908          /*
3797 3909           * If the dma was broken up into PARTIAL transfers cmd_nwin will be
↓ open down ↓ 98 lines elided ↑ open up ↑
3896 4008                                  mptsas_scsi_destroy_pkt(ap, pkt);
3897 4009                          }
3898 4010                          return ((struct scsi_pkt *)NULL);
3899 4011                  }
3900 4012  
3901 4013  get_dma_cookies:
3902 4014                  cmd->cmd_flags |= CFLAG_DMAVALID;
3903 4015                  ASSERT(cmd->cmd_cookiec > 0);
3904 4016  
3905 4017                  if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3906      -                        mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
     4018 +                        mptsas_log(mpt, CE_NOTE, "large cookiec received %d",
3907 4019                              cmd->cmd_cookiec);
3908 4020                          bioerror(bp, EINVAL);
3909 4021                          if (new_cmd) {
3910 4022                                  mptsas_scsi_destroy_pkt(ap, pkt);
3911 4023                          }
3912 4024                          return ((struct scsi_pkt *)NULL);
3913 4025                  }
3914 4026  
3915 4027                  /*
3916 4028                   * Allocate extra SGL buffer if needed.
↓ open down ↓ 141 lines elided ↑ open up ↑
4058 4170          }
4059 4171  
4060 4172          mptsas_free_extra_sgl_frame(mpt, cmd);
4061 4173  
4062 4174          if ((cmd->cmd_flags &
4063 4175              (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
4064 4176              CFLAG_SCBEXTERN)) == 0) {
4065 4177                  cmd->cmd_flags = CFLAG_FREE;
4066 4178                  kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4067 4179          } else {
4068      -                boolean_t extrqslen = cmd->cmd_extrqslen != 0;
4069      -
4070 4180                  mptsas_pkt_destroy_extern(mpt, cmd);
4071      -
4072      -                /*
4073      -                 * If the packet had the sense data buffer for DMA allocated we
4074      -                 * need to decrease the reference counter.
4075      -                 */
4076      -                if (extrqslen) {
4077      -                        mutex_enter(&mpt->m_mutex);
4078      -                        ASSERT(mpt->m_extreq_sense_refcount > 0);
4079      -                        mpt->m_extreq_sense_refcount--;
4080      -                        if (mpt->m_extreq_sense_refcount == 0)
4081      -                                cv_broadcast(&mpt->m_extreq_sense_refcount_cv);
4082      -                        mutex_exit(&mpt->m_mutex);
4083      -                }
4084 4181          }
4085 4182  }
4086 4183  
4087 4184  /*
4088 4185   * kmem cache constructor and destructor:
4089 4186   * When constructing, we bzero the cmd and allocate the dma handle
4090 4187   * When destructing, just free the dma handle
4091 4188   */
4092 4189  static int
4093 4190  mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
↓ open down ↓ 1139 lines elided ↑ open up ↑
5233 5330  
5234 5331          scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
5235 5332          SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
5236 5333  
5237 5334          /*
5238 5335           * This is a success reply so just complete the IO.  First, do a sanity
5239 5336           * check on the SMID.  The final slot is used for TM requests, which
5240 5337           * would not come into this reply handler.
5241 5338           */
5242 5339          if ((SMID == 0) || (SMID > slots->m_n_normal)) {
5243      -                mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
5244      -                    SMID);
     5340 +                mptsas_log(mpt, CE_WARN, "received invalid SMID of %d", SMID);
5245 5341                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5246 5342                  return;
5247 5343          }
5248 5344  
5249 5345          cmd = slots->m_slot[SMID];
5250 5346  
5251 5347          /*
5252 5348           * print warning and return if the slot is empty
5253 5349           */
5254 5350          if (cmd == NULL) {
5255      -                mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
     5351 +                mptsas_log(mpt, CE_WARN, "NULL command for successful SCSI IO "
5256 5352                      "in slot %d", SMID);
5257 5353                  return;
5258 5354          }
5259 5355  
5260 5356          pkt = CMD2PKT(cmd);
     5357 +        ASSERT(pkt->pkt_start != 0);
     5358 +        pkt->pkt_stop = gethrtime();
5261 5359          pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
5262 5360              STATE_GOT_STATUS);
5263 5361          if (cmd->cmd_flags & CFLAG_DMAVALID) {
5264 5362                  pkt->pkt_state |= STATE_XFERRED_DATA;
5265 5363          }
5266 5364          pkt->pkt_resid = 0;
5267 5365  
5268 5366          if (cmd->cmd_flags & CFLAG_PASSTHRU) {
5269 5367                  cmd->cmd_flags |= CFLAG_FINISHED;
5270 5368                  cv_broadcast(&mpt->m_passthru_cv);
↓ open down ↓ 43 lines elided ↑ open up ↑
5314 5412          /*
5315 5413           * If reply frame is not in the proper range we should ignore this
5316 5414           * message and exit the interrupt handler.
5317 5415           */
5318 5416          reply_frame_dma_baseaddr = mpt->m_reply_frame_dma_addr & 0xffffffffu;
5319 5417          if ((reply_addr < reply_frame_dma_baseaddr) ||
5320 5418              (reply_addr >= (reply_frame_dma_baseaddr +
5321 5419              (mpt->m_reply_frame_size * mpt->m_max_replies))) ||
5322 5420              ((reply_addr - reply_frame_dma_baseaddr) %
5323 5421              mpt->m_reply_frame_size != 0)) {
5324      -                mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
5325      -                    "address 0x%x\n", reply_addr);
     5422 +                mptsas_log(mpt, CE_WARN, "received invalid reply frame "
     5423 +                    "address 0x%x", reply_addr);
5326 5424                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5327 5425                  return;
5328 5426          }
5329 5427  
5330 5428          (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
5331 5429              DDI_DMA_SYNC_FORCPU);
5332 5430          reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
5333 5431              reply_frame_dma_baseaddr));
5334 5432          function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
5335 5433  
↓ open down ↓ 4 lines elided ↑ open up ↑
5340 5438           * don't get slot information and command for events since these values
5341 5439           * don't exist
5342 5440           */
5343 5441          if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
5344 5442              (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
5345 5443                  /*
5346 5444                   * This could be a TM reply, which use the last allocated SMID,
5347 5445                   * so allow for that.
5348 5446                   */
5349 5447                  if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
5350      -                        mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
5351      -                            "%d\n", SMID);
     5448 +                        mptsas_log(mpt, CE_WARN, "received invalid SMID of "
     5449 +                            "%d", SMID);
5352 5450                          ddi_fm_service_impact(mpt->m_dip,
5353 5451                              DDI_SERVICE_UNAFFECTED);
5354 5452                          return;
5355 5453                  }
5356 5454  
5357 5455                  cmd = slots->m_slot[SMID];
5358 5456  
5359 5457                  /*
5360 5458                   * print warning and return if the slot is empty
5361 5459                   */
5362 5460                  if (cmd == NULL) {
5363      -                        mptsas_log(mpt, CE_WARN, "?NULL command for address "
     5461 +                        mptsas_log(mpt, CE_WARN, "NULL command for address "
5364 5462                              "reply in slot %d", SMID);
5365 5463                          return;
5366 5464                  }
5367 5465                  if ((cmd->cmd_flags &
5368 5466                      (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) {
5369 5467                          cmd->cmd_rfm = reply_addr;
5370 5468                          cmd->cmd_flags |= CFLAG_FINISHED;
5371 5469                          cv_broadcast(&mpt->m_passthru_cv);
5372 5470                          cv_broadcast(&mpt->m_config_cv);
5373 5471                          cv_broadcast(&mpt->m_fw_diag_cv);
↓ open down ↓ 92 lines elided ↑ open up ↑
5466 5564                  } else {
5467 5565                          /*
5468 5566                           * Normal handling of diag post reply with SMID.
5469 5567                           */
5470 5568                          cmd = slots->m_slot[SMID];
5471 5569  
5472 5570                          /*
5473 5571                           * print warning and return if the slot is empty
5474 5572                           */
5475 5573                          if (cmd == NULL) {
5476      -                                mptsas_log(mpt, CE_WARN, "?NULL command for "
     5574 +                                mptsas_log(mpt, CE_WARN, "NULL command for "
5477 5575                                      "address reply in slot %d", SMID);
5478 5576                                  return;
5479 5577                          }
5480 5578                          cmd->cmd_rfm = reply_addr;
5481 5579                          cmd->cmd_flags |= CFLAG_FINISHED;
5482 5580                          cv_broadcast(&mpt->m_fw_diag_cv);
5483 5581                  }
5484 5582                  return;
5485 5583          default:
5486 5584                  mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
↓ open down ↓ 64 lines elided ↑ open up ↑
5551 5649                  sas_wwn = ptgt->m_addr.mta_wwn;
5552 5650                  phy = ptgt->m_phynum;
5553 5651                  if (sas_wwn == 0) {
5554 5652                          (void) sprintf(wwn_str, "p%x", phy);
5555 5653                  } else {
5556 5654                          (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn);
5557 5655                  }
5558 5656                  loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
5559 5657                      &reply->IOCLogInfo);
5560 5658                  mptsas_log(mpt, CE_NOTE,
5561      -                    "?Log info 0x%x received for target %d %s.\n"
5562      -                    "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
     5659 +                    "log info 0x%x received for target %d %s, "
     5660 +                    "scsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5563 5661                      loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status,
5564 5662                      scsi_state);
5565 5663          }
5566 5664  
5567 5665          NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
5568 5666              scsi_status, ioc_status, scsi_state));
5569 5667  
5570 5668          pkt = CMD2PKT(cmd);
     5669 +        ASSERT(pkt->pkt_start != 0);
     5670 +        pkt->pkt_stop = gethrtime();
5571 5671          *(pkt->pkt_scbp) = scsi_status;
5572 5672  
5573 5673          if (loginfo == 0x31170000) {
5574 5674                  /*
5575 5675                   * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
5576 5676                   * 0x31170000 comes, that means the device missing delay
5577 5677                   * is in progressing, the command need retry later.
5578 5678                   */
5579 5679                  *(pkt->pkt_scbp) = STATUS_BUSY;
5580 5680                  return;
↓ open down ↓ 7 lines elided ↑ open up ↑
5588 5688                  if (ptgt->m_reset_delay == 0) {
5589 5689                          mptsas_set_throttle(mpt, ptgt,
5590 5690                              DRAIN_THROTTLE);
5591 5691                  }
5592 5692                  return;
5593 5693          }
5594 5694  
5595 5695          if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
5596 5696                  responsedata &= 0x000000FF;
5597 5697                  if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
5598      -                        mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
     5698 +                        mptsas_log(mpt, CE_NOTE, "TLR not supported");
5599 5699                          pkt->pkt_reason = CMD_TLR_OFF;
5600 5700                          return;
5601 5701                  }
5602 5702          }
5603 5703  
5604 5704  
5605 5705          switch (scsi_status) {
5606 5706          case MPI2_SCSI_STATUS_CHECK_CONDITION:
5607 5707                  pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5608 5708                  arqstat = (void*)(pkt->pkt_scbp);
↓ open down ↓ 55 lines elided ↑ open up ↑
5664 5764                      (scsi_sense_asc(sensedata) == 0x25) &&
5665 5765                      (scsi_sense_ascq(sensedata) == 0x00))) {
5666 5766                          mptsas_topo_change_list_t *topo_node = NULL;
5667 5767  
5668 5768                          topo_node = kmem_zalloc(
5669 5769                              sizeof (mptsas_topo_change_list_t),
5670 5770                              KM_NOSLEEP);
5671 5771                          if (topo_node == NULL) {
5672 5772                                  mptsas_log(mpt, CE_NOTE, "No memory"
5673 5773                                      "resource for handle SAS dynamic"
5674      -                                    "reconfigure.\n");
     5774 +                                    "reconfigure");
5675 5775                                  break;
5676 5776                          }
5677 5777                          topo_node->mpt = mpt;
5678 5778                          topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5679 5779                          topo_node->un.phymask = ptgt->m_addr.mta_phymask;
5680 5780                          topo_node->devhdl = ptgt->m_devhdl;
5681 5781                          topo_node->object = (void *)ptgt;
5682 5782                          topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5683 5783  
5684 5784                          if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5685 5785                              mptsas_handle_dr,
5686 5786                              (void *)topo_node,
5687 5787                              DDI_NOSLEEP)) != DDI_SUCCESS) {
5688 5788                                  kmem_free(topo_node,
5689 5789                                      sizeof (mptsas_topo_change_list_t));
5690 5790                                  mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5691 5791                                      "for handle SAS dynamic reconfigure"
5692      -                                    "failed. \n");
     5792 +                                    "failed");
5693 5793                          }
5694 5794                  }
5695 5795                  break;
5696 5796          case MPI2_SCSI_STATUS_GOOD:
5697 5797                  switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5698 5798                  case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5699 5799                          pkt->pkt_reason = CMD_DEV_GONE;
5700 5800                          pkt->pkt_state |= STATE_GOT_BUS;
5701 5801                          if (ptgt->m_reset_delay == 0) {
5702 5802                                  mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
↓ open down ↓ 59 lines elided ↑ open up ↑
5762 5862                          /*
5763 5863                           * retry command
5764 5864                           */
5765 5865                          cmd->cmd_flags |= CFLAG_RETRY;
5766 5866                          cmd->cmd_pkt_flags |= FLAG_HEAD;
5767 5867  
5768 5868                          (void) mptsas_accept_pkt(mpt, cmd);
5769 5869                          break;
5770 5870                  default:
5771 5871                          mptsas_log(mpt, CE_WARN,
5772      -                            "unknown ioc_status = %x\n", ioc_status);
     5872 +                            "unknown ioc_status = %x", ioc_status);
5773 5873                          mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5774 5874                              "count = %x, scsi_status = %x", scsi_state,
5775 5875                              xferred, scsi_status);
5776 5876                          break;
5777 5877                  }
5778 5878                  break;
5779 5879          case MPI2_SCSI_STATUS_TASK_SET_FULL:
5780 5880                  mptsas_handle_qfull(mpt, cmd);
5781 5881                  break;
5782 5882          case MPI2_SCSI_STATUS_BUSY:
5783 5883                  NDBG31(("scsi_status busy received"));
5784 5884                  break;
5785 5885          case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5786 5886                  NDBG31(("scsi_status reservation conflict received"));
5787 5887                  break;
5788 5888          default:
5789      -                mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
     5889 +                mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x",
5790 5890                      scsi_status, ioc_status);
5791 5891                  mptsas_log(mpt, CE_WARN,
5792      -                    "mptsas_process_intr: invalid scsi status\n");
     5892 +                    "mptsas_process_intr: invalid scsi status");
5793 5893                  break;
5794 5894          }
5795 5895  }
5796 5896  
5797 5897  static void
5798 5898  mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5799 5899      mptsas_cmd_t *cmd)
5800 5900  {
5801 5901          uint8_t         task_type;
5802 5902          uint16_t        ioc_status;
↓ open down ↓ 1 lines elided ↑ open up ↑
5804 5904          uint16_t        dev_handle;
5805 5905          struct scsi_pkt *pkt = CMD2PKT(cmd);
5806 5906  
5807 5907          task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5808 5908          ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5809 5909          log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5810 5910          dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5811 5911  
5812 5912          if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5813 5913                  mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5814      -                    "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
     5914 +                    "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d",
5815 5915                      task_type, ioc_status, log_info, dev_handle);
5816 5916                  pkt->pkt_reason = CMD_INCOMPLETE;
5817 5917                  return;
5818 5918          }
5819 5919  
5820 5920          switch (task_type) {
5821 5921          case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5822 5922          case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5823 5923          case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5824 5924          case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
↓ open down ↓ 1 lines elided ↑ open up ↑
5826 5926          case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5827 5927                  break;
5828 5928          case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5829 5929          case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5830 5930          case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5831 5931                  /*
5832 5932                   * Check for invalid DevHandle of 0 in case application
5833 5933                   * sends bad command.  DevHandle of 0 could cause problems.
5834 5934                   */
5835 5935                  if (dev_handle == 0) {
5836      -                        mptsas_log(mpt, CE_WARN, "!Can't flush target with"
     5936 +                        mptsas_log(mpt, CE_WARN, "Can't flush target with"
5837 5937                              " DevHandle of 0.");
5838 5938                  } else {
5839 5939                          mptsas_flush_target(mpt, dev_handle, Lun(cmd),
5840 5940                              task_type);
5841 5941                  }
5842 5942                  break;
5843 5943          default:
5844 5944                  mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5845 5945                      task_type);
5846 5946                  mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
↓ open down ↓ 166 lines elided ↑ open up ↑
6013 6113           */
6014 6114          reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
6015 6115              &reply_desc_union->Default.ReplyFlags);
6016 6116          reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
6017 6117          if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS ||
6018 6118              reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) {
6019 6119                  mptsas_handle_scsi_io_success(mpt, reply_desc_union);
6020 6120          } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
6021 6121                  mptsas_handle_address_reply(mpt, reply_desc_union);
6022 6122          } else {
6023      -                mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
     6123 +                mptsas_log(mpt, CE_WARN, "bad reply type %x", reply_type);
6024 6124                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
6025 6125          }
6026 6126  
6027 6127          /*
6028 6128           * Clear the reply descriptor for re-use and increment
6029 6129           * index.
6030 6130           */
6031 6131          ddi_put64(mpt->m_acc_post_queue_hdl,
6032 6132              &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
6033 6133              0xFFFFFFFFFFFFFFFF);
↓ open down ↓ 141 lines elided ↑ open up ↑
6175 6275  {
6176 6276          int                     rval;
6177 6277          uint16_t                dev_hdl;
6178 6278          uint16_t                pdev_hdl;
6179 6279          uint64_t                dev_sas_wwn;
6180 6280          uint8_t                 physport;
6181 6281          uint8_t                 phy_id;
6182 6282          uint32_t                page_address;
6183 6283          uint16_t                bay_num, enclosure, io_flags;
6184 6284          uint32_t                dev_info;
6185      -        char                    uabuf[SCSI_WWN_BUFLEN];
     6285 +        char                    uabuf[SCSI_WWN_BUFLEN];
6186 6286          dev_info_t              *dip;
6187 6287          mdi_pathinfo_t          *pip;
6188 6288  
6189 6289          mutex_enter(&mpt->m_mutex);
6190 6290          page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6191 6291              MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)ptgt->m_devhdl;
6192 6292          rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl,
6193 6293              &dev_sas_wwn, &dev_info, &physport, &phy_id, &pdev_hdl, &bay_num,
6194 6294              &enclosure, &io_flags);
6195 6295          mutex_exit(&mpt->m_mutex);
↓ open down ↓ 261 lines elided ↑ open up ↑
6457 6557  
6458 6558                  }
6459 6559                  ASSERT(parent);
6460 6560  handle_topo_change:
6461 6561  
6462 6562                  mutex_enter(&mpt->m_mutex);
6463 6563                  /*
6464 6564                   * If HBA is being reset, don't perform operations depending
6465 6565                   * on the IOC. We must free the topo list, however.
6466 6566                   */
6467      -                if (!mpt->m_in_reset)
     6567 +                if (!mpt->m_in_reset) {
6468 6568                          mptsas_handle_topo_change(topo_node, parent);
6469      -                else
     6569 +                } else {
6470 6570                          NDBG20(("skipping topo change received during reset"));
     6571 +                }
6471 6572                  save_node = topo_node;
6472 6573                  topo_node = topo_node->next;
6473 6574                  ASSERT(save_node);
6474 6575                  kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
6475 6576                  mutex_exit(&mpt->m_mutex);
6476 6577  
6477 6578                  if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6478 6579                      (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
6479 6580                      (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
6480 6581                          /*
↓ open down ↓ 65 lines elided ↑ open up ↑
6546 6647                           */
6547 6648                          page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
6548 6649                              MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
6549 6650                              topo_node->devhdl;
6550 6651  
6551 6652                          rval = mptsas_get_target_device_info(mpt, page_address,
6552 6653                              &devhdl, &ptgt);
6553 6654                          if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
6554 6655                                  mptsas_log(mpt, CE_NOTE,
6555 6656                                      "mptsas_handle_topo_change: target %d is "
6556      -                                    "not a SAS/SATA device. \n",
     6657 +                                    "not a SAS/SATA device",
6557 6658                                      topo_node->devhdl);
6558 6659                          } else if (rval == DEV_INFO_FAIL_ALLOC) {
6559 6660                                  mptsas_log(mpt, CE_NOTE,
6560 6661                                      "mptsas_handle_topo_change: could not "
6561      -                                    "allocate memory. \n");
     6662 +                                    "allocate memory");
6562 6663                          } else if (rval == DEV_INFO_FAIL_GUID) {
6563 6664                                  mptsas_log(mpt, CE_NOTE,
6564 6665                                      "mptsas_handle_topo_change: could not "
6565      -                                    "get SATA GUID for target %d. \n",
     6666 +                                    "get SATA GUID for target %d",
6566 6667                                      topo_node->devhdl);
6567 6668                          }
6568 6669                          /*
6569 6670                           * If rval is DEV_INFO_PHYS_DISK or indicates failure
6570 6671                           * then there is nothing else to do, just leave.
6571 6672                           */
6572 6673                          if (rval != DEV_INFO_SUCCESS) {
6573 6674                                  return;
6574 6675                          }
6575 6676                  }
↓ open down ↓ 206 lines elided ↑ open up ↑
6782 6883                                  (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6783 6884                                      MPTSAS_VIRTUAL_PORT);
6784 6885                                  mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6785 6886                                      "prop update failed");
6786 6887                                  mutex_enter(&mpt->m_mutex);
6787 6888                                  break;
6788 6889                          }
6789 6890                  }
6790 6891  
6791 6892                  mutex_enter(&mpt->m_mutex);
6792      -                ptgt->m_led_status = 0;
6793      -                (void) mptsas_flush_led_status(mpt, ptgt);
6794 6893                  if (rval == DDI_SUCCESS) {
6795 6894                          refhash_remove(mpt->m_targets, ptgt);
6796 6895                          ptgt = NULL;
6797 6896                  } else {
6798 6897                          /*
6799 6898                           * clean DR_INTRANSITION flag to allow I/O down to
6800 6899                           * PHCI driver since failover finished.
6801 6900                           * Invalidate the devhdl
6802 6901                           */
6803 6902                          ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
↓ open down ↓ 79 lines elided ↑ open up ↑
6883 6982                      mptsas_smp_eval_devhdl, &devhdl);
6884 6983                  if (psmp == NULL)
6885 6984                          break;
6886 6985                  /*
6887 6986                   * The mptsas_smp_t data is released only if the dip is offlined
6888 6987                   * successfully.
6889 6988                   */
6890 6989                  mutex_exit(&mpt->m_mutex);
6891 6990  
6892 6991                  ndi_devi_enter(parent, &circ1);
6893      -                rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
     6992 +                rval = mptsas_offline_smp(parent, psmp);
6894 6993                  ndi_devi_exit(parent, circ1);
6895 6994  
6896 6995                  dev_info = psmp->m_deviceinfo;
6897 6996                  if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6898 6997                      DEVINFO_DIRECT_ATTACHED) {
6899 6998                          if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6900 6999                              MPTSAS_VIRTUAL_PORT, 1) !=
6901 7000                              DDI_PROP_SUCCESS) {
6902 7001                                  (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6903 7002                                      MPTSAS_VIRTUAL_PORT);
6904 7003                                  mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6905 7004                                      "prop update failed");
     7005 +                                mutex_enter(&mpt->m_mutex);
6906 7006                                  return;
6907 7007                          }
6908 7008                          /*
6909 7009                           * Check whether the smp connected to the iport,
6910 7010                           */
6911 7011                          if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6912 7012                              MPTSAS_NUM_PHYS, 0) !=
6913 7013                              DDI_PROP_SUCCESS) {
6914 7014                                  (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6915 7015                                      MPTSAS_NUM_PHYS);
6916 7016                                  mptsas_log(mpt, CE_WARN, "mptsas num phys"
6917 7017                                      "prop update failed");
     7018 +                                mutex_enter(&mpt->m_mutex);
6918 7019                                  return;
6919 7020                          }
6920 7021                          /*
6921 7022                           * Clear parent's attached-port props
6922 7023                           */
6923 7024                          bzero(attached_wwnstr, sizeof (attached_wwnstr));
6924 7025                          if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6925 7026                              SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6926 7027                              DDI_PROP_SUCCESS) {
6927 7028                                  (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6928 7029                                      SCSI_ADDR_PROP_ATTACHED_PORT);
6929 7030                                  mptsas_log(mpt, CE_WARN, "mptsas attached port "
6930 7031                                      "prop update failed");
     7032 +                                mutex_enter(&mpt->m_mutex);
6931 7033                                  return;
6932 7034                          }
6933 7035                  }
6934 7036  
6935 7037                  mutex_enter(&mpt->m_mutex);
6936 7038                  NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6937 7039                      "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6938 7040                  if (rval == DDI_SUCCESS) {
6939 7041                          refhash_remove(mpt->m_smp_targets, psmp);
6940 7042                  } else {
↓ open down ↓ 114 lines elided ↑ open up ↑
7055 7157          rfm = replyh_arg->rfm;
7056 7158          mpt = replyh_arg->mpt;
7057 7159  
7058 7160          ASSERT(mutex_owned(&mpt->m_mutex));
7059 7161  
7060 7162          eventreply = (pMpi2EventNotificationReply_t)
7061 7163              (mpt->m_reply_frame + (rfm -
7062 7164              (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7063 7165          event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7064 7166  
7065      -        if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7066      -            &eventreply->IOCStatus)) {
     7167 +        if ((iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
     7168 +            &eventreply->IOCStatus)) != 0) {
7067 7169                  if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7068 7170                          mptsas_log(mpt, CE_WARN,
7069      -                            "!mptsas_handle_event_sync: event 0x%x, "
     7171 +                            "mptsas_handle_event_sync: event 0x%x, "
7070 7172                              "IOCStatus=0x%x, "
7071 7173                              "IOCLogInfo=0x%x", event, iocstatus,
7072 7174                              ddi_get32(mpt->m_acc_reply_frame_hdl,
7073 7175                              &eventreply->IOCLogInfo));
7074 7176                  } else {
7075 7177                          mptsas_log(mpt, CE_WARN,
7076 7178                              "mptsas_handle_event_sync: event 0x%x, "
7077 7179                              "IOCStatus=0x%x, "
7078 7180                              "(IOCLogInfo=0x%x)", event, iocstatus,
7079 7181                              ddi_get32(mpt->m_acc_reply_frame_hdl,
↓ open down ↓ 451 lines elided ↑ open up ↑
7531 7633                          if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7532 7634                              mptsas_handle_dr, (void *)topo_head,
7533 7635                              DDI_NOSLEEP)) != DDI_SUCCESS) {
7534 7636                                  while (topo_head != NULL) {
7535 7637                                          topo_node = topo_head;
7536 7638                                          topo_head = topo_head->next;
7537 7639                                          kmem_free(topo_node,
7538 7640                                              sizeof (mptsas_topo_change_list_t));
7539 7641                                  }
7540 7642                                  mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7541      -                                    "for handle SAS DR event failed. \n");
     7643 +                                    "for handle SAS DR event failed");
7542 7644                          }
7543 7645                  }
7544 7646                  break;
7545 7647          }
7546 7648          case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7547 7649          {
7548 7650                  Mpi2EventDataIrConfigChangeList_t       *irChangeList;
7549 7651                  mptsas_topo_change_list_t               *topo_head = NULL;
7550 7652                  mptsas_topo_change_list_t               *topo_tail = NULL;
7551 7653                  mptsas_topo_change_list_t               *topo_node = NULL;
↓ open down ↓ 163 lines elided ↑ open up ↑
7715 7817                          if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
7716 7818                              mptsas_handle_dr, (void *)topo_head,
7717 7819                              DDI_NOSLEEP)) != DDI_SUCCESS) {
7718 7820                                  while (topo_head != NULL) {
7719 7821                                          topo_node = topo_head;
7720 7822                                          topo_head = topo_head->next;
7721 7823                                          kmem_free(topo_node,
7722 7824                                              sizeof (mptsas_topo_change_list_t));
7723 7825                                  }
7724 7826                                  mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
7725      -                                    "for handle SAS DR event failed. \n");
     7827 +                                    "for handle SAS DR event failed");
7726 7828                          }
7727 7829                  }
7728 7830                  break;
7729 7831          }
7730 7832          default:
7731 7833                  return (DDI_FAILURE);
7732 7834          }
7733 7835  
7734 7836          return (DDI_SUCCESS);
7735 7837  }
↓ open down ↓ 24 lines elided ↑ open up ↑
7760 7862                  NDBG20(("dropping event received prior to reset"));
7761 7863                  mutex_exit(&mpt->m_mutex);
7762 7864                  return;
7763 7865          }
7764 7866  
7765 7867          eventreply = (pMpi2EventNotificationReply_t)
7766 7868              (mpt->m_reply_frame + (rfm -
7767 7869              (mpt->m_reply_frame_dma_addr & 0xffffffffu)));
7768 7870          event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7769 7871  
7770      -        if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7771      -            &eventreply->IOCStatus)) {
     7872 +        if ((iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
     7873 +            &eventreply->IOCStatus)) != 0) {
7772 7874                  if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7773 7875                          mptsas_log(mpt, CE_WARN,
7774      -                            "!mptsas_handle_event: IOCStatus=0x%x, "
     7876 +                            "mptsas_handle_event: IOCStatus=0x%x, "
7775 7877                              "IOCLogInfo=0x%x", iocstatus,
7776 7878                              ddi_get32(mpt->m_acc_reply_frame_hdl,
7777 7879                              &eventreply->IOCLogInfo));
7778 7880                  } else {
7779 7881                          mptsas_log(mpt, CE_WARN,
7780 7882                              "mptsas_handle_event: IOCStatus=0x%x, "
7781 7883                              "IOCLogInfo=0x%x", iocstatus,
7782 7884                              ddi_get32(mpt->m_acc_reply_frame_hdl,
7783 7885                              &eventreply->IOCLogInfo));
7784 7886                  }
↓ open down ↓ 90 lines elided ↑ open up ↑
7875 7977                      &encstatus->EnclosureHandle);
7876 7978  
7877 7979                  switch (rc) {
7878 7980                  case MPI2_EVENT_SAS_ENCL_RC_ADDED:
7879 7981                          (void) sprintf(string, "added");
7880 7982                          break;
7881 7983                  case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
7882 7984                          mep = mptsas_enc_lookup(mpt, enchdl);
7883 7985                          if (mep != NULL) {
7884 7986                                  list_remove(&mpt->m_enclosures, mep);
7885      -                                kmem_free(mep, sizeof (*mep));
     7987 +                                mptsas_enc_free(mep);
     7988 +                                mep = NULL;
7886 7989                          }
7887 7990                          (void) sprintf(string, ", not responding");
7888 7991                          break;
7889 7992                  default:
7890 7993                  break;
7891 7994                  }
7892 7995                  NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure "
7893 7996                      "%x%s\n", mpt->m_instance,
7894 7997                      ddi_get16(mpt->m_acc_reply_frame_hdl,
7895 7998                      &encstatus->EnclosureHandle), string));
↓ open down ↓ 246 lines elided ↑ open up ↑
8142 8245                  case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
8143 8246                  {
8144 8247                          uint32_t i;
8145 8248                          mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
8146 8249                              state;
8147 8250  
8148 8251                          i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
8149 8252                          mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
8150 8253                              ", auto-config of hot-swap drives is %s"
8151 8254                              ", write caching is %s"
8152      -                            ", hot-spare pool mask is %02x\n",
     8255 +                            ", hot-spare pool mask is %02x",
8153 8256                              vol, state &
8154 8257                              MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
8155 8258                              ? "disabled" : "enabled",
8156 8259                              i == MPI2_RAIDVOL0_SETTING_UNCHANGED
8157 8260                              ? "controlled by member disks" :
8158 8261                              i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
8159 8262                              ? "disabled" :
8160 8263                              i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
8161 8264                              ? "enabled" :
8162 8265                              "incorrectly set",
8163 8266                              (state >> 16) & 0xff);
8164 8267                                  break;
8165 8268                  }
8166 8269                  case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
8167 8270                  {
8168 8271                          mpt->m_raidconfig[config].m_raidvol[vol].m_state =
8169 8272                              (uint8_t)state;
8170 8273  
8171 8274                          mptsas_log(mpt, CE_NOTE,
8172      -                            "Volume %d is now %s\n", vol,
     8275 +                            "Volume %d is now %s", vol,
8173 8276                              state == MPI2_RAID_VOL_STATE_OPTIMAL
8174 8277                              ? "optimal" :
8175 8278                              state == MPI2_RAID_VOL_STATE_DEGRADED
8176 8279                              ? "degraded" :
8177 8280                              state == MPI2_RAID_VOL_STATE_ONLINE
8178 8281                              ? "online" :
8179 8282                              state == MPI2_RAID_VOL_STATE_INITIALIZING
8180 8283                              ? "initializing" :
8181 8284                              state == MPI2_RAID_VOL_STATE_FAILED
8182 8285                              ? "failed" :
↓ open down ↓ 1 lines elided ↑ open up ↑
8184 8287                              ? "missing" :
8185 8288                              "state unknown");
8186 8289                          break;
8187 8290                  }
8188 8291                  case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
8189 8292                  {
8190 8293                          mpt->m_raidconfig[config].m_raidvol[vol].
8191 8294                              m_statusflags = state;
8192 8295  
8193 8296                          mptsas_log(mpt, CE_NOTE,
8194      -                            " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
     8297 +                            " Volume %d is now %s%s%s%s%s%s%s%s%s",
8195 8298                              vol,
8196 8299                              state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
8197 8300                              ? ", enabled" : ", disabled",
8198 8301                              state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
8199 8302                              ? ", quiesced" : "",
8200 8303                              state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
8201 8304                              ? ", inactive" : ", active",
8202 8305                              state &
8203 8306                              MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
8204 8307                              ? ", bad block table is full" : "",
↓ open down ↓ 49 lines elided ↑ open up ↑
8254 8357                              "spare pool %d",
8255 8358                              physdisknum, devhandle, slot, enchandle,
8256 8359                              (state >> 16) & 0xff);
8257 8360                          break;
8258 8361  
8259 8362                  case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
8260 8363                          status = state;
8261 8364                          mptsas_log(mpt, CE_NOTE,
8262 8365                              " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8263 8366                              "for enclosure with handle 0x%x is now "
8264      -                            "%s%s%s%s%s\n", physdisknum, devhandle, slot,
     8367 +                            "%s%s%s%s%s", physdisknum, devhandle, slot,
8265 8368                              enchandle,
8266 8369                              status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
8267 8370                              ? ", inactive" : ", active",
8268 8371                              status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
8269 8372                              ? ", out of sync" : "",
8270 8373                              status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
8271 8374                              ? ", quiesced" : "",
8272 8375                              status &
8273 8376                              MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
8274 8377                              ? ", write cache enabled" : "",
8275 8378                              status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
8276 8379                              ? ", capacity expansion target" : "");
8277 8380                          break;
8278 8381  
8279 8382                  case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
8280 8383                          mptsas_log(mpt, CE_NOTE,
8281 8384                              " PhysDiskNum %d with DevHandle 0x%x in slot %d "
8282      -                            "for enclosure with handle 0x%x is now %s\n",
     8385 +                            "for enclosure with handle 0x%x is now %s",
8283 8386                              physdisknum, devhandle, slot, enchandle,
8284 8387                              state == MPI2_RAID_PD_STATE_OPTIMAL
8285 8388                              ? "optimal" :
8286 8389                              state == MPI2_RAID_PD_STATE_REBUILDING
8287 8390                              ? "rebuilding" :
8288 8391                              state == MPI2_RAID_PD_STATE_DEGRADED
8289 8392                              ? "degraded" :
8290 8393                              state == MPI2_RAID_PD_STATE_HOT_SPARE
8291 8394                              ? "a hot spare" :
8292 8395                              state == MPI2_RAID_PD_STATE_ONLINE
↓ open down ↓ 2 lines elided ↑ open up ↑
8295 8398                              ? "offline" :
8296 8399                              state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
8297 8400                              ? "not compatible" :
8298 8401                              state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
8299 8402                              ? "not configured" :
8300 8403                              "state unknown");
8301 8404                          break;
8302 8405                  }
8303 8406                  break;
8304 8407          }
     8408 +        case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
     8409 +        {
     8410 +                pMpi26EventDataActiveCableExcept_t      actcable;
     8411 +                uint32_t power;
     8412 +                uint8_t reason, id;
     8413 +
     8414 +                actcable = (pMpi26EventDataActiveCableExcept_t)
     8415 +                    eventreply->EventData;
     8416 +                power = ddi_get32(mpt->m_acc_reply_frame_hdl,
     8417 +                    &actcable->ActiveCablePowerRequirement);
     8418 +                reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
     8419 +                    &actcable->ReasonCode);
     8420 +                id = ddi_get8(mpt->m_acc_reply_frame_hdl,
     8421 +                    &actcable->ReceptacleID);
     8422 +
     8423 +                /*
     8424 +                 * It'd be nice if this weren't just logging to the system but
     8425 +                 * were telling FMA about the active cable problem and FMA was
     8426 +                 * aware of the cable topology and state.
     8427 +                 */
     8428 +                switch (reason) {
     8429 +                case MPI26_EVENT_ACTIVE_CABLE_PRESENT:
     8430 +                        /* Don't log anything if it's fine */
     8431 +                        break;
     8432 +                case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER:
     8433 +                        mptsas_log(mpt, CE_WARN, "An active cable (id %u) does "
     8434 +                            "not have sufficient power to be enabled. "
     8435 +                            "Devices connected to this cable will not be "
     8436 +                            "visible to the system.", id);
     8437 +                        if (power == UINT32_MAX) {
     8438 +                                mptsas_log(mpt, CE_CONT, "The cable's power "
     8439 +                                    "requirements are unknown.\n");
     8440 +                        } else {
     8441 +                                mptsas_log(mpt, CE_CONT, "The cable requires "
     8442 +                                    "%u mW of power to function.\n", power);
     8443 +                        }
     8444 +                        break;
     8445 +                case MPI26_EVENT_ACTIVE_CABLE_DEGRADED:
     8446 +                        mptsas_log(mpt, CE_WARN, "An active cable (id %u) is "
     8447 +                            "degraded and not running at its full speed. "
     8448 +                            "Some devices might not appear.", id);
     8449 +                        break;
     8450 +                default:
     8451 +                        break;
     8452 +                }
     8453 +                break;
     8454 +        }
     8455 +        case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
     8456 +        case MPI2_EVENT_PCIE_ENUMERATION:
     8457 +        case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
     8458 +        case MPI2_EVENT_PCIE_LINK_COUNTER:
     8459 +                mptsas_log(mpt, CE_NOTE, "Unhandled mpt_sas PCIe device "
     8460 +                    "event received (0x%x)", event);
     8461 +                break;
8305 8462          default:
8306 8463                  NDBG20(("mptsas%d: unknown event %x received",
8307 8464                      mpt->m_instance, event));
8308 8465                  break;
8309 8466          }
8310 8467  
8311 8468          /*
8312 8469           * Return the reply frame to the free queue.
8313 8470           */
8314 8471          ddi_put32(mpt->m_acc_free_queue_hdl,
↓ open down ↓ 227 lines elided ↑ open up ↑
8542 8699                          mpt->m_tx_draining = 0;
8543 8700                          break;
8544 8701                  }
8545 8702                  if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
8546 8703                          mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8547 8704                  }
8548 8705                  cmd->cmd_linkp = NULL;
8549 8706                  mutex_exit(&mpt->m_tx_waitq_mutex);
8550 8707                  if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
8551 8708                          cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
8552      -                            "to accept cmd on queue\n");
     8709 +                            "to accept cmd on queue");
8553 8710                  mutex_enter(&mpt->m_tx_waitq_mutex);
8554 8711          }
8555 8712  }
8556 8713  
8557 8714  
8558 8715  /*
8559 8716   * mpt tag type lookup
8560 8717   */
8561 8718  static char mptsas_tag_lookup[] =
8562 8719          {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
↓ open down ↓ 65 lines elided ↑ open up ↑
8628 8785                  case MSG_SIMPLE_QTAG:
8629 8786                          control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8630 8787                          break;
8631 8788                  case MSG_HEAD_QTAG:
8632 8789                          control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
8633 8790                          break;
8634 8791                  case MSG_ORDERED_QTAG:
8635 8792                          control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
8636 8793                          break;
8637 8794                  default:
8638      -                        mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
     8795 +                        mptsas_log(mpt, CE_WARN, "invalid tag type");
8639 8796                          break;
8640 8797                  }
8641 8798          } else {
8642 8799                  if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
8643 8800                                  ptgt->m_t_throttle = 1;
8644 8801                  }
8645 8802                  control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8646 8803          }
8647 8804  
8648 8805          if (cmd->cmd_pkt_flags & FLAG_TLR) {
↓ open down ↓ 60 lines elided ↑ open up ↑
8709 8866          ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, ars_dmaaddrlow);
8710 8867  
8711 8868          ddi_put32(acc_hdl, &io_request->Control, control);
8712 8869  
8713 8870          NDBG31(("starting message=%d(0x%p), with cmd=0x%p",
8714 8871              SMID, (void *)io_request, (void *)cmd));
8715 8872  
8716 8873          (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
8717 8874          (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0,
8718 8875              DDI_DMA_SYNC_FORDEV);
     8876 +        pkt->pkt_start = gethrtime();
8719 8877  
8720 8878          /*
8721 8879           * Build request descriptor and write it to the request desc post reg.
8722 8880           */
8723 8881          request_desc |= (SMID << 16);
8724 8882          request_desc |= (uint64_t)ptgt->m_devhdl << 48;
8725 8883          MPTSAS_START_CMD(mpt, request_desc);
8726 8884  
8727 8885          /*
8728 8886           * Start timeout.
8729 8887           */
8730      -        cmd->cmd_active_expiration =
8731      -            gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC;
     8888 +        cmd->cmd_active_expiration = pkt->pkt_start +
     8889 +            (hrtime_t)pkt->pkt_time * (hrtime_t)NANOSEC;
     8890 +
8732 8891  #ifdef MPTSAS_TEST
8733 8892          /*
8734 8893           * Force timeouts to happen immediately.
8735 8894           */
8736 8895          if (mptsas_test_timeouts)
8737 8896                  cmd->cmd_active_expiration = gethrtime();
8738 8897  #endif
8739 8898          c = TAILQ_FIRST(&ptgt->m_active_cmdq);
8740 8899          if (c == NULL ||
8741 8900              c->cmd_active_expiration < cmd->cmd_active_expiration) {
↓ open down ↓ 501 lines elided ↑ open up ↑
9243 9402           * are allowed. Not allowing change of throttles during draining
9244 9403           * limits error recovery but will reduce draining time
9245 9404           *
9246 9405           * all throttles should have been set to HOLD_THROTTLE
9247 9406           */
9248 9407          if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
9249 9408                  return;
9250 9409          }
9251 9410  
9252 9411          if (what == HOLD_THROTTLE) {
9253      -                ptgt->m_t_throttle = HOLD_THROTTLE;
9254      -        } else if (ptgt->m_reset_delay == 0) {
9255 9412                  ptgt->m_t_throttle = what;
     9413 +        } else if (ptgt->m_reset_delay == 0) {
     9414 +                if (what == MAX_THROTTLE)
     9415 +                        ptgt->m_t_throttle = mpt->m_max_tune_throttle;
     9416 +                else
     9417 +                        ptgt->m_t_throttle = what;
9256 9418          }
9257 9419  }
9258 9420  
9259 9421  /*
9260 9422   * Clean up from a device reset.
9261 9423   * For the case of target reset, this function clears the waitq of all
9262 9424   * commands for a particular target.   For the case of abort task set, this
9263 9425   * function clears the waitq of all commonds for a particular target/lun.
9264 9426   */
9265 9427  static void
↓ open down ↓ 129 lines elided ↑ open up ↑
9395 9557                          }
9396 9558                          cmd = next_cmd;
9397 9559                  }
9398 9560                  mutex_exit(&mpt->m_tx_waitq_mutex);
9399 9561                  break;
9400 9562          default:
9401 9563                  mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
9402 9564                      tasktype);
9403 9565                  break;
9404 9566          }
     9567 +
     9568 +#ifdef MPTSAS_FAULTINJECTION
     9569 +        mptsas_fminj_move_tgt_to_doneq(mpt, target, reason, stat);
     9570 +#endif
9405 9571  }
9406 9572  
9407 9573  /*
9408 9574   * Clean up hba state, abort all outstanding command and commands in waitq
9409 9575   * reset timeout of all targets.
9410 9576   */
9411 9577  static void
9412 9578  mptsas_flush_hba(mptsas_t *mpt)
9413 9579  {
9414 9580          mptsas_slots_t  *slots = mpt->m_active;
↓ open down ↓ 271 lines elided ↑ open up ↑
9686 9852           * driver through the callback routine, with pkt_reason set to
9687 9853           * CMD_ABORTED.
9688 9854           *
9689 9855           * abort cmd pkt on HBA hardware; clean out of outstanding
9690 9856           * command lists, etc.
9691 9857           */
9692 9858          if (pkt != NULL) {
9693 9859                  /* abort the specified packet */
9694 9860                  sp = PKT2CMD(pkt);
9695 9861  
     9862 +#ifdef MPTSAS_FAULTINJECTION
     9863 +        /* Command already on the list. */
     9864 +        if (((pkt->pkt_flags & FLAG_PKT_TIMEOUT) != 0) &&
     9865 +            (sp->cmd_active_expiration != 0)) {
     9866 +                mptsas_fminj_move_cmd_to_doneq(mpt, sp, CMD_ABORTED,
     9867 +                    STAT_ABORTED);
     9868 +                rval = TRUE;
     9869 +                goto done;
     9870 +        }
     9871 +#endif
     9872 +
9696 9873                  if (sp->cmd_queued) {
9697 9874                          NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
9698 9875                              (void *)sp));
9699 9876                          mptsas_waitq_delete(mpt, sp);
9700 9877                          mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
9701 9878                              STAT_ABORTED);
9702 9879                          mptsas_doneq_add(mpt, sp);
9703 9880                          rval = TRUE;
9704 9881                          goto done;
9705 9882                  }
↓ open down ↓ 270 lines elided ↑ open up ↑
9976 10153          } else {
9977 10154                  dev = 0;
9978 10155          }
9979 10156  
9980 10157          mutex_enter(&mptsas_log_mutex);
9981 10158  
9982 10159          va_start(ap, fmt);
9983 10160          (void) vsprintf(mptsas_log_buf, fmt, ap);
9984 10161          va_end(ap);
9985 10162  
9986      -        if (level == CE_CONT) {
9987      -                scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
     10163 +        if (level == CE_CONT || level == CE_NOTE) {
     10164 +                scsi_log(dev, mptsas_label, level, "!%s\n", mptsas_log_buf);
9988 10165          } else {
9989      -                scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
     10166 +                scsi_log(dev, mptsas_label, level, "!%s", mptsas_log_buf);
9990 10167          }
9991 10168  
9992 10169          mutex_exit(&mptsas_log_mutex);
9993 10170  }
9994 10171  
9995 10172  #ifdef MPTSAS_DEBUG
9996 10173  /*
9997 10174   * Use a circular buffer to log messages to private memory.
9998 10175   * Increment idx atomically to minimize risk to miss lines.
9999 10176   * It's fast and does not hold up the proceedings too much.
↓ open down ↓ 47 lines elided ↑ open up ↑
10047 10224  static void
10048 10225  mptsas_watch(void *arg)
10049 10226  {
10050 10227  #ifndef __lock_lint
10051 10228          _NOTE(ARGUNUSED(arg))
10052 10229  #endif
10053 10230  
10054 10231          mptsas_t        *mpt;
10055 10232          uint32_t        doorbell;
10056 10233  
     10234 +#ifdef MPTSAS_FAULTINJECTION
     10235 +        struct mptsas_active_cmdq finj_cmds;
     10236 +
     10237 +        TAILQ_INIT(&finj_cmds);
     10238 +#endif
     10239 +
10057 10240          NDBG30(("mptsas_watch"));
10058 10241  
10059 10242          rw_enter(&mptsas_global_rwlock, RW_READER);
10060 10243          for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
10061 10244  
10062 10245                  mutex_enter(&mpt->m_mutex);
10063 10246  
10064 10247                  /* Skip device if not powered on */
10065 10248                  if (mpt->m_options & MPTSAS_OPT_PM) {
10066 10249                          if (mpt->m_power_level == PM_LEVEL_D0) {
↓ open down ↓ 23 lines elided ↑ open up ↑
10090 10273                  /*
10091 10274                   * For now, always call mptsas_watchsubr.
10092 10275                   */
10093 10276                  mptsas_watchsubr(mpt);
10094 10277  
10095 10278                  if (mpt->m_options & MPTSAS_OPT_PM) {
10096 10279                          mpt->m_busy = 0;
10097 10280                          (void) pm_idle_component(mpt->m_dip, 0);
10098 10281                  }
10099 10282  
     10283 +#ifdef MPTSAS_FAULTINJECTION
     10284 +                mptsas_fminj_watchsubr(mpt, &finj_cmds);
     10285 +#endif
     10286 +
10100 10287                  mutex_exit(&mpt->m_mutex);
10101 10288          }
10102 10289          rw_exit(&mptsas_global_rwlock);
10103 10290  
10104 10291          mutex_enter(&mptsas_global_mutex);
10105 10292          if (mptsas_timeouts_enabled)
10106 10293                  mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
10107 10294          mutex_exit(&mptsas_global_mutex);
     10295 +
     10296 +#ifdef MPTSAS_FAULTINJECTION
     10297 +        /* Complete all completed commands. */
     10298 +        if (!TAILQ_EMPTY(&finj_cmds)) {
     10299 +                mptsas_cmd_t *cmd;
     10300 +
     10301 +                while ((cmd = TAILQ_FIRST(&finj_cmds)) != NULL) {
     10302 +                        TAILQ_REMOVE(&finj_cmds, cmd, cmd_active_link);
     10303 +                        struct scsi_pkt *pkt = cmd->cmd_pkt;
     10304 +
     10305 +                        if (pkt->pkt_comp != NULL) {
     10306 +                                (*pkt->pkt_comp)(pkt);
     10307 +                        }
     10308 +                }
     10309 +        }
     10310 +#endif
10108 10311  }
10109 10312  
10110 10313  static void
10111 10314  mptsas_watchsubr_tgt(mptsas_t *mpt, mptsas_target_t *ptgt, hrtime_t timestamp)
10112 10315  {
10113 10316          mptsas_cmd_t    *cmd;
10114 10317  
10115 10318          /*
10116 10319           * If we were draining due to a qfull condition,
10117 10320           * go back to full throttle.
↓ open down ↓ 546 lines elided ↑ open up ↑
10664 10867           */
10665 10868          req = (pMpi2FWDownloadRequest)pt->request;
10666 10869          tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL;
10667 10870          if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10668 10871              tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10669 10872                  mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10670 10873          }
10671 10874  
10672 10875          pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) +
10673 10876              sizeof (*tcsge);
10674      -        if (pt->request_size != pt->sgl_offset)
     10877 +        if (pt->request_size != pt->sgl_offset) {
10675 10878                  NDBG15(("mpi_pre_fw_download(): Incorrect req size, "
10676 10879                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10677 10880                      (int)pt->request_size, (int)pt->sgl_offset,
10678 10881                      (int)pt->dataout_size));
10679      -        if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
     10882 +        }
     10883 +        if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) {
10680 10884                  NDBG15(("mpi_pre_fw_download(): Incorrect rep size, "
10681 10885                      "0x%x, should be 0x%x", pt->data_size,
10682 10886                      (int)sizeof (MPI2_FW_DOWNLOAD_REPLY)));
     10887 +        }
10683 10888  }
10684 10889  
10685 10890  /*
10686 10891   * Prepare the pt for a SAS3 FW_DOWNLOAD request.
10687 10892   */
10688 10893  static void
10689 10894  mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt)
10690 10895  {
10691 10896          pMpi2FWDownloadTCSGE_t tcsge;
10692 10897          pMpi2FWDownloadRequest req2;
↓ open down ↓ 9 lines elided ↑ open up ↑
10702 10907          req25 = (pMpi25FWDownloadRequest)pt->request;
10703 10908          tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL;
10704 10909          if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10705 10910              tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10706 10911                  mptsas_log(mpt, CE_WARN, "FW Download tce invalid!");
10707 10912          }
10708 10913          req25->ImageOffset = tcsge->ImageOffset;
10709 10914          req25->ImageSize = tcsge->ImageSize;
10710 10915  
10711 10916          pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL);
10712      -        if (pt->request_size != pt->sgl_offset)
     10917 +        if (pt->request_size != pt->sgl_offset) {
10713 10918                  NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, "
10714 10919                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10715 10920                      pt->request_size, pt->sgl_offset,
10716 10921                      pt->dataout_size));
10717      -        if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY))
     10922 +        }
     10923 +        if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) {
10718 10924                  NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, "
10719 10925                      "0x%x, should be 0x%x", pt->data_size,
10720 10926                      (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
     10927 +        }
10721 10928  }
10722 10929  
10723 10930  /*
10724 10931   * Prepare the pt for a SAS2 FW_UPLOAD request.
10725 10932   */
10726 10933  static void
10727 10934  mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10728 10935  {
10729 10936          pMpi2FWUploadTCSGE_t tcsge;
10730 10937          pMpi2FWUploadRequest_t req;
↓ open down ↓ 15 lines elided ↑ open up ↑
10746 10953           */
10747 10954          req = (pMpi2FWUploadRequest_t)pt->request;
10748 10955          tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL;
10749 10956          if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10750 10957              tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10751 10958                  mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10752 10959          }
10753 10960  
10754 10961          pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) +
10755 10962              sizeof (*tcsge);
10756      -        if (pt->request_size != pt->sgl_offset)
     10963 +        if (pt->request_size != pt->sgl_offset) {
10757 10964                  NDBG15(("mpi_pre_fw_upload(): Incorrect req size, "
10758 10965                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10759 10966                      pt->request_size, pt->sgl_offset,
10760 10967                      pt->dataout_size));
10761      -        if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
     10968 +        }
     10969 +        if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) {
10762 10970                  NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, "
10763 10971                      "0x%x, should be 0x%x", pt->data_size,
10764 10972                      (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
     10973 +        }
10765 10974  }
10766 10975  
10767 10976  /*
10768 10977   * Prepare the pt a SAS3 FW_UPLOAD request.
10769 10978   */
10770 10979  static void
10771 10980  mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt)
10772 10981  {
10773 10982          pMpi2FWUploadTCSGE_t tcsge;
10774 10983          pMpi2FWUploadRequest_t req2;
↓ open down ↓ 9 lines elided ↑ open up ↑
10784 10993          req25 = (pMpi25FWUploadRequest_t)pt->request;
10785 10994          tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL;
10786 10995          if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 ||
10787 10996              tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) {
10788 10997                  mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!");
10789 10998          }
10790 10999          req25->ImageOffset = tcsge->ImageOffset;
10791 11000          req25->ImageSize = tcsge->ImageSize;
10792 11001  
10793 11002          pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL);
10794      -        if (pt->request_size != pt->sgl_offset)
     11003 +        if (pt->request_size != pt->sgl_offset) {
10795 11004                  NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, "
10796 11005                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10797 11006                      pt->request_size, pt->sgl_offset,
10798 11007                      pt->dataout_size));
10799      -        if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY))
     11008 +        }
     11009 +        if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) {
10800 11010                  NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, "
10801 11011                      "0x%x, should be 0x%x", pt->data_size,
10802 11012                      (int)sizeof (MPI2_FW_UPLOAD_REPLY)));
     11013 +        }
10803 11014  }
10804 11015  
10805 11016  /*
10806 11017   * Prepare the pt for an IOC_FACTS request.
10807 11018   */
10808 11019  static void
10809 11020  mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10810 11021  {
10811 11022  #ifndef __lock_lint
10812 11023          _NOTE(ARGUNUSED(mpt))
10813 11024  #endif
10814      -        if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST))
     11025 +        if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST)) {
10815 11026                  NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, "
10816 11027                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10817 11028                      pt->request_size,
10818 11029                      (int)sizeof (MPI2_IOC_FACTS_REQUEST),
10819 11030                      pt->dataout_size));
10820      -        if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY))
     11031 +        }
     11032 +        if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY)) {
10821 11033                  NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, "
10822 11034                      "0x%x, should be 0x%x", pt->data_size,
10823 11035                      (int)sizeof (MPI2_IOC_FACTS_REPLY)));
     11036 +        }
10824 11037          pt->sgl_offset = (uint16_t)pt->request_size;
10825 11038  }
10826 11039  
10827 11040  /*
10828 11041   * Prepare the pt for a PORT_FACTS request.
10829 11042   */
10830 11043  static void
10831 11044  mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt)
10832 11045  {
10833 11046  #ifndef __lock_lint
10834 11047          _NOTE(ARGUNUSED(mpt))
10835 11048  #endif
10836      -        if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST))
     11049 +        if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST)) {
10837 11050                  NDBG15(("mpi_pre_port_facts(): Incorrect req size, "
10838 11051                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10839 11052                      pt->request_size,
10840 11053                      (int)sizeof (MPI2_PORT_FACTS_REQUEST),
10841 11054                      pt->dataout_size));
10842      -        if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY))
     11055 +        }
     11056 +        if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY)) {
10843 11057                  NDBG15(("mpi_pre_port_facts(): Incorrect rep size, "
10844 11058                      "0x%x, should be 0x%x", pt->data_size,
10845 11059                      (int)sizeof (MPI2_PORT_FACTS_REPLY)));
     11060 +        }
10846 11061          pt->sgl_offset = (uint16_t)pt->request_size;
10847 11062  }
10848 11063  
10849 11064  /*
10850 11065   * Prepare pt for a SATA_PASSTHROUGH request.
10851 11066   */
10852 11067  static void
10853 11068  mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10854 11069  {
10855 11070  #ifndef __lock_lint
10856 11071          _NOTE(ARGUNUSED(mpt))
10857 11072  #endif
10858 11073          pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL);
10859      -        if (pt->request_size != pt->sgl_offset)
     11074 +        if (pt->request_size != pt->sgl_offset) {
10860 11075                  NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, "
10861 11076                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10862 11077                      pt->request_size, pt->sgl_offset,
10863 11078                      pt->dataout_size));
10864      -        if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY))
     11079 +        }
     11080 +        if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY)) {
10865 11081                  NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, "
10866 11082                      "0x%x, should be 0x%x", pt->data_size,
10867 11083                      (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY)));
     11084 +        }
10868 11085  }
10869 11086  
10870 11087  static void
10871 11088  mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt)
10872 11089  {
10873 11090  #ifndef __lock_lint
10874 11091          _NOTE(ARGUNUSED(mpt))
10875 11092  #endif
10876 11093          pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL);
10877      -        if (pt->request_size != pt->sgl_offset)
     11094 +        if (pt->request_size != pt->sgl_offset) {
10878 11095                  NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, "
10879 11096                      "0x%x, should be 0x%x, dataoutsz 0x%x",
10880 11097                      pt->request_size, pt->sgl_offset,
10881 11098                      pt->dataout_size));
10882      -        if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY))
     11099 +        }
     11100 +        if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY)) {
10883 11101                  NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, "
10884 11102                      "0x%x, should be 0x%x", pt->data_size,
10885 11103                      (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY)));
     11104 +        }
10886 11105  }
10887 11106  
10888 11107  /*
10889 11108   * Prepare pt for a CONFIG request.
10890 11109   */
10891 11110  static void
10892 11111  mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt)
10893 11112  {
10894 11113  #ifndef __lock_lint
10895 11114          _NOTE(ARGUNUSED(mpt))
10896 11115  #endif
10897 11116          pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE);
10898      -        if (pt->request_size != pt->sgl_offset)
     11117 +        if (pt->request_size != pt->sgl_offset) {
10899 11118                  NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10900 11119                      "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10901 11120                      pt->sgl_offset, pt->dataout_size));
10902      -        if (pt->data_size != sizeof (MPI2_CONFIG_REPLY))
     11121 +        }
     11122 +        if (pt->data_size != sizeof (MPI2_CONFIG_REPLY)) {
10903 11123                  NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10904 11124                      "should be 0x%x", pt->data_size,
10905 11125                      (int)sizeof (MPI2_CONFIG_REPLY)));
     11126 +        }
10906 11127          pt->simple = 1;
10907 11128  }
10908 11129  
10909 11130  /*
10910 11131   * Prepare pt for a SCSI_IO_REQ request.
10911 11132   */
10912 11133  static void
10913 11134  mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt)
10914 11135  {
10915 11136  #ifndef __lock_lint
10916 11137          _NOTE(ARGUNUSED(mpt))
10917 11138  #endif
10918 11139          pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL);
10919      -        if (pt->request_size != pt->sgl_offset)
     11140 +        if (pt->request_size != pt->sgl_offset) {
10920 11141                  NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, "
10921 11142                      "should be 0x%x, dataoutsz 0x%x", pt->request_size,
10922 11143                      pt->sgl_offset,
10923 11144                      pt->dataout_size));
10924      -        if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY))
     11145 +        }
     11146 +        if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY)) {
10925 11147                  NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, "
10926 11148                      "should be 0x%x", pt->data_size,
10927 11149                      (int)sizeof (MPI2_SCSI_IO_REPLY)));
     11150 +        }
10928 11151  }
10929 11152  
10930 11153  /*
10931 11154   * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request.
10932 11155   */
10933 11156  static void
10934 11157  mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt)
10935 11158  {
10936 11159  #ifndef __lock_lint
10937 11160          _NOTE(ARGUNUSED(mpt))
↓ open down ↓ 184 lines elided ↑ open up ↑
11122 11345          mptsas_prep_sgl_offset(mpt, &pt);
11123 11346  
11124 11347          /*
11125 11348           * Form a blank cmd/pkt to store the acknowledgement message
11126 11349           */
11127 11350          pkt->pkt_cdbp           = (opaque_t)&cmd->cmd_cdb[0];
11128 11351          pkt->pkt_scbp           = (opaque_t)&cmd->cmd_scb;
11129 11352          pkt->pkt_ha_private     = (opaque_t)&pt;
11130 11353          pkt->pkt_flags          = FLAG_HEAD;
11131 11354          pkt->pkt_time           = timeout;
     11355 +        pkt->pkt_start          = gethrtime();
11132 11356          cmd->cmd_pkt            = pkt;
11133 11357          cmd->cmd_flags          = CFLAG_CMDIOC | CFLAG_PASSTHRU;
11134 11358  
11135 11359          if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
11136 11360              (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
11137 11361                  uint8_t                 com, cdb_group_id;
11138 11362                  boolean_t               ret;
11139 11363  
11140 11364                  pkt->pkt_cdbp = ((pMpi2SCSIIORequest_t)request_msg)->CDB.CDB32;
11141 11365                  com = pkt->pkt_cdbp[0];
↓ open down ↓ 1432 lines elided ↑ open up ↑
12574 12798  
12575 12799          mutex_exit(&mpt->m_mutex);
12576 12800          return (status);
12577 12801  }
12578 12802  
12579 12803  static int
12580 12804  led_control(mptsas_t *mpt, intptr_t data, int mode)
12581 12805  {
12582 12806          int ret = 0;
12583 12807          mptsas_led_control_t lc;
12584      -        mptsas_target_t *ptgt;
     12808 +        mptsas_enclosure_t *mep;
     12809 +        uint16_t slotidx;
12585 12810  
12586 12811          if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
12587 12812                  return (EFAULT);
12588 12813          }
12589 12814  
12590 12815          if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
12591 12816              lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
12592 12817              lc.Led < MPTSAS_LEDCTL_LED_MIN ||
12593 12818              lc.Led > MPTSAS_LEDCTL_LED_MAX ||
12594 12819              (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
12595 12820              lc.LedStatus != 1)) {
12596 12821                  return (EINVAL);
12597 12822          }
12598 12823  
12599 12824          if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
12600 12825              (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
12601 12826                  return (EACCES);
12602 12827  
12603      -        /* Locate the target we're interrogating... */
     12828 +        /* Locate the required enclosure */
12604 12829          mutex_enter(&mpt->m_mutex);
12605      -        ptgt = refhash_linear_search(mpt->m_targets,
12606      -            mptsas_target_eval_slot, &lc);
12607      -        if (ptgt == NULL) {
12608      -                /* We could not find a target for that enclosure/slot. */
     12830 +        mep = mptsas_enc_lookup(mpt, lc.Enclosure);
     12831 +        if (mep == NULL) {
12609 12832                  mutex_exit(&mpt->m_mutex);
12610 12833                  return (ENOENT);
12611 12834          }
12612 12835  
     12836 +        if (lc.Slot < mep->me_fslot) {
     12837 +                mutex_exit(&mpt->m_mutex);
     12838 +                return (ENOENT);
     12839 +        }
     12840 +
     12841 +        /*
     12842 +         * Slots on the enclosure are maintained in array where me_fslot is
     12843 +         * entry zero. We normalize the requested slot.
     12844 +         */
     12845 +        slotidx = lc.Slot - mep->me_fslot;
     12846 +        if (slotidx >= mep->me_nslots) {
     12847 +                mutex_exit(&mpt->m_mutex);
     12848 +                return (ENOENT);
     12849 +        }
     12850 +
12613 12851          if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
12614 12852                  /* Update our internal LED state. */
12615      -                ptgt->m_led_status &= ~(1 << (lc.Led - 1));
12616      -                ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
     12853 +                mep->me_slotleds[slotidx] &= ~(1 << (lc.Led - 1));
     12854 +                mep->me_slotleds[slotidx] |= lc.LedStatus << (lc.Led - 1);
12617 12855  
12618 12856                  /* Flush it to the controller. */
12619      -                ret = mptsas_flush_led_status(mpt, ptgt);
     12857 +                ret = mptsas_flush_led_status(mpt, mep, slotidx);
12620 12858                  mutex_exit(&mpt->m_mutex);
12621 12859                  return (ret);
12622 12860          }
12623 12861  
12624 12862          /* Return our internal LED state. */
12625      -        lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
     12863 +        lc.LedStatus = (mep->me_slotleds[slotidx] >> (lc.Led - 1)) & 1;
12626 12864          mutex_exit(&mpt->m_mutex);
12627 12865  
12628 12866          if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
12629 12867                  return (EFAULT);
12630 12868          }
12631 12869  
12632 12870          return (0);
12633 12871  }
12634 12872  
12635 12873  static int
↓ open down ↓ 121 lines elided ↑ open up ↑
12757 12995          }
12758 12996          /* Make sure power level is D0 before accessing registers */
12759 12997          mutex_enter(&mpt->m_mutex);
12760 12998          if (mpt->m_options & MPTSAS_OPT_PM) {
12761 12999                  (void) pm_busy_component(mpt->m_dip, 0);
12762 13000                  if (mpt->m_power_level != PM_LEVEL_D0) {
12763 13001                          mutex_exit(&mpt->m_mutex);
12764 13002                          if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
12765 13003                              DDI_SUCCESS) {
12766 13004                                  mptsas_log(mpt, CE_WARN,
12767      -                                    "mptsas%d: mptsas_ioctl: Raise power "
12768      -                                    "request failed.", mpt->m_instance);
     13005 +                                    "raise power request failed");
12769 13006                                  (void) pm_idle_component(mpt->m_dip, 0);
12770 13007                                  return (ENXIO);
12771 13008                          }
12772 13009                  } else {
12773 13010                          mutex_exit(&mpt->m_mutex);
12774 13011                  }
12775 13012          } else {
12776 13013                  mutex_exit(&mpt->m_mutex);
12777 13014          }
12778 13015  
↓ open down ↓ 13 lines elided ↑ open up ↑
12792 13029                                  goto out;
12793 13030                          }
12794 13031                          addr = ndi_dc_getaddr(dcp);
12795 13032                          ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12796 13033                          if (ptgt == NULL) {
12797 13034                                  NDBG14(("mptsas_ioctl led control: tgt %s not "
12798 13035                                      "found", addr));
12799 13036                                  ndi_dc_freehdl(dcp);
12800 13037                                  goto out;
12801 13038                          }
12802      -                        mutex_enter(&mpt->m_mutex);
12803      -                        if (cmd == DEVCTL_DEVICE_ONLINE) {
12804      -                                ptgt->m_tgt_unconfigured = 0;
12805      -                        } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12806      -                                ptgt->m_tgt_unconfigured = 1;
12807      -                        }
12808      -                        if (cmd == DEVCTL_DEVICE_OFFLINE) {
12809      -                                ptgt->m_led_status |=
12810      -                                    (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12811      -                        } else {
12812      -                                ptgt->m_led_status &=
12813      -                                    ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12814      -                        }
12815      -                        (void) mptsas_flush_led_status(mpt, ptgt);
12816      -                        mutex_exit(&mpt->m_mutex);
12817 13039                          ndi_dc_freehdl(dcp);
12818 13040                  }
12819 13041                  goto out;
12820 13042          }
12821 13043          switch (cmd) {
12822 13044                  case MPTIOCTL_GET_DISK_INFO:
12823 13045                          status = get_disk_info(mpt, data, mode);
12824 13046                          break;
12825 13047                  case MPTIOCTL_LED_CONTROL:
12826 13048                          status = led_control(mpt, data, mode);
↓ open down ↓ 166 lines elided ↑ open up ↑
12993 13215          /*
12994 13216           * Set a flag telling I/O path that we're processing a reset.  This is
12995 13217           * needed because after the reset is complete, the hash table still
12996 13218           * needs to be rebuilt.  If I/Os are started before the hash table is
12997 13219           * rebuilt, I/O errors will occur.  This flag allows I/Os to be marked
12998 13220           * so that they can be retried.
12999 13221           */
13000 13222          mpt->m_in_reset = TRUE;
13001 13223  
13002 13224          /*
13003      -         * Wait until all the allocated sense data buffers for DMA are freed.
13004      -         */
13005      -        while (mpt->m_extreq_sense_refcount > 0)
13006      -                cv_wait(&mpt->m_extreq_sense_refcount_cv, &mpt->m_mutex);
13007      -
13008      -        /*
13009 13225           * Set all throttles to HOLD
13010 13226           */
13011 13227          for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
13012 13228              ptgt = refhash_next(mpt->m_targets, ptgt)) {
13013 13229                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
13014 13230          }
13015 13231  
13016 13232          /*
13017 13233           * Disable interrupts
13018 13234           */
↓ open down ↓ 88 lines elided ↑ open up ↑
13107 13323          /*
13108 13324           * IOC facts can change after a diag reset so all buffers that are
13109 13325           * based on these numbers must be de-allocated and re-allocated.  Get
13110 13326           * new IOC facts each time chip is initialized.
13111 13327           */
13112 13328          if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
13113 13329                  mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
13114 13330                  goto fail;
13115 13331          }
13116 13332  
13117      -        if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
13118      -                goto fail;
     13333 +        if (first_time) {
     13334 +                if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
     13335 +                        goto fail;
     13336 +                }
     13337 +                /*
     13338 +                 * Allocate request message frames, reply free queue, reply
     13339 +                 * descriptor post queue, and reply message frames using
     13340 +                 * latest IOC facts.
     13341 +                 */
     13342 +                if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
     13343 +                        mptsas_log(mpt, CE_WARN,
     13344 +                            "mptsas_alloc_request_frames failed");
     13345 +                        goto fail;
     13346 +                }
     13347 +                if (mptsas_alloc_sense_bufs(mpt) == DDI_FAILURE) {
     13348 +                        mptsas_log(mpt, CE_WARN,
     13349 +                            "mptsas_alloc_sense_bufs failed");
     13350 +                        goto fail;
     13351 +                }
     13352 +                if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
     13353 +                        mptsas_log(mpt, CE_WARN,
     13354 +                            "mptsas_alloc_free_queue failed!");
     13355 +                        goto fail;
     13356 +                }
     13357 +                if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
     13358 +                        mptsas_log(mpt, CE_WARN,
     13359 +                            "mptsas_alloc_post_queue failed!");
     13360 +                        goto fail;
     13361 +                }
     13362 +                if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
     13363 +                        mptsas_log(mpt, CE_WARN,
     13364 +                            "mptsas_alloc_reply_frames failed!");
     13365 +                        goto fail;
     13366 +                }
13119 13367          }
13120      -        /*
13121      -         * Allocate request message frames, reply free queue, reply descriptor
13122      -         * post queue, and reply message frames using latest IOC facts.
13123      -         */
13124      -        if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
13125      -                mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
13126      -                goto fail;
13127      -        }
13128      -        if (mptsas_alloc_sense_bufs(mpt) == DDI_FAILURE) {
13129      -                mptsas_log(mpt, CE_WARN, "mptsas_alloc_sense_bufs failed");
13130      -                goto fail;
13131      -        }
13132      -        if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
13133      -                mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
13134      -                goto fail;
13135      -        }
13136      -        if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
13137      -                mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
13138      -                goto fail;
13139      -        }
13140      -        if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
13141      -                mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!");
13142      -                goto fail;
13143      -        }
13144      -
13145 13368  mur:
13146 13369          /*
13147 13370           * Re-Initialize ioc to operational state
13148 13371           */
13149 13372          if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
13150 13373                  mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
13151 13374                  goto fail;
13152 13375          }
13153 13376  
13154 13377          mptsas_alloc_reply_args(mpt);
↓ open down ↓ 123 lines elided ↑ open up ↑
13278 13501           * Walk capabilities if supported.
13279 13502           */
13280 13503          for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
13281 13504  
13282 13505                  /*
13283 13506                   * Check that we haven't exceeded the maximum number of
13284 13507                   * capabilities and that the pointer is in a valid range.
13285 13508                   */
13286 13509                  if (++cap_count > 48) {
13287 13510                          mptsas_log(mpt, CE_WARN,
13288      -                            "too many device capabilities.\n");
     13511 +                            "too many device capabilities");
13289 13512                          break;
13290 13513                  }
13291 13514                  if (caps_ptr < 64) {
13292 13515                          mptsas_log(mpt, CE_WARN,
13293      -                            "capabilities pointer 0x%x out of range.\n",
     13516 +                            "capabilities pointer 0x%x out of range",
13294 13517                              caps_ptr);
13295 13518                          break;
13296 13519                  }
13297 13520  
13298 13521                  /*
13299 13522                   * Get next capability and check that it is valid.
13300 13523                   * For now, we only support power management.
13301 13524                   */
13302 13525                  cap = pci_config_get8(mpt->m_config_handle, caps_ptr);
13303 13526                  switch (cap) {
13304 13527                          case PCI_CAP_ID_PM:
13305 13528                                  mptsas_log(mpt, CE_NOTE,
13306      -                                    "?mptsas%d supports power management.\n",
13307      -                                    mpt->m_instance);
     13529 +                                    "power management supported");
13308 13530                                  mpt->m_options |= MPTSAS_OPT_PM;
13309 13531  
13310 13532                                  /* Save PMCSR offset */
13311 13533                                  mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR;
13312 13534                                  break;
13313 13535                          /*
13314 13536                           * The following capabilities are valid.  Any others
13315 13537                           * will cause a message to be logged.
13316 13538                           */
13317 13539                          case PCI_CAP_ID_VPD:
13318 13540                          case PCI_CAP_ID_MSI:
13319 13541                          case PCI_CAP_ID_PCIX:
13320 13542                          case PCI_CAP_ID_PCI_E:
13321 13543                          case PCI_CAP_ID_MSI_X:
13322 13544                                  break;
13323 13545                          default:
13324 13546                                  mptsas_log(mpt, CE_NOTE,
13325      -                                    "?mptsas%d unrecognized capability "
13326      -                                    "0x%x.\n", mpt->m_instance, cap);
     13547 +                                    "unrecognized capability 0x%x", cap);
13327 13548                                  break;
13328 13549                  }
13329 13550  
13330 13551                  /*
13331 13552                   * Get next capabilities pointer and clear bits 0,1.
13332 13553                   */
13333 13554                  caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
13334 13555                      (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
13335 13556          }
13336 13557          return (TRUE);
↓ open down ↓ 17 lines elided ↑ open up ↑
13354 13575          /*
13355 13576           * If PCI's capability does not support PM, then don't need
13356 13577           * to registe the pm-components
13357 13578           */
13358 13579          if (!(mpt->m_options & MPTSAS_OPT_PM))
13359 13580                  return (DDI_SUCCESS);
13360 13581          /*
13361 13582           * If power management is supported by this chip, create
13362 13583           * pm-components property for the power management framework
13363 13584           */
13364      -        (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
     13585 +        (void) sprintf(pmc_name, "NAME=mpt_sas%d", mpt->m_instance);
13365 13586          pmc[0] = pmc_name;
13366 13587          if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
13367 13588              "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
13368 13589                  mpt->m_options &= ~MPTSAS_OPT_PM;
13369 13590                  mptsas_log(mpt, CE_WARN,
13370      -                    "mptsas%d: pm-component property creation failed.",
13371      -                    mpt->m_instance);
     13591 +                    "pm-component property creation failed");
13372 13592                  return (DDI_FAILURE);
13373 13593          }
13374 13594  
13375 13595          /*
13376 13596           * Power on device.
13377 13597           */
13378 13598          (void) pm_busy_component(mpt->m_dip, 0);
13379 13599          pmcsr_stat = pci_config_get16(mpt->m_config_handle,
13380 13600              mpt->m_pmcsr_offset);
13381 13601          if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
13382      -                mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
13383      -                    mpt->m_instance);
     13602 +                mptsas_log(mpt, CE_WARN, "power up the device");
13384 13603                  pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
13385 13604                      PCI_PMCSR_D0);
13386 13605          }
13387 13606          if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
13388 13607                  mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
13389 13608                  return (DDI_FAILURE);
13390 13609          }
13391 13610          mpt->m_power_level = PM_LEVEL_D0;
13392 13611          /*
13393 13612           * Set pm idle delay.
↓ open down ↓ 8 lines elided ↑ open up ↑
13402 13621  mptsas_register_intrs(mptsas_t *mpt)
13403 13622  {
13404 13623          dev_info_t *dip;
13405 13624          int intr_types;
13406 13625  
13407 13626          dip = mpt->m_dip;
13408 13627  
13409 13628          /* Get supported interrupt types */
13410 13629          if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
13411 13630                  mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types "
13412      -                    "failed\n");
     13631 +                    "failed");
13413 13632                  return (FALSE);
13414 13633          }
13415 13634  
13416 13635          NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types));
13417 13636  
13418 13637          /*
13419 13638           * Try MSI, but fall back to FIXED
13420 13639           */
13421 13640          if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) {
13422 13641                  if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) {
↓ open down ↓ 33 lines elided ↑ open up ↑
13456 13675          dev_info_t      *dip = mpt->m_dip;
13457 13676          int             avail, actual, count = 0;
13458 13677          int             i, flag, ret;
13459 13678  
13460 13679          NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
13461 13680  
13462 13681          /* Get number of interrupts */
13463 13682          ret = ddi_intr_get_nintrs(dip, intr_type, &count);
13464 13683          if ((ret != DDI_SUCCESS) || (count <= 0)) {
13465 13684                  mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
13466      -                    "ret %d count %d\n", ret, count);
     13685 +                    "ret %d count %d", ret, count);
13467 13686  
13468 13687                  return (DDI_FAILURE);
13469 13688          }
13470 13689  
13471 13690          /* Get number of available interrupts */
13472 13691          ret = ddi_intr_get_navail(dip, intr_type, &avail);
13473 13692          if ((ret != DDI_SUCCESS) || (avail == 0)) {
13474 13693                  mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
13475      -                    "ret %d avail %d\n", ret, avail);
     13694 +                    "ret %d avail %d", ret, avail);
13476 13695  
13477 13696                  return (DDI_FAILURE);
13478 13697          }
13479 13698  
13480 13699          if (avail < count) {
13481 13700                  mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
13482 13701                      "navail() returned %d", count, avail);
13483 13702          }
13484 13703  
13485 13704          /* Mpt only have one interrupt routine */
↓ open down ↓ 5 lines elided ↑ open up ↑
13491 13710          mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
13492 13711          mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
13493 13712  
13494 13713          flag = DDI_INTR_ALLOC_NORMAL;
13495 13714  
13496 13715          /* call ddi_intr_alloc() */
13497 13716          ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
13498 13717              count, &actual, flag);
13499 13718  
13500 13719          if ((ret != DDI_SUCCESS) || (actual == 0)) {
13501      -                mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
     13720 +                mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d",
13502 13721                      ret);
13503 13722                  kmem_free(mpt->m_htable, mpt->m_intr_size);
13504 13723                  return (DDI_FAILURE);
13505 13724          }
13506 13725  
13507 13726          /* use interrupt count returned or abort? */
13508 13727          if (actual < count) {
13509      -                mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
     13728 +                mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d",
13510 13729                      count, actual);
13511 13730          }
13512 13731  
13513 13732          mpt->m_intr_cnt = actual;
13514 13733  
13515 13734          /*
13516 13735           * Get priority for first msi, assume remaining are all the same
13517 13736           */
13518 13737          if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
13519 13738              &mpt->m_intr_pri)) != DDI_SUCCESS) {
13520      -                mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
     13739 +                mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d", ret);
13521 13740  
13522 13741                  /* Free already allocated intr */
13523 13742                  for (i = 0; i < actual; i++) {
13524 13743                          (void) ddi_intr_free(mpt->m_htable[i]);
13525 13744                  }
13526 13745  
13527 13746                  kmem_free(mpt->m_htable, mpt->m_intr_size);
13528 13747                  return (DDI_FAILURE);
13529 13748          }
13530 13749  
13531 13750          /* Test for high level mutex */
13532 13751          if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
13533 13752                  mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
13534      -                    "Hi level interrupt not supported\n");
     13753 +                    "Hi level interrupt not supported");
13535 13754  
13536 13755                  /* Free already allocated intr */
13537 13756                  for (i = 0; i < actual; i++) {
13538 13757                          (void) ddi_intr_free(mpt->m_htable[i]);
13539 13758                  }
13540 13759  
13541 13760                  kmem_free(mpt->m_htable, mpt->m_intr_size);
13542 13761                  return (DDI_FAILURE);
13543 13762          }
13544 13763  
13545 13764          /* Call ddi_intr_add_handler() */
13546 13765          for (i = 0; i < actual; i++) {
13547 13766                  if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
13548 13767                      (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
13549 13768                          mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
13550      -                            "failed %d\n", ret);
     13769 +                            "failed %d", ret);
13551 13770  
13552 13771                          /* Free already allocated intr */
13553 13772                          for (i = 0; i < actual; i++) {
13554 13773                                  (void) ddi_intr_free(mpt->m_htable[i]);
13555 13774                          }
13556 13775  
13557 13776                          kmem_free(mpt->m_htable, mpt->m_intr_size);
13558 13777                          return (DDI_FAILURE);
13559 13778                  }
13560 13779          }
13561 13780  
13562 13781          if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
13563 13782              != DDI_SUCCESS) {
13564      -                mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
     13783 +                mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d", ret);
13565 13784  
13566 13785                  /* Free already allocated intr */
13567 13786                  for (i = 0; i < actual; i++) {
13568 13787                          (void) ddi_intr_free(mpt->m_htable[i]);
13569 13788                  }
13570 13789  
13571 13790                  kmem_free(mpt->m_htable, mpt->m_intr_size);
13572 13791                  return (DDI_FAILURE);
13573 13792          }
13574 13793  
↓ open down ↓ 280 lines elided ↑ open up ↑
13855 14074          uchar_t         *dblk = NULL;
13856 14075          int             inq83_retry = 3;
13857 14076          int             rval = DDI_FAILURE;
13858 14077  
13859 14078          inq83   = kmem_zalloc(inq83_len, KM_SLEEP);
13860 14079  
13861 14080  inq83_retry:
13862 14081          rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
13863 14082              inq83_len, NULL, 1);
13864 14083          if (rval != DDI_SUCCESS) {
13865      -                mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
     14084 +                mptsas_log(mpt, CE_WARN, "mptsas request inquiry page "
13866 14085                      "0x83 for target:%x, lun:%x failed!", target, lun);
13867 14086                  sata_guid = -1;
13868 14087                  goto out;
13869 14088          }
13870 14089          /* According to SAT2, the first descriptor is logic unit name */
13871 14090          dblk = &inq83[4];
13872 14091          if ((dblk[1] & 0x30) != 0) {
13873      -                mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
     14092 +                mptsas_log(mpt, CE_WARN, "Descriptor is not lun associated.");
13874 14093                  goto out;
13875 14094          }
13876 14095          pwwn = (uint64_t *)(void *)(&dblk[4]);
13877 14096          if ((dblk[4] & 0xf0) == 0x50) {
13878 14097                  sata_guid = BE_64(*pwwn);
13879 14098                  goto out;
13880 14099          } else if (dblk[4] == 'A') {
13881 14100                  NDBG20(("SATA drive has no NAA format GUID."));
13882 14101                  goto out;
13883 14102          } else {
↓ open down ↓ 87 lines elided ↑ open up ↑
13971 14190          ap->a_hba_tran = tran_clone;
13972 14191  
13973 14192          pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
13974 14193              data_bp, cdblen, sizeof (struct scsi_arq_status),
13975 14194              0, PKT_CONSISTENT, NULL, NULL);
13976 14195          if (pktp == NULL) {
13977 14196                  goto out;
13978 14197          }
13979 14198          bcopy(cdb, pktp->pkt_cdbp, cdblen);
13980 14199          pktp->pkt_flags = FLAG_NOPARITY;
     14200 +        pktp->pkt_time = mptsas_scsi_pkt_time;
13981 14201          if (scsi_poll(pktp) < 0) {
13982 14202                  goto out;
13983 14203          }
13984 14204          if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
13985 14205                  goto out;
13986 14206          }
13987 14207          if (resid != NULL) {
13988 14208                  *resid = pktp->pkt_resid;
13989 14209          }
13990 14210  
↓ open down ↓ 190 lines elided ↑ open up ↑
14181 14401                  /*
14182 14402                   * DDI group instructed us to use this flag.
14183 14403                   */
14184 14404                  mflags |= NDI_MDI_FALLBACK;
14185 14405                  break;
14186 14406          case BUS_CONFIG_DRIVER:
14187 14407          case BUS_CONFIG_ALL:
14188 14408                  mptsas_config_all(pdip);
14189 14409                  ret = NDI_SUCCESS;
14190 14410                  break;
     14411 +        default:
     14412 +                ret = NDI_FAILURE;
     14413 +                break;
14191 14414          }
14192 14415  
14193 14416          if ((ret == NDI_SUCCESS) && bconfig) {
14194 14417                  ret = ndi_busop_bus_config(pdip, mflags, op,
14195 14418                      (devnm == NULL) ? arg : devnm, childp, 0);
14196 14419          }
14197 14420  
14198 14421          ndi_devi_exit(pdip, circ1);
14199 14422          ndi_devi_exit(scsi_vhci_dip, circ);
14200 14423          if (devnm != NULL)
↓ open down ↓ 27 lines elided ↑ open up ↑
14228 14451  static int
14229 14452  mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
14230 14453      dev_info_t **lundip)
14231 14454  {
14232 14455          int             rval;
14233 14456          mptsas_t                *mpt = DIP2MPT(pdip);
14234 14457          int             phymask;
14235 14458          mptsas_target_t *ptgt = NULL;
14236 14459  
14237 14460          /*
     14461 +         * The phymask exists if the port is active, otherwise
     14462 +         * nothing to do.
     14463 +         */
     14464 +        if (ddi_prop_exists(DDI_DEV_T_ANY, pdip,
     14465 +            DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "phymask") == 0)
     14466 +                return (DDI_FAILURE);
     14467 +
     14468 +        /*
14238 14469           * Get the physical port associated to the iport
14239 14470           */
14240 14471          phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14241 14472              "phymask", 0);
14242 14473  
14243 14474          ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
14244 14475          if (ptgt == NULL) {
14245 14476                  /*
14246 14477                   * didn't match any device by searching
14247 14478                   */
↓ open down ↓ 19 lines elided ↑ open up ↑
14267 14498                          /*
14268 14499                           * The device has changed although the devhdl is the
14269 14500                           * same (Enclosure mapping mode, change drive on the
14270 14501                           * same slot)
14271 14502                           */
14272 14503                          return (DDI_FAILURE);
14273 14504                  }
14274 14505                  return (DDI_SUCCESS);
14275 14506          }
14276 14507  
14277      -        if (phymask == 0) {
     14508 +        /*
     14509 +         * If this is a RAID, configure the volumes
     14510 +         */
     14511 +        if (mpt->m_num_raid_configs > 0) {
14278 14512                  /*
14279 14513                   * Configure IR volume
14280 14514                   */
14281 14515                  rval =  mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
14282 14516                  return (rval);
14283 14517          }
14284 14518          rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
14285 14519  
14286 14520          return (rval);
14287 14521  }
↓ open down ↓ 1 lines elided ↑ open up ↑
14289 14523  static int
14290 14524  mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
14291 14525      dev_info_t **lundip)
14292 14526  {
14293 14527          int             rval;
14294 14528          mptsas_t        *mpt = DIP2MPT(pdip);
14295 14529          mptsas_phymask_t phymask;
14296 14530          mptsas_target_t *ptgt = NULL;
14297 14531  
14298 14532          /*
     14533 +         * The phymask exists if the port is active, otherwise
     14534 +         * nothing to do.
     14535 +         */
     14536 +        if (ddi_prop_exists(DDI_DEV_T_ANY, pdip,
     14537 +            DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "phymask") == 0)
     14538 +                return (DDI_FAILURE);
     14539 +        /*
14299 14540           * Get the physical port associated to the iport
14300 14541           */
14301 14542          phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14302 14543              "phymask", 0);
14303 14544  
14304 14545          ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
14305 14546          if (ptgt == NULL) {
14306 14547                  /*
14307 14548                   * didn't match any device by searching
14308 14549                   */
↓ open down ↓ 159 lines elided ↑ open up ↑
14468 14709          if (saved_repluns == NULL) {
14469 14710                  scsi_free_consistent_buf(repluns_bp);
14470 14711                  return (DDI_FAILURE);
14471 14712          }
14472 14713          for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
14473 14714                  if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
14474 14715                      &lun_num, &lun_addr_type) != DDI_SUCCESS) {
14475 14716                          continue;
14476 14717                  }
14477 14718                  saved_repluns[lun_cnt] = lun_num;
14478      -                if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num))
     14719 +                if ((cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) !=
     14720 +                    NULL) {
14479 14721                          ret = DDI_SUCCESS;
14480      -                else
     14722 +                } else {
14481 14723                          ret = mptsas_probe_lun(pdip, lun_num, &cdip,
14482 14724                              ptgt);
     14725 +                }
14483 14726                  if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
14484 14727                          (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
14485 14728                              MPTSAS_DEV_GONE);
14486 14729                  }
14487 14730          }
14488 14731          mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
14489 14732          kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
14490 14733          scsi_free_consistent_buf(repluns_bp);
14491 14734          return (DDI_SUCCESS);
14492 14735  }
↓ open down ↓ 110 lines elided ↑ open up ↑
14603 14846                                          break;
14604 14847                                  }
14605 14848                          }
14606 14849                  } else {
14607 14850                          continue;
14608 14851                  }
14609 14852                  if (find == 0) {
14610 14853                          /*
14611 14854                           * The lun has not been there already
14612 14855                           */
14613      -                        (void) mptsas_offline_lun(pdip, savechild, NULL,
14614      -                            NDI_DEVI_REMOVE);
     14856 +                        (void) mptsas_offline_lun(savechild, NULL);
14615 14857                  }
14616 14858          }
14617 14859  
14618 14860          pip = mdi_get_next_client_path(pdip, NULL);
14619 14861          while (pip) {
14620 14862                  find = 0;
14621 14863                  savepip = pip;
14622 14864                  addr = MDI_PI(pip)->pi_addr;
14623 14865  
14624 14866                  pip = mdi_get_next_client_path(pdip, pip);
↓ open down ↓ 15 lines elided ↑ open up ↑
14640 14882                                  }
14641 14883                          }
14642 14884                  } else {
14643 14885                          continue;
14644 14886                  }
14645 14887  
14646 14888                  if (find == 0) {
14647 14889                          /*
14648 14890                           * The lun has not been there already
14649 14891                           */
14650      -                        (void) mptsas_offline_lun(pdip, NULL, savepip,
14651      -                            NDI_DEVI_REMOVE);
     14892 +                        (void) mptsas_offline_lun(NULL, savepip);
14652 14893                  }
14653 14894          }
14654 14895  }
14655 14896  
14656 14897  /*
14657 14898   * If this enclosure doesn't exist in the enclosure list, add it. If it does,
14658 14899   * update it.
14659 14900   */
14660 14901  static void
14661 14902  mptsas_enclosure_update(mptsas_t *mpt, mptsas_enclosure_t *mep)
14662 14903  {
14663 14904          mptsas_enclosure_t *m;
14664 14905  
14665 14906          ASSERT(MUTEX_HELD(&mpt->m_mutex));
14666 14907          m = mptsas_enc_lookup(mpt, mep->me_enchdl);
14667 14908          if (m != NULL) {
     14909 +                uint8_t *ledp;
14668 14910                  m->me_flags = mep->me_flags;
     14911 +
     14912 +
     14913 +                /*
     14914 +                 * If the number of slots and the first slot entry in the
     14915 +                 * enclosure has not changed, then we don't need to do anything
     14916 +                 * here. Otherwise, we need to allocate a new array for the LED
     14917 +                 * status of the slot.
     14918 +                 */
     14919 +                if (m->me_fslot == mep->me_fslot &&
     14920 +                    m->me_nslots == mep->me_nslots)
     14921 +                        return;
     14922 +
     14923 +                /*
     14924 +                 * If the number of slots or the first slot has changed, it's
     14925 +                 * not clear that we're really in a place that we can continue
     14926 +                 * to honor the existing flags.
     14927 +                 */
     14928 +                if (mep->me_nslots > 0) {
     14929 +                        ledp = kmem_zalloc(sizeof (uint8_t) * mep->me_nslots,
     14930 +                            KM_SLEEP);
     14931 +                } else {
     14932 +                        ledp = NULL;
     14933 +                }
     14934 +
     14935 +                if (m->me_slotleds != NULL) {
     14936 +                        kmem_free(m->me_slotleds, sizeof (uint8_t) *
     14937 +                            m->me_nslots);
     14938 +                }
     14939 +                m->me_slotleds = ledp;
     14940 +                m->me_fslot = mep->me_fslot;
     14941 +                m->me_nslots = mep->me_nslots;
14669 14942                  return;
14670 14943          }
14671 14944  
14672 14945          m = kmem_zalloc(sizeof (*m), KM_SLEEP);
14673 14946          m->me_enchdl = mep->me_enchdl;
14674 14947          m->me_flags = mep->me_flags;
     14948 +        m->me_nslots = mep->me_nslots;
     14949 +        m->me_fslot = mep->me_fslot;
     14950 +        if (m->me_nslots > 0) {
     14951 +                m->me_slotleds = kmem_zalloc(sizeof (uint8_t) * mep->me_nslots,
     14952 +                    KM_SLEEP);
     14953 +                /*
     14954 +                 * It may make sense to optionally flush all of the slots and/or
     14955 +                 * read the slot status flag here to synchronize between
     14956 +                 * ourselves and the card. So far, that hasn't been needed
     14957 +                 * annecdotally when enumerating something new. If we do, we
     14958 +                 * should kick that off in a taskq potentially.
     14959 +                 */
     14960 +        }
14675 14961          list_insert_tail(&mpt->m_enclosures, m);
14676 14962  }
14677 14963  
14678 14964  static void
14679 14965  mptsas_update_hashtab(struct mptsas *mpt)
14680 14966  {
14681 14967          uint32_t        page_address;
14682 14968          int             rval = 0;
14683 14969          uint16_t        dev_handle;
14684 14970          mptsas_target_t *ptgt = NULL;
↓ open down ↓ 110 lines elided ↑ open up ↑
14795 15081  mptsas_config_all(dev_info_t *pdip)
14796 15082  {
14797 15083          dev_info_t      *smpdip = NULL;
14798 15084          mptsas_t        *mpt = DIP2MPT(pdip);
14799 15085          int             phymask = 0;
14800 15086          mptsas_phymask_t phy_mask;
14801 15087          mptsas_target_t *ptgt = NULL;
14802 15088          mptsas_smp_t    *psmp;
14803 15089  
14804 15090          /*
14805      -         * Get the phymask associated to the iport
     15091 +         * The phymask exists if the port is active, otherwise
     15092 +         * nothing to do.
14806 15093           */
     15094 +        if (ddi_prop_exists(DDI_DEV_T_ANY, pdip,
     15095 +            DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "phymask") == 0)
     15096 +                return;
     15097 +
14807 15098          phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
14808 15099              "phymask", 0);
14809 15100  
14810 15101          /*
14811      -         * Enumerate RAID volumes here (phymask == 0).
     15102 +         * If this is a RAID, enumerate the volumes
14812 15103           */
14813      -        if (phymask == 0) {
     15104 +        if (mpt->m_num_raid_configs > 0) {
14814 15105                  mptsas_config_all_viport(pdip);
14815 15106                  return;
14816 15107          }
14817 15108  
14818 15109          mutex_enter(&mpt->m_mutex);
14819 15110  
14820 15111          if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp ||
14821 15112              !mpt->m_done_traverse_enc) {
14822 15113                  mptsas_update_hashtab(mpt);
14823 15114          }
↓ open down ↓ 66 lines elided ↑ open up ↑
14890 15181                  if ((cp = strchr(addr, ',')) == NULL) {
14891 15182                          continue;
14892 15183                  }
14893 15184  
14894 15185                  s = (uintptr_t)cp - (uintptr_t)addr;
14895 15186  
14896 15187                  if (strncmp(addr, name, s) != 0) {
14897 15188                          continue;
14898 15189                  }
14899 15190  
14900      -                tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
14901      -                    NDI_DEVI_REMOVE);
     15191 +                tmp_rval = mptsas_offline_lun(prechild, NULL);
14902 15192                  if (tmp_rval != DDI_SUCCESS) {
14903 15193                          rval = DDI_FAILURE;
14904 15194                          if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
14905 15195                              prechild, MPTSAS_DEV_GONE) !=
14906 15196                              DDI_PROP_SUCCESS) {
14907 15197                                  mptsas_log(mpt, CE_WARN, "mptsas driver "
14908 15198                                      "unable to create property for "
14909 15199                                      "SAS %s (MPTSAS_DEV_GONE)", addr);
14910 15200                          }
14911 15201                  }
↓ open down ↓ 11 lines elided ↑ open up ↑
14923 15213                  if ((cp = strchr(addr, ',')) == NULL) {
14924 15214                          continue;
14925 15215                  }
14926 15216  
14927 15217                  s = (uintptr_t)cp - (uintptr_t)addr;
14928 15218  
14929 15219                  if (strncmp(addr, name, s) != 0) {
14930 15220                          continue;
14931 15221                  }
14932 15222  
14933      -                (void) mptsas_offline_lun(pdip, NULL, savepip,
14934      -                    NDI_DEVI_REMOVE);
     15223 +                (void) mptsas_offline_lun(NULL, savepip);
14935 15224                  /*
14936 15225                   * driver will not invoke mdi_pi_free, so path will not
14937 15226                   * be freed forever, return DDI_FAILURE.
14938 15227                   */
14939 15228                  rval = DDI_FAILURE;
14940 15229          }
14941 15230          return (rval);
14942 15231  }
14943 15232  
14944 15233  static int
14945      -mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
14946      -    mdi_pathinfo_t *rpip, uint_t flags)
     15234 +mptsas_offline_lun(dev_info_t *rdip, mdi_pathinfo_t *rpip)
14947 15235  {
14948 15236          int             rval = DDI_FAILURE;
14949      -        char            *devname;
14950      -        dev_info_t      *cdip, *parent;
14951 15237  
14952 15238          if (rpip != NULL) {
14953      -                parent = scsi_vhci_dip;
14954      -                cdip = mdi_pi_get_client(rpip);
14955      -        } else if (rdip != NULL) {
14956      -                parent = pdip;
14957      -                cdip = rdip;
14958      -        } else {
14959      -                return (DDI_FAILURE);
14960      -        }
14961      -
14962      -        /*
14963      -         * Make sure node is attached otherwise
14964      -         * it won't have related cache nodes to
14965      -         * clean up.  i_ddi_devi_attached is
14966      -         * similiar to i_ddi_node_state(cdip) >=
14967      -         * DS_ATTACHED.
14968      -         */
14969      -        if (i_ddi_devi_attached(cdip)) {
14970      -
14971      -                /* Get full devname */
14972      -                devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
14973      -                (void) ddi_deviname(cdip, devname);
14974      -                /* Clean cache */
14975      -                (void) devfs_clean(parent, devname + 1,
14976      -                    DV_CLEAN_FORCE);
14977      -                kmem_free(devname, MAXNAMELEN + 1);
14978      -        }
14979      -        if (rpip != NULL) {
14980 15239                  if (MDI_PI_IS_OFFLINE(rpip)) {
14981 15240                          rval = DDI_SUCCESS;
14982 15241                  } else {
14983 15242                          rval = mdi_pi_offline(rpip, 0);
14984 15243                  }
14985      -        } else {
14986      -                rval = ndi_devi_offline(cdip, flags);
     15244 +        } else if (rdip != NULL) {
     15245 +                rval = ndi_devi_offline(rdip,
     15246 +                    NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE | NDI_DEVI_GONE);
14987 15247          }
14988 15248  
14989 15249          return (rval);
14990 15250  }
14991 15251  
14992 15252  static dev_info_t *
14993 15253  mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
14994 15254  {
14995 15255          dev_info_t      *child = NULL;
14996 15256          char            *smp_wwn = NULL;
↓ open down ↓ 11 lines elided ↑ open up ↑
15008 15268                          ddi_prop_free(smp_wwn);
15009 15269                          break;
15010 15270                  }
15011 15271                  child = ddi_get_next_sibling(child);
15012 15272                  ddi_prop_free(smp_wwn);
15013 15273          }
15014 15274          return (child);
15015 15275  }
15016 15276  
15017 15277  static int
15018      -mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
     15278 +mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node)
15019 15279  {
15020 15280          int             rval = DDI_FAILURE;
15021      -        char            *devname;
15022 15281          char            wwn_str[MPTSAS_WWN_STRLEN];
15023 15282          dev_info_t      *cdip;
15024 15283  
15025 15284          (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
15026 15285  
15027 15286          cdip = mptsas_find_smp_child(pdip, wwn_str);
15028      -
15029 15287          if (cdip == NULL)
15030 15288                  return (DDI_SUCCESS);
15031 15289  
15032      -        /*
15033      -         * Make sure node is attached otherwise
15034      -         * it won't have related cache nodes to
15035      -         * clean up.  i_ddi_devi_attached is
15036      -         * similiar to i_ddi_node_state(cdip) >=
15037      -         * DS_ATTACHED.
15038      -         */
15039      -        if (i_ddi_devi_attached(cdip)) {
     15290 +        rval = ndi_devi_offline(cdip, NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE);
15040 15291  
15041      -                /* Get full devname */
15042      -                devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
15043      -                (void) ddi_deviname(cdip, devname);
15044      -                /* Clean cache */
15045      -                (void) devfs_clean(pdip, devname + 1,
15046      -                    DV_CLEAN_FORCE);
15047      -                kmem_free(devname, MAXNAMELEN + 1);
15048      -        }
15049      -
15050      -        rval = ndi_devi_offline(cdip, flags);
15051      -
15052 15292          return (rval);
15053 15293  }
15054 15294  
15055 15295  static dev_info_t *
15056 15296  mptsas_find_child(dev_info_t *pdip, char *name)
15057 15297  {
15058 15298          dev_info_t      *child = NULL;
15059 15299          char            *rname = NULL;
15060 15300          int             rval = DDI_FAILURE;
15061 15301  
↓ open down ↓ 114 lines elided ↑ open up ↑
15176 15416           * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
15177 15417           * give up to get VPD page at this stage and fail the enumeration.
15178 15418           */
15179 15419  
15180 15420          inq83   = kmem_zalloc(inq83_len1, KM_SLEEP);
15181 15421  
15182 15422          for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
15183 15423                  rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
15184 15424                      inq83_len1, &inq83_len, 1);
15185 15425                  if (rval != 0) {
15186      -                        mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
     15426 +                        mptsas_log(mpt, CE_WARN, "mptsas request inquiry page "
15187 15427                              "0x83 for target:%x, lun:%x failed!", target, lun);
15188 15428                          if (mptsas_physical_bind_failed_page_83 != B_FALSE)
15189 15429                                  goto create_lun;
15190 15430                          goto out;
15191 15431                  }
15192 15432                  /*
15193 15433                   * create DEVID from inquiry data
15194 15434                   */
15195 15435                  if ((rval = ddi_devid_scsi_encode(
15196 15436                      DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
↓ open down ↓ 6 lines elided ↑ open up ↑
15203 15443  
15204 15444                          /*
15205 15445                           * Do not enable MPXIO if the strlen(guid) is greater
15206 15446                           * than MPTSAS_MAX_GUID_LEN, this constrain would be
15207 15447                           * handled by framework later.
15208 15448                           */
15209 15449                          if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
15210 15450                                  ddi_devid_free_guid(guid);
15211 15451                                  guid = NULL;
15212 15452                                  if (mpt->m_mpxio_enable == TRUE) {
15213      -                                        mptsas_log(mpt, CE_NOTE, "!Target:%x, "
     15453 +                                        mptsas_log(mpt, CE_NOTE, "Target:%x, "
15214 15454                                              "lun:%x doesn't have a valid GUID, "
15215 15455                                              "multipathing for this drive is "
15216 15456                                              "not enabled", target, lun);
15217 15457                                  }
15218 15458                          }
15219 15459  
15220 15460                          /*
15221 15461                           * devid no longer needed
15222 15462                           */
15223 15463                          ddi_devid_free(devid);
↓ open down ↓ 1 lines elided ↑ open up ↑
15225 15465                  } else if (rval == DDI_NOT_WELL_FORMED) {
15226 15466                          /*
15227 15467                           * return value of ddi_devid_scsi_encode equal to
15228 15468                           * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
15229 15469                           * to retry inquiry page 0x83 and get GUID.
15230 15470                           */
15231 15471                          NDBG20(("Not well formed devid, retry..."));
15232 15472                          delay(1 * drv_usectohz(1000000));
15233 15473                          continue;
15234 15474                  } else {
15235      -                        mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
     15475 +                        mptsas_log(mpt, CE_WARN, "Encode devid failed for "
15236 15476                              "path target:%x, lun:%x", target, lun);
15237 15477                          rval = DDI_FAILURE;
15238 15478                          goto create_lun;
15239 15479                  }
15240 15480          }
15241 15481  
15242 15482          if (i == mptsas_inq83_retry_timeout) {
15243      -                mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
     15483 +                mptsas_log(mpt, CE_WARN, "Repeated page83 requests timeout "
15244 15484                      "for path target:%x, lun:%x", target, lun);
15245 15485          }
15246 15486  
15247 15487          rval = DDI_FAILURE;
15248 15488  
15249 15489  create_lun:
15250 15490          if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
15251 15491                  rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
15252 15492                      ptgt, lun);
15253 15493          }
↓ open down ↓ 67 lines elided ↑ open up ↑
15321 15561                      MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
15322 15562                          if (strncmp(guid, old_guid, strlen(guid)) == 0) {
15323 15563                                  /*
15324 15564                                   * Same path back online again.
15325 15565                                   */
15326 15566                                  (void) ddi_prop_free(old_guid);
15327 15567                                  if ((!MDI_PI_IS_ONLINE(*pip)) &&
15328 15568                                      (!MDI_PI_IS_STANDBY(*pip)) &&
15329 15569                                      (ptgt->m_tgt_unconfigured == 0)) {
15330 15570                                          rval = mdi_pi_online(*pip, 0);
15331      -                                        mutex_enter(&mpt->m_mutex);
15332      -                                        ptgt->m_led_status = 0;
15333      -                                        (void) mptsas_flush_led_status(mpt,
15334      -                                            ptgt);
15335      -                                        mutex_exit(&mpt->m_mutex);
15336 15571                                  } else {
15337 15572                                          rval = DDI_SUCCESS;
15338 15573                                  }
15339 15574                                  if (rval != DDI_SUCCESS) {
15340 15575                                          mptsas_log(mpt, CE_WARN, "path:target: "
15341 15576                                              "%x, lun:%x online failed!", target,
15342 15577                                              lun);
15343 15578                                          *pip = NULL;
15344 15579                                          *lun_dip = NULL;
15345 15580                                  }
↓ open down ↓ 13 lines elided ↑ open up ↑
15359 15594                                          rval = mdi_pi_offline(*pip, 0);
15360 15595                                          if (rval != MDI_SUCCESS) {
15361 15596                                                  mptsas_log(mpt, CE_WARN, "path:"
15362 15597                                                      "target:%x, lun:%x offline "
15363 15598                                                      "failed!", target, lun);
15364 15599                                                  *pip = NULL;
15365 15600                                                  *lun_dip = NULL;
15366 15601                                                  return (DDI_FAILURE);
15367 15602                                          }
15368 15603                                  }
15369      -                                if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
     15604 +                                if (mdi_pi_free(*pip,
     15605 +                                    MDI_CLIENT_FLAGS_NO_EVENT) != MDI_SUCCESS) {
15370 15606                                          mptsas_log(mpt, CE_WARN, "path:target:"
15371 15607                                              "%x, lun:%x free failed!", target,
15372 15608                                              lun);
15373 15609                                          *pip = NULL;
15374 15610                                          *lun_dip = NULL;
15375 15611                                          return (DDI_FAILURE);
15376 15612                                  }
15377 15613                          }
15378 15614                  } else {
15379 15615                          mptsas_log(mpt, CE_WARN, "Can't get client-guid "
↓ open down ↓ 220 lines elided ↑ open up ↑
15600 15836                  if (mdi_prop_update_int(*pip, "phy-num",
15601 15837                      ptgt->m_phynum) != DDI_SUCCESS) {
15602 15838                          mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
15603 15839                              "create phy-num property for target %d lun %d",
15604 15840                              target, lun);
15605 15841                          mdi_rtn = MDI_FAILURE;
15606 15842                          goto virt_create_done;
15607 15843                  }
15608 15844                  NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
15609 15845                  mdi_rtn = mdi_pi_online(*pip, 0);
15610      -                if (mdi_rtn == MDI_SUCCESS) {
15611      -                        mutex_enter(&mpt->m_mutex);
15612      -                        ptgt->m_led_status = 0;
15613      -                        (void) mptsas_flush_led_status(mpt, ptgt);
15614      -                        mutex_exit(&mpt->m_mutex);
15615      -                }
15616 15846                  if (mdi_rtn == MDI_NOT_SUPPORTED) {
15617 15847                          mdi_rtn = MDI_FAILURE;
15618 15848                  }
15619 15849  virt_create_done:
15620 15850                  if (*pip && mdi_rtn != MDI_SUCCESS) {
15621      -                        (void) mdi_pi_free(*pip, 0);
     15851 +                        (void) mdi_pi_free(*pip, MDI_CLIENT_FLAGS_NO_EVENT);
15622 15852                          *pip = NULL;
15623 15853                          *lun_dip = NULL;
15624 15854                  }
15625 15855          }
15626 15856  
15627 15857          scsi_hba_nodename_compatible_free(nodename, compatible);
15628 15858          if (lun_addr != NULL) {
15629 15859                  kmem_free(lun_addr, SCSI_MAXNAMELEN);
15630 15860          }
15631 15861          if (wwn_str != NULL) {
↓ open down ↓ 346 lines elided ↑ open up ↑
15978 16208  phys_create_done:
15979 16209                  /*
15980 16210                   * If props were setup ok, online the lun
15981 16211                   */
15982 16212                  if (ndi_rtn == NDI_SUCCESS) {
15983 16213                          /*
15984 16214                           * Try to online the new node
15985 16215                           */
15986 16216                          ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15987 16217                  }
15988      -                if (ndi_rtn == NDI_SUCCESS) {
15989      -                        mutex_enter(&mpt->m_mutex);
15990      -                        ptgt->m_led_status = 0;
15991      -                        (void) mptsas_flush_led_status(mpt, ptgt);
15992      -                        mutex_exit(&mpt->m_mutex);
15993      -                }
15994 16218  
15995 16219                  /*
15996 16220                   * If success set rtn flag, else unwire alloc'd lun
15997 16221                   */
15998 16222                  if (ndi_rtn != NDI_SUCCESS) {
15999 16223                          NDBG12(("mptsas driver unable to online "
16000 16224                              "target %d lun %d", target, lun));
16001 16225                          ndi_prop_remove_all(*lun_dip);
16002 16226                          (void) ndi_devi_free(*lun_dip);
16003 16227                          *lun_dip = NULL;
↓ open down ↓ 31 lines elided ↑ open up ↑
16035 16259  
16036 16260  static int
16037 16261  mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
16038 16262  {
16039 16263          mptsas_t        *mpt = DIP2MPT(pdip);
16040 16264          mptsas_smp_t    *psmp = NULL;
16041 16265          int             rval;
16042 16266          int             phymask;
16043 16267  
16044 16268          /*
16045      -         * Get the physical port associated to the iport
16046      -         * PHYMASK TODO
     16269 +         * The phymask exists if the port is active, otherwise
     16270 +         * nothing to do.
16047 16271           */
     16272 +        if (ddi_prop_exists(DDI_DEV_T_ANY, pdip,
     16273 +            DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "phymask") == 0)
     16274 +                return (DDI_FAILURE);
     16275 +
16048 16276          phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
16049 16277              "phymask", 0);
16050 16278          /*
16051 16279           * Find the smp node in hash table with specified sas address and
16052 16280           * physical port
16053 16281           */
16054 16282          psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
16055 16283          if (psmp == NULL) {
16056 16284                  return (DDI_FAILURE);
16057 16285          }
↓ open down ↓ 612 lines elided ↑ open up ↑
16670 16898  }
16671 16899  
16672 16900  /*
16673 16901   * Functions for SGPIO LED support
16674 16902   */
16675 16903  static dev_info_t *
16676 16904  mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
16677 16905  {
16678 16906          dev_info_t      *dip;
16679 16907          int             prop;
     16908 +
16680 16909          dip = e_ddi_hold_devi_by_dev(dev, 0);
16681 16910          if (dip == NULL)
16682 16911                  return (dip);
     16912 +
     16913 +        /*
     16914 +         * The phymask exists if the port is active, otherwise
     16915 +         * nothing to do.
     16916 +         */
     16917 +        if (ddi_prop_exists(DDI_DEV_T_ANY, dip,
     16918 +            DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "phymask") == 0) {
     16919 +                ddi_release_devi(dip);
     16920 +                return ((dev_info_t *)NULL);
     16921 +        }
     16922 +
16683 16923          prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
16684 16924              "phymask", 0);
     16925 +
16685 16926          *phymask = (mptsas_phymask_t)prop;
16686 16927          ddi_release_devi(dip);
16687 16928          return (dip);
16688 16929  }
16689 16930  static mptsas_target_t *
16690 16931  mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16691 16932  {
16692 16933          uint8_t                 phynum;
16693 16934          uint64_t                wwn;
16694 16935          int                     lun;
↓ open down ↓ 4 lines elided ↑ open up ↑
16699 16940          }
16700 16941          if (addr[0] == 'w') {
16701 16942                  ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16702 16943          } else {
16703 16944                  ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16704 16945          }
16705 16946          return (ptgt);
16706 16947  }
16707 16948  
16708 16949  static int
16709      -mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt)
     16950 +mptsas_flush_led_status(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx)
16710 16951  {
16711 16952          uint32_t slotstatus = 0;
16712 16953  
     16954 +        ASSERT3U(idx, <, mep->me_nslots);
     16955 +
16713 16956          /* Build an MPI2 Slot Status based on our view of the world */
16714      -        if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
     16957 +        if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
16715 16958                  slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
16716      -        if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
     16959 +        if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
16717 16960                  slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
16718      -        if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
     16961 +        if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
16719 16962                  slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
16720 16963  
16721 16964          /* Write it to the controller */
16722 16965          NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16723      -            slotstatus, ptgt->m_slot_num));
16724      -        return (mptsas_send_sep(mpt, ptgt, &slotstatus,
     16966 +            slotstatus, idx + mep->me_fslot));
     16967 +        return (mptsas_send_sep(mpt, mep, idx, &slotstatus,
16725 16968              MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16726 16969  }
16727 16970  
16728 16971  /*
16729 16972   *  send sep request, use enclosure/slot addressing
16730 16973   */
16731 16974  static int
16732      -mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
     16975 +mptsas_send_sep(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx,
16733 16976      uint32_t *status, uint8_t act)
16734 16977  {
16735 16978          Mpi2SepRequest_t        req;
16736 16979          Mpi2SepReply_t          rep;
16737 16980          int                     ret;
16738      -        mptsas_enclosure_t      *mep;
16739 16981          uint16_t                enctype;
     16982 +        uint16_t                slot;
16740 16983  
16741 16984          ASSERT(mutex_owned(&mpt->m_mutex));
16742 16985  
16743 16986          /*
16744      -         * We only support SEP control of directly-attached targets, in which
16745      -         * case the "SEP" we're talking to is a virtual one contained within
16746      -         * the HBA itself.  This is necessary because DA targets typically have
16747      -         * no other mechanism for LED control.  Targets for which a separate
16748      -         * enclosure service processor exists should be controlled via ses(7d)
16749      -         * or sgen(7d).  Furthermore, since such requests can time out, they
16750      -         * should be made in user context rather than in response to
16751      -         * asynchronous fabric changes.
16752      -         *
16753      -         * In addition, we do not support this operation for RAID volumes,
16754      -         * since there is no slot associated with them.
16755      -         */
16756      -        if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
16757      -            ptgt->m_addr.mta_phymask == 0) {
16758      -                return (ENOTTY);
16759      -        }
16760      -
16761      -        /*
16762 16987           * Look through the enclosures and make sure that this enclosure is
16763 16988           * something that is directly attached device. If we didn't find an
16764 16989           * enclosure for this device, don't send the ioctl.
16765 16990           */
16766      -        mep = mptsas_enc_lookup(mpt, ptgt->m_enclosure);
16767      -        if (mep == NULL)
16768      -                return (ENOTTY);
16769 16991          enctype = mep->me_flags & MPI2_SAS_ENCLS0_FLAGS_MNG_MASK;
16770 16992          if (enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES &&
16771 16993              enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO &&
16772 16994              enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO) {
16773 16995                  return (ENOTTY);
16774 16996          }
     16997 +        slot = idx + mep->me_fslot;
16775 16998  
16776 16999          bzero(&req, sizeof (req));
16777 17000          bzero(&rep, sizeof (rep));
16778 17001  
16779 17002          req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
16780 17003          req.Action = act;
16781 17004          req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
16782      -        req.EnclosureHandle = LE_16(ptgt->m_enclosure);
16783      -        req.Slot = LE_16(ptgt->m_slot_num);
     17005 +        req.EnclosureHandle = LE_16(mep->me_enchdl);
     17006 +        req.Slot = LE_16(slot);
16784 17007          if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16785 17008                  req.SlotStatus = LE_32(*status);
16786 17009          }
16787 17010          ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
16788 17011              sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
16789 17012          if (ret != 0) {
16790 17013                  mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
16791 17014                      "Processor Request message error %d", ret);
16792 17015                  return (ret);
16793 17016          }
↓ open down ↓ 83 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX