Print this page
XXXX Nexenta fixes for mpt_sas(7d)

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 ↓ 59 lines elided ↑ open up ↑
  60   60  #define MPTSAS_DEBUG
  61   61  #endif
  62   62  
  63   63  /*
  64   64   * standard header files.
  65   65   */
  66   66  #include <sys/note.h>
  67   67  #include <sys/scsi/scsi.h>
  68   68  #include <sys/pci.h>
  69   69  #include <sys/file.h>
  70      -#include <sys/cpuvar.h>
  71   70  #include <sys/policy.h>
  72   71  #include <sys/sysevent.h>
  73   72  #include <sys/sysevent/eventdefs.h>
  74   73  #include <sys/sysevent/dr.h>
  75   74  #include <sys/sata/sata_defs.h>
  76   75  #include <sys/scsi/generic/sas.h>
  77   76  #include <sys/scsi/impl/scsi_sas.h>
  78   77  
  79   78  #pragma pack(1)
  80   79  #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
↓ open down ↓ 7 lines elided ↑ open up ↑
  88   87  #pragma pack()
  89   88  
  90   89  /*
  91   90   * private header files.
  92   91   *
  93   92   */
  94   93  #include <sys/scsi/impl/scsi_reset_notify.h>
  95   94  #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
  96   95  #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
  97   96  #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
  98      -
  99   97  #include <sys/raidioctl.h>
 100   98  
 101   99  #include <sys/fs/dv_node.h>     /* devfs_clean */
 102  100  
 103  101  /*
 104  102   * FMA header files
 105  103   */
 106  104  #include <sys/ddifm.h>
 107  105  #include <sys/fm/protocol.h>
 108  106  #include <sys/fm/util.h>
 109  107  #include <sys/fm/io/ddi.h>
 110  108  
 111  109  /*
 112      - * For anyone who would modify the code in mptsas_driver, it must be awared
 113      - * that from snv_145 where CR6910752(mpt_sas driver performance can be
 114      - * improved) is integrated, the per_instance mutex m_mutex is not hold
 115      - * in the key IO code path, including mptsas_scsi_start(), mptsas_intr()
 116      - * and all of the recursive functions called in them, so don't
 117      - * make it for granted that all operations are sync/exclude correctly. Before
 118      - * doing any modification in key code path, and even other code path such as
 119      - * DR, watchsubr, ioctl, passthrough etc, make sure the elements modified have
 120      - * no releationship to elements shown in the fastpath
 121      - * (function mptsas_handle_io_fastpath()) in ISR and its recursive functions.
 122      - * otherwise, you have to use the new introduced mutex to protect them.
 123      - * As to how to do correctly, refer to the comments in mptsas_intr().
 124      - */
 125      -
 126      -/*
 127  110   * autoconfiguration data and routines.
 128  111   */
 129  112  static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
 130  113  static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
 131  114  static int mptsas_power(dev_info_t *dip, int component, int level);
 132  115  
 133  116  /*
 134  117   * cb_ops function
 135  118   */
 136  119  static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
↓ open down ↓ 72 lines elided ↑ open up ↑
 209  192  static int mptsas_quiesce_bus(mptsas_t *mpt);
 210  193  static int mptsas_unquiesce_bus(mptsas_t *mpt);
 211  194  
 212  195  static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size);
 213  196  static void mptsas_free_handshake_msg(mptsas_t *mpt);
 214  197  
 215  198  static void mptsas_ncmds_checkdrain(void *arg);
 216  199  
 217  200  static int mptsas_prepare_pkt(mptsas_cmd_t *cmd);
 218  201  static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
      202 +static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
      203 +static void mptsas_accept_tx_waitq(mptsas_t *mpt);
 219  204  
 220  205  static int mptsas_do_detach(dev_info_t *dev);
 221  206  static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl);
 222  207  static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun,
 223  208      struct scsi_pkt *pkt);
 224  209  static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp);
 225  210  
 226  211  static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd);
 227  212  static void mptsas_handle_event(void *args);
 228  213  static int mptsas_handle_event_sync(void *args);
↓ open down ↓ 5 lines elided ↑ open up ↑
 234  219  
 235  220  static void mptsas_flush_hba(mptsas_t *mpt);
 236  221  static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
 237  222          uint8_t tasktype);
 238  223  static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
 239  224      uchar_t reason, uint_t stat);
 240  225  
 241  226  static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
 242  227  static void mptsas_process_intr(mptsas_t *mpt,
 243  228      pMpi2ReplyDescriptorsUnion_t reply_desc_union);
 244      -static int mptsas_handle_io_fastpath(mptsas_t *mpt, uint16_t SMID);
 245  229  static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
 246  230      pMpi2ReplyDescriptorsUnion_t reply_desc);
 247  231  static void mptsas_handle_address_reply(mptsas_t *mpt,
 248  232      pMpi2ReplyDescriptorsUnion_t reply_desc);
 249  233  static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
 250  234  static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
 251  235      uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
 252  236  
 253  237  static void mptsas_watch(void *arg);
 254  238  static void mptsas_watchsubr(mptsas_t *mpt);
 255  239  static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl);
      240 +static void mptsas_kill_target(mptsas_t *mpt, mptsas_target_t *ptgt);
 256  241  
 257  242  static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
 258  243  static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
 259  244      uint8_t *data, uint32_t request_size, uint32_t reply_size,
 260  245      uint32_t data_size, uint32_t direction, uint8_t *dataout,
 261  246      uint32_t dataout_size, short timeout, int mode);
 262  247  static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
 263  248  
 264  249  static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
 265  250      uint32_t unique_id);
↓ open down ↓ 35 lines elided ↑ open up ↑
 301  286      mptsas_cmd_t *cmd);
 302  287  static void mptsas_check_task_mgt(mptsas_t *mpt,
 303  288      pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd);
 304  289  static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
 305  290      mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
 306  291      int *resid);
 307  292  
 308  293  static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag);
 309  294  static void mptsas_free_active_slots(mptsas_t *mpt);
 310  295  static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
 311      -static int mptsas_start_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd);
 312  296  
 313  297  static void mptsas_restart_hba(mptsas_t *mpt);
      298 +static void mptsas_restart_waitq(mptsas_t *mpt);
 314  299  
 315  300  static void mptsas_deliver_doneq_thread(mptsas_t *mpt);
 316  301  static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
 317      -static inline void mptsas_doneq_add0(mptsas_t *mpt, mptsas_cmd_t *cmd);
 318  302  static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t);
 319  303  
 320  304  static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t);
 321  305  static void mptsas_doneq_empty(mptsas_t *mpt);
 322  306  static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg);
 323  307  
 324  308  static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt);
 325  309  static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
      310 +static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt);
      311 +static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
 326  312  
      313 +
 327  314  static void mptsas_start_watch_reset_delay();
 328  315  static void mptsas_setup_bus_reset_delay(mptsas_t *mpt);
 329  316  static void mptsas_watch_reset_delay(void *arg);
 330  317  static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
 331  318  
 332      -static int mptsas_outstanding_cmds_n(mptsas_t *mpt);
 333  319  /*
 334  320   * helper functions
 335  321   */
 336  322  static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
 337  323  
 338  324  static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
 339  325  static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
 340  326  static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
 341  327      int lun);
 342  328  static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
↓ open down ↓ 11 lines elided ↑ open up ↑
 354  340      uint64_t wwid);
 355  341  static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
 356  342      uint64_t wwid);
 357  343  
 358  344  static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
 359  345      uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
 360  346  
 361  347  static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
 362  348      uint16_t *handle, mptsas_target_t **pptgt);
 363  349  static void mptsas_update_phymask(mptsas_t *mpt);
 364      -static inline void mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd);
 365  350  
 366      -static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
 367      -    uint32_t *status, uint8_t cmd);
 368  351  static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
 369  352      mptsas_phymask_t *phymask);
 370      -static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
 371      -    mptsas_phymask_t phymask);
 372      -static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
 373      -    uint32_t slotstatus);
 374  353  
 375  354  
 376  355  /*
 377  356   * Enumeration / DR functions
 378  357   */
 379  358  static void mptsas_config_all(dev_info_t *pdip);
 380  359  static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
 381  360      dev_info_t **lundip);
 382  361  static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
 383  362      dev_info_t **lundip);
↓ open down ↓ 40 lines elided ↑ open up ↑
 424  403  static void mptsas_hash_init(mptsas_hash_table_t *hashtab);
 425  404  static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen);
 426  405  static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data);
 427  406  static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
 428  407      mptsas_phymask_t key2);
 429  408  static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
 430  409      mptsas_phymask_t key2);
 431  410  static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos);
 432  411  
 433  412  mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t,
 434      -    uint32_t, mptsas_phymask_t, uint8_t, mptsas_t *);
      413 +    uint32_t, mptsas_phymask_t, uint8_t);
 435  414  static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab,
 436  415      mptsas_smp_t *data);
 437  416  static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
 438  417      mptsas_phymask_t phymask);
 439  418  static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t);
 440  419  static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t);
 441  420  static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
 442  421      dev_info_t **smp_dip);
 443  422  
 444  423  /*
↓ open down ↓ 29 lines elided ↑ open up ↑
 474  453   * under this device that the paths to a physical device are created when
 475  454   * MPxIO is used.
 476  455   */
 477  456  extern dev_info_t       *scsi_vhci_dip;
 478  457  
 479  458  /*
 480  459   * Tunable timeout value for Inquiry VPD page 0x83
 481  460   * By default the value is 30 seconds.
 482  461   */
 483  462  int mptsas_inq83_retry_timeout = 30;
      463 +/*
      464 + * Maximum number of command timeouts (0 - 255) considered acceptable.
      465 + */
      466 +int mptsas_timeout_threshold = 2;
      467 +/*
      468 + * Timeouts exceeding threshold within this period are considered excessive.
      469 + */
      470 +int mptsas_timeout_interval = 30;
 484  471  
 485  472  /*
 486  473   * This is used to allocate memory for message frame storage, not for
 487  474   * data I/O DMA. All message frames must be stored in the first 4G of
 488  475   * physical memory.
 489  476   */
 490  477  ddi_dma_attr_t mptsas_dma_attrs = {
 491  478          DMA_ATTR_V0,    /* attribute layout version             */
 492  479          0x0ull,         /* address low - should be 0 (longlong) */
 493  480          0xffffffffull,  /* address high - 32-bit max range      */
↓ open down ↓ 696 lines elided ↑ open up ↑
1190 1177                          mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1191 1178                  }
1192 1179                  mutex_exit(&mpt->m_doneq_mutex);
1193 1180                  doneq_thread_create++;
1194 1181          }
1195 1182  
1196 1183          /* Initialize mutex used in interrupt handler */
1197 1184          mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1198 1185              DDI_INTR_PRI(mpt->m_intr_pri));
1199 1186          mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL);
1200      -        mutex_init(&mpt->m_intr_mutex, NULL, MUTEX_DRIVER,
     1187 +        mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1201 1188              DDI_INTR_PRI(mpt->m_intr_pri));
1202 1189          for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1203 1190                  mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex,
1204 1191                      NULL, MUTEX_DRIVER,
1205 1192                      DDI_INTR_PRI(mpt->m_intr_pri));
1206 1193          }
1207 1194  
1208 1195          cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1209 1196          cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1210 1197          cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
↓ open down ↓ 82 lines elided ↑ open up ↑
1293 1280                      "scsi_reset_delay of 0 is not recommended,"
1294 1281                      " resetting to SCSI_DEFAULT_RESET_DELAY\n");
1295 1282                  mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1296 1283          }
1297 1284  
1298 1285          /*
1299 1286           * Initialize the wait and done FIFO queue
1300 1287           */
1301 1288          mpt->m_donetail = &mpt->m_doneq;
1302 1289          mpt->m_waitqtail = &mpt->m_waitq;
     1290 +        mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
     1291 +        mpt->m_tx_draining = 0;
1303 1292  
1304 1293          /*
1305 1294           * ioc cmd queue initialize
1306 1295           */
1307 1296          mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1308 1297          mpt->m_dev_handle = 0xFFFF;
1309 1298  
1310 1299          MPTSAS_ENABLE_INTR(mpt);
1311 1300  
1312 1301          /*
↓ open down ↓ 139 lines elided ↑ open up ↑
1452 1441                          cv_destroy(&mpt->m_doneq_thread_cv);
1453 1442                          mutex_destroy(&mpt->m_doneq_mutex);
1454 1443                  }
1455 1444                  if (event_taskq_create) {
1456 1445                          ddi_taskq_destroy(mpt->m_event_taskq);
1457 1446                  }
1458 1447                  if (dr_taskq_create) {
1459 1448                          ddi_taskq_destroy(mpt->m_dr_taskq);
1460 1449                  }
1461 1450                  if (mutex_init_done) {
1462      -                        mutex_destroy(&mpt->m_intr_mutex);
     1451 +                        mutex_destroy(&mpt->m_tx_waitq_mutex);
1463 1452                          mutex_destroy(&mpt->m_passthru_mutex);
1464 1453                          mutex_destroy(&mpt->m_mutex);
1465 1454                          for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1466 1455                                  mutex_destroy(
1467 1456                                      &mpt->m_phy_info[i].smhba_info.phy_mutex);
1468 1457                          }
1469 1458                          cv_destroy(&mpt->m_cv);
1470 1459                          cv_destroy(&mpt->m_passthru_cv);
1471 1460                          cv_destroy(&mpt->m_fw_cv);
1472 1461                          cv_destroy(&mpt->m_config_cv);
↓ open down ↓ 397 lines elided ↑ open up ↑
1870 1859  
1871 1860          /* Lower the power informing PM Framework */
1872 1861          if (mpt->m_options & MPTSAS_OPT_PM) {
1873 1862                  if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
1874 1863                          mptsas_log(mpt, CE_WARN,
1875 1864                              "!mptsas%d: Lower power request failed "
1876 1865                              "during detach, ignoring.",
1877 1866                              mpt->m_instance);
1878 1867          }
1879 1868  
1880      -        mutex_destroy(&mpt->m_intr_mutex);
     1869 +        mutex_destroy(&mpt->m_tx_waitq_mutex);
1881 1870          mutex_destroy(&mpt->m_passthru_mutex);
1882 1871          mutex_destroy(&mpt->m_mutex);
1883 1872          for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
1884 1873                  mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex);
1885 1874          }
1886 1875          cv_destroy(&mpt->m_cv);
1887 1876          cv_destroy(&mpt->m_passthru_cv);
1888 1877          cv_destroy(&mpt->m_fw_cv);
1889 1878          cv_destroy(&mpt->m_config_cv);
1890 1879          cv_destroy(&mpt->m_fw_diag_cv);
↓ open down ↓ 343 lines elided ↑ open up ↑
2234 2223                  if ((ioc_status & MPI2_IOC_STATE_MASK) !=
2235 2224                      MPI2_IOC_STATE_OPERATIONAL) {
2236 2225                          mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
2237 2226                          if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
2238 2227                                  mptsas_log(mpt, CE_WARN,
2239 2228                                      "mptsas_power: hard reset failed");
2240 2229                                  mutex_exit(&mpt->m_mutex);
2241 2230                                  return (DDI_FAILURE);
2242 2231                          }
2243 2232                  }
2244      -                mutex_enter(&mpt->m_intr_mutex);
2245 2233                  mpt->m_power_level = PM_LEVEL_D0;
2246      -                mutex_exit(&mpt->m_intr_mutex);
2247 2234                  break;
2248 2235          case PM_LEVEL_D3:
2249 2236                  NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2250 2237                  MPTSAS_POWER_OFF(mpt);
2251 2238                  break;
2252 2239          default:
2253 2240                  mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2254 2241                      mpt->m_instance, level);
2255 2242                  rval = DDI_FAILURE;
2256 2243                  break;
↓ open down ↓ 370 lines elided ↑ open up ↑
2627 2614           * Clear the reply post queue memory.
2628 2615           */
2629 2616          bzero(mpt->m_post_queue, mem_size);
2630 2617  
2631 2618          return (DDI_SUCCESS);
2632 2619  }
2633 2620  
2634 2621  static void
2635 2622  mptsas_alloc_reply_args(mptsas_t *mpt)
2636 2623  {
2637      -        if (mpt->m_replyh_args != NULL) {
2638      -                kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
2639      -                    * mpt->m_max_replies);
2640      -                mpt->m_replyh_args = NULL;
     2624 +        if (mpt->m_replyh_args == NULL) {
     2625 +                mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
     2626 +                    mpt->m_max_replies, KM_SLEEP);
2641 2627          }
2642      -        mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
2643      -            mpt->m_max_replies, KM_SLEEP);
2644 2628  }
2645 2629  
2646 2630  static int
2647 2631  mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2648 2632  {
2649 2633          mptsas_cache_frames_t   *frames = NULL;
2650 2634          if (cmd->cmd_extra_frames == NULL) {
2651 2635                  frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2652 2636                  if (frames == NULL) {
2653 2637                          return (DDI_FAILURE);
↓ open down ↓ 338 lines elided ↑ open up ↑
2992 2976           * Remember that access to shared resources, including the mptsas_t
2993 2977           * data structure and the HBA hardware registers, must be protected
2994 2978           * with mutexes, here and everywhere.
2995 2979           *
2996 2980           * Also remember that at interrupt time, you'll get an argument
2997 2981           * to the interrupt handler which is a pointer to your mptsas_t
2998 2982           * structure; you'll have to remember which commands are outstanding
2999 2983           * and which scsi_pkt is the currently-running command so the
3000 2984           * interrupt handler can refer to the pkt to set completion
3001 2985           * status, call the target driver back through pkt_comp, etc.
     2986 +         *
     2987 +         * If the instance lock is held by other thread, don't spin to wait
     2988 +         * for it. Instead, queue the cmd and next time when the instance lock
     2989 +         * is not held, accept all the queued cmd. A extra tx_waitq is
     2990 +         * introduced to protect the queue.
     2991 +         *
     2992 +         * The polled cmd will not be queud and accepted as usual.
     2993 +         *
     2994 +         * Under the tx_waitq mutex, record whether a thread is draining
     2995 +         * the tx_waitq.  An IO requesting thread that finds the instance
     2996 +         * mutex contended appends to the tx_waitq and while holding the
     2997 +         * tx_wait mutex, if the draining flag is not set, sets it and then
     2998 +         * proceeds to spin for the instance mutex. This scheme ensures that
     2999 +         * the last cmd in a burst be processed.
     3000 +         *
     3001 +         * we enable this feature only when the helper threads are enabled,
     3002 +         * at which we think the loads are heavy.
     3003 +         *
     3004 +         * per instance mutex m_tx_waitq_mutex is introduced to protect the
     3005 +         * m_tx_waitqtail, m_tx_waitq, m_tx_draining.
3002 3006           */
3003 3007  
3004      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
     3008 +        if (mpt->m_doneq_thread_n) {
     3009 +                if (mutex_tryenter(&mpt->m_mutex) != 0) {
     3010 +                        rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
     3011 +                        mutex_exit(&mpt->m_mutex);
     3012 +                } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
     3013 +                        mutex_enter(&mpt->m_mutex);
     3014 +                        rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
     3015 +                        mutex_exit(&mpt->m_mutex);
     3016 +                } else {
     3017 +                        mutex_enter(&mpt->m_tx_waitq_mutex);
     3018 +                        /*
     3019 +                         * ptgt->m_dr_flag is protected by m_mutex or
     3020 +                         * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex
     3021 +                         * is acquired.
     3022 +                         */
     3023 +                        if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
     3024 +                                if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
     3025 +                                        /*
     3026 +                                         * The command should be allowed to
     3027 +                                         * retry by returning TRAN_BUSY to
     3028 +                                         * to stall the I/O's which come from
     3029 +                                         * scsi_vhci since the device/path is
     3030 +                                         * in unstable state now.
     3031 +                                         */
     3032 +                                        mutex_exit(&mpt->m_tx_waitq_mutex);
     3033 +                                        return (TRAN_BUSY);
     3034 +                                } else {
     3035 +                                        /*
     3036 +                                         * The device is offline, just fail the
     3037 +                                         * command by returning
     3038 +                                         * TRAN_FATAL_ERROR.
     3039 +                                         */
     3040 +                                        mutex_exit(&mpt->m_tx_waitq_mutex);
     3041 +                                        return (TRAN_FATAL_ERROR);
     3042 +                                }
     3043 +                        }
     3044 +                        if (mpt->m_tx_draining) {
     3045 +                                cmd->cmd_flags |= CFLAG_TXQ;
     3046 +                                *mpt->m_tx_waitqtail = cmd;
     3047 +                                mpt->m_tx_waitqtail = &cmd->cmd_linkp;
     3048 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
     3049 +                        } else { /* drain the queue */
     3050 +                                mpt->m_tx_draining = 1;
     3051 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
     3052 +                                mutex_enter(&mpt->m_mutex);
     3053 +                                rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
     3054 +                                mutex_exit(&mpt->m_mutex);
     3055 +                        }
     3056 +                }
     3057 +        } else {
     3058 +                mutex_enter(&mpt->m_mutex);
     3059 +                /*
     3060 +                 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
     3061 +                 * in this case, m_mutex is acquired.
     3062 +                 */
     3063 +                if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
     3064 +                        if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
     3065 +                                /*
     3066 +                                 * commands should be allowed to retry by
     3067 +                                 * returning TRAN_BUSY to stall the I/O's
     3068 +                                 * which come from scsi_vhci since the device/
     3069 +                                 * path is in unstable state now.
     3070 +                                 */
     3071 +                                mutex_exit(&mpt->m_mutex);
     3072 +                                return (TRAN_BUSY);
     3073 +                        } else {
     3074 +                                /*
     3075 +                                 * The device is offline, just fail the
     3076 +                                 * command by returning TRAN_FATAL_ERROR.
     3077 +                                 */
     3078 +                                mutex_exit(&mpt->m_mutex);
     3079 +                                return (TRAN_FATAL_ERROR);
     3080 +                        }
     3081 +                }
     3082 +                rval = mptsas_accept_pkt(mpt, cmd);
     3083 +                mutex_exit(&mpt->m_mutex);
     3084 +        }
     3085 +
     3086 +        return (rval);
     3087 +}
     3088 +
     3089 +/*
     3090 + * Accept all the queued cmds(if any) before accept the current one.
     3091 + */
     3092 +static int
     3093 +mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
     3094 +{
     3095 +        int rval;
     3096 +        mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
     3097 +
     3098 +        ASSERT(mutex_owned(&mpt->m_mutex));
     3099 +        /*
     3100 +         * The call to mptsas_accept_tx_waitq() must always be performed
     3101 +         * because that is where mpt->m_tx_draining is cleared.
     3102 +         */
     3103 +        mutex_enter(&mpt->m_tx_waitq_mutex);
     3104 +        mptsas_accept_tx_waitq(mpt);
     3105 +        mutex_exit(&mpt->m_tx_waitq_mutex);
     3106 +        /*
     3107 +         * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
     3108 +         * in this case, m_mutex is acquired.
     3109 +         */
3005 3110          if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3006 3111                  if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3007 3112                          /*
3008      -                         * commands should be allowed to retry by
3009      -                         * returning TRAN_BUSY to stall the I/O's
3010      -                         * which come from scsi_vhci since the device/
3011      -                         * path is in unstable state now.
     3113 +                         * The command should be allowed to retry by returning
     3114 +                         * TRAN_BUSY to stall the I/O's which come from
     3115 +                         * scsi_vhci since the device/path is in unstable state
     3116 +                         * now.
3012 3117                           */
3013      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
3014 3118                          return (TRAN_BUSY);
3015 3119                  } else {
3016 3120                          /*
3017      -                         * The device is offline, just fail the
3018      -                         * command by returning TRAN_FATAL_ERROR.
     3121 +                         * The device is offline, just fail the command by
     3122 +                         * return TRAN_FATAL_ERROR.
3019 3123                           */
3020      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
3021 3124                          return (TRAN_FATAL_ERROR);
3022 3125                  }
3023 3126          }
3024      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
3025 3127          rval = mptsas_accept_pkt(mpt, cmd);
3026 3128  
3027 3129          return (rval);
3028 3130  }
3029 3131  
3030 3132  static int
3031 3133  mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3032 3134  {
3033 3135          int             rval = TRAN_ACCEPT;
3034 3136          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3035 3137  
3036 3138          NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3037 3139  
     3140 +        ASSERT(mutex_owned(&mpt->m_mutex));
     3141 +
3038 3142          if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
3039 3143                  rval = mptsas_prepare_pkt(cmd);
3040 3144                  if (rval != TRAN_ACCEPT) {
3041 3145                          cmd->cmd_flags &= ~CFLAG_TRANFLAG;
3042 3146                          return (rval);
3043 3147                  }
3044 3148          }
3045 3149  
3046 3150          /*
3047 3151           * reset the throttle if we were draining
3048 3152           */
3049      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
3050 3153          if ((ptgt->m_t_ncmds == 0) &&
3051 3154              (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3052 3155                  NDBG23(("reset throttle"));
3053 3156                  ASSERT(ptgt->m_reset_delay == 0);
3054 3157                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3055 3158          }
3056 3159  
3057 3160          /*
     3161 +         * If HBA is being reset, the DevHandles are being re-initialized,
     3162 +         * which means that they could be invalid even if the target is still
     3163 +         * attached.  Check if being reset and if DevHandle is being
     3164 +         * re-initialized.  If this is the case, return BUSY so the I/O can be
     3165 +         * retried later.
     3166 +         */
     3167 +        if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) {
     3168 +                mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
     3169 +                if (cmd->cmd_flags & CFLAG_TXQ) {
     3170 +                        mptsas_doneq_add(mpt, cmd);
     3171 +                        mptsas_doneq_empty(mpt);
     3172 +                        return (rval);
     3173 +                } else {
     3174 +                        return (TRAN_BUSY);
     3175 +                }
     3176 +        }
     3177 +
     3178 +        /*
3058 3179           * If device handle has already been invalidated, just
3059 3180           * fail the command. In theory, command from scsi_vhci
3060 3181           * client is impossible send down command with invalid
3061 3182           * devhdl since devhdl is set after path offline, target
3062 3183           * driver is not suppose to select a offlined path.
3063 3184           */
3064 3185          if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3065 3186                  NDBG20(("rejecting command, it might because invalid devhdl "
3066 3187                      "request."));
3067      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
3068      -                mutex_enter(&mpt->m_mutex);
3069      -                /*
3070      -                 * If HBA is being reset, the DevHandles are being
3071      -                 * re-initialized, which means that they could be invalid
3072      -                 * even if the target is still attached. Check if being reset
3073      -                 * and if DevHandle is being re-initialized. If this is the
3074      -                 * case, return BUSY so the I/O can be retried later.
3075      -                 */
3076      -                if (mpt->m_in_reset) {
3077      -                        mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
3078      -                            STAT_BUS_RESET);
3079      -                        if (cmd->cmd_flags & CFLAG_TXQ) {
3080      -                                mptsas_doneq_add(mpt, cmd);
3081      -                                mptsas_doneq_empty(mpt);
3082      -                                mutex_exit(&mpt->m_mutex);
3083      -                                return (rval);
3084      -                        } else {
3085      -                                mutex_exit(&mpt->m_mutex);
3086      -                                return (TRAN_BUSY);
3087      -                        }
3088      -                }
3089 3188                  mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3090 3189                  if (cmd->cmd_flags & CFLAG_TXQ) {
3091 3190                          mptsas_doneq_add(mpt, cmd);
3092 3191                          mptsas_doneq_empty(mpt);
3093      -                        mutex_exit(&mpt->m_mutex);
3094 3192                          return (rval);
3095 3193                  } else {
3096      -                        mutex_exit(&mpt->m_mutex);
3097 3194                          return (TRAN_FATAL_ERROR);
3098 3195                  }
3099 3196          }
3100      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
3101 3197          /*
3102 3198           * The first case is the normal case.  mpt gets a command from the
3103 3199           * target driver and starts it.
3104 3200           * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3105 3201           * commands is m_max_requests - 2.
3106 3202           */
3107      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
3108      -        if ((ptgt->m_t_throttle > HOLD_THROTTLE) &&
     3203 +        if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
     3204 +            (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3109 3205              (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3110 3206              (ptgt->m_reset_delay == 0) &&
3111 3207              (ptgt->m_t_nwait == 0) &&
3112 3208              ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) {
3113      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
3114 3209                  if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3115      -                        (void) mptsas_start_cmd0(mpt, cmd);
     3210 +                        (void) mptsas_start_cmd(mpt, cmd);
3116 3211                  } else {
3117      -                        mutex_enter(&mpt->m_mutex);
3118 3212                          mptsas_waitq_add(mpt, cmd);
3119      -                        mutex_exit(&mpt->m_mutex);
3120 3213                  }
3121 3214          } else {
3122 3215                  /*
3123 3216                   * Add this pkt to the work queue
3124 3217                   */
3125      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
3126      -                mutex_enter(&mpt->m_mutex);
3127 3218                  mptsas_waitq_add(mpt, cmd);
3128 3219  
3129 3220                  if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3130 3221                          (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3131 3222  
3132 3223                          /*
3133 3224                           * Only flush the doneq if this is not a TM
3134 3225                           * cmd.  For TM cmds the flushing of the
3135 3226                           * doneq will be done in those routines.
3136 3227                           */
3137 3228                          if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3138 3229                                  mptsas_doneq_empty(mpt);
3139 3230                          }
3140 3231                  }
3141      -                mutex_exit(&mpt->m_mutex);
3142 3232          }
3143 3233          return (rval);
3144 3234  }
3145 3235  
3146 3236  int
3147 3237  mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3148 3238  {
3149 3239          mptsas_slots_t  *slots;
3150 3240          int             slot;
3151 3241          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3152      -        mptsas_slot_free_e_t    *pe;
3153      -        int             qn, qn_first;
3154 3242  
     3243 +        ASSERT(mutex_owned(&mpt->m_mutex));
3155 3244          slots = mpt->m_active;
3156 3245  
3157 3246          /*
3158 3247           * Account for reserved TM request slot and reserved SMID of 0.
3159 3248           */
3160 3249          ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2));
3161 3250  
3162      -        qn = qn_first = CPU->cpu_seqid & (mpt->m_slot_freeq_pair_n - 1);
     3251 +        /*
     3252 +         * m_tags is equivalent to the SMID when sending requests.  Since the
     3253 +         * SMID cannot be 0, start out at one if rolling over past the size
     3254 +         * of the request queue depth.  Also, don't use the last SMID, which is
     3255 +         * reserved for TM requests.
     3256 +         */
     3257 +        slot = (slots->m_tags)++;
     3258 +        if (slots->m_tags > slots->m_n_slots) {
     3259 +                slots->m_tags = 1;
     3260 +        }
3163 3261  
3164      -qpair_retry:
3165      -        ASSERT(qn < mpt->m_slot_freeq_pair_n);
3166      -        mutex_enter(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_mutex);
3167      -        pe = list_head(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.
3168      -            s.m_fq_list);
3169      -        if (!pe) { /* switch the allocq and releq */
3170      -                mutex_enter(&mpt->m_slot_freeq_pairp[qn].m_slot_releq.
3171      -                    s.m_fq_mutex);
3172      -                if (mpt->m_slot_freeq_pairp[qn].m_slot_releq.s.m_fq_n) {
3173      -                        mpt->m_slot_freeq_pairp[qn].
3174      -                            m_slot_allocq.s.m_fq_n =
3175      -                            mpt->m_slot_freeq_pairp[qn].
3176      -                            m_slot_releq.s.m_fq_n;
3177      -                        mpt->m_slot_freeq_pairp[qn].
3178      -                            m_slot_allocq.s.m_fq_list.list_head.list_next =
3179      -                            mpt->m_slot_freeq_pairp[qn].
3180      -                            m_slot_releq.s.m_fq_list.list_head.list_next;
3181      -                        mpt->m_slot_freeq_pairp[qn].
3182      -                            m_slot_allocq.s.m_fq_list.list_head.list_prev =
3183      -                            mpt->m_slot_freeq_pairp[qn].
3184      -                            m_slot_releq.s.m_fq_list.list_head.list_prev;
3185      -                        mpt->m_slot_freeq_pairp[qn].
3186      -                            m_slot_releq.s.m_fq_list.list_head.list_prev->
3187      -                            list_next =
3188      -                            &mpt->m_slot_freeq_pairp[qn].
3189      -                            m_slot_allocq.s.m_fq_list.list_head;
3190      -                        mpt->m_slot_freeq_pairp[qn].
3191      -                            m_slot_releq.s.m_fq_list.list_head.list_next->
3192      -                            list_prev =
3193      -                            &mpt->m_slot_freeq_pairp[qn].
3194      -                            m_slot_allocq.s.m_fq_list.list_head;
     3262 +alloc_tag:
     3263 +        /* Validate tag, should never fail. */
     3264 +        if (slots->m_slot[slot] == NULL) {
     3265 +                /*
     3266 +                 * Make sure SMID is not using reserved value of 0
     3267 +                 * and the TM request slot.
     3268 +                 */
     3269 +                ASSERT((slot > 0) && (slot <= slots->m_n_slots));
     3270 +                cmd->cmd_slot = slot;
     3271 +                slots->m_slot[slot] = cmd;
     3272 +                mpt->m_ncmds++;
3195 3273  
3196      -                        mpt->m_slot_freeq_pairp[qn].
3197      -                            m_slot_releq.s.m_fq_list.list_head.list_next =
3198      -                            mpt->m_slot_freeq_pairp[qn].
3199      -                            m_slot_releq.s.m_fq_list.list_head.list_prev =
3200      -                            &mpt->m_slot_freeq_pairp[qn].
3201      -                            m_slot_releq.s.m_fq_list.list_head;
3202      -                        mpt->m_slot_freeq_pairp[qn].
3203      -                            m_slot_releq.s.m_fq_n = 0;
3204      -                } else {
3205      -                        mutex_exit(&mpt->m_slot_freeq_pairp[qn].
3206      -                            m_slot_releq.s.m_fq_mutex);
3207      -                        mutex_exit(&mpt->m_slot_freeq_pairp[qn].
3208      -                            m_slot_allocq.s.m_fq_mutex);
3209      -                        qn = (qn + 1) & (mpt->m_slot_freeq_pair_n - 1);
3210      -                        if (qn == qn_first)
3211      -                                return (FALSE);
3212      -                        else
3213      -                                goto qpair_retry;
     3274 +                /*
     3275 +                 * only increment per target ncmds if this is not a
     3276 +                 * command that has no target associated with it (i.e. a
     3277 +                 * event acknoledgment)
     3278 +                 */
     3279 +                if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
     3280 +                        ptgt->m_t_ncmds++;
3214 3281                  }
3215      -                mutex_exit(&mpt->m_slot_freeq_pairp[qn].
3216      -                    m_slot_releq.s.m_fq_mutex);
3217      -                pe = list_head(&mpt->m_slot_freeq_pairp[qn].
3218      -                    m_slot_allocq.s.m_fq_list);
3219      -                ASSERT(pe);
3220      -        }
3221      -        list_remove(&mpt->m_slot_freeq_pairp[qn].
3222      -            m_slot_allocq.s.m_fq_list, pe);
3223      -        slot = pe->slot;
3224      -        /*
3225      -         * Make sure SMID is not using reserved value of 0
3226      -         * and the TM request slot.
3227      -         */
3228      -        ASSERT((slot > 0) && (slot <= slots->m_n_slots) &&
3229      -            mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n > 0);
3230      -        cmd->cmd_slot = slot;
3231      -        mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n--;
3232      -        ASSERT(mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n >= 0);
     3282 +                cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
3233 3283  
3234      -        mutex_exit(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_mutex);
3235      -        /*
3236      -         * only increment per target ncmds if this is not a
3237      -         * command that has no target associated with it (i.e. a
3238      -         * event acknoledgment)
3239      -         */
3240      -        if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3241      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
3242      -                ptgt->m_t_ncmds++;
3243      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
3244      -        }
3245      -        cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
     3284 +                /*
     3285 +                 * If initial timout is less than or equal to one tick, bump
     3286 +                 * the timeout by a tick so that command doesn't timeout before
     3287 +                 * its allotted time.
     3288 +                 */
     3289 +                if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
     3290 +                        cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
     3291 +                }
     3292 +                return (TRUE);
     3293 +        } else {
     3294 +                int i;
3246 3295  
3247      -        /*
3248      -         * If initial timout is less than or equal to one tick, bump
3249      -         * the timeout by a tick so that command doesn't timeout before
3250      -         * its allotted time.
3251      -         */
3252      -        if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
3253      -                cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
     3296 +                /*
     3297 +                 * If slot in use, scan until a free one is found. Don't use 0
     3298 +                 * or final slot, which is reserved for TM requests.
     3299 +                 */
     3300 +                for (i = 0; i < slots->m_n_slots; i++) {
     3301 +                        slot = slots->m_tags;
     3302 +                        if (++(slots->m_tags) > slots->m_n_slots) {
     3303 +                                slots->m_tags = 1;
     3304 +                        }
     3305 +                        if (slots->m_slot[slot] == NULL) {
     3306 +                                NDBG22(("found free slot %d", slot));
     3307 +                                goto alloc_tag;
     3308 +                        }
     3309 +                }
3254 3310          }
3255      -        return (TRUE);
     3311 +        return (FALSE);
3256 3312  }
3257 3313  
3258 3314  /*
3259 3315   * prepare the pkt:
3260 3316   * the pkt may have been resubmitted or just reused so
3261 3317   * initialize some fields and do some checks.
3262 3318   */
3263 3319  static int
3264 3320  mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3265 3321  {
↓ open down ↓ 47 lines elided ↑ open up ↑
3313 3369   *      - allocate DMA resources to an already-allocated pkt
3314 3370   */
3315 3371  static struct scsi_pkt *
3316 3372  mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3317 3373      struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3318 3374      int (*callback)(), caddr_t arg)
3319 3375  {
3320 3376          mptsas_cmd_t            *cmd, *new_cmd;
3321 3377          mptsas_t                *mpt = ADDR2MPT(ap);
3322 3378          int                     failure = 1;
3323      -#ifndef __sparc
3324 3379          uint_t                  oldcookiec;
3325      -#endif  /* __sparc */
3326 3380          mptsas_target_t         *ptgt = NULL;
3327 3381          int                     rval;
3328 3382          mptsas_tgt_private_t    *tgt_private;
3329 3383          int                     kf;
3330 3384  
3331 3385          kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3332 3386  
3333 3387          tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3334 3388              tran_tgt_private;
3335 3389          ASSERT(tgt_private != NULL);
↓ open down ↓ 17 lines elided ↑ open up ↑
3353 3407              cmdlen, statuslen, tgtlen, flags));
3354 3408  
3355 3409          /*
3356 3410           * Allocate the new packet.
3357 3411           */
3358 3412          if (pkt == NULL) {
3359 3413                  ddi_dma_handle_t        save_dma_handle;
3360 3414                  ddi_dma_handle_t        save_arq_dma_handle;
3361 3415                  struct buf              *save_arq_bp;
3362 3416                  ddi_dma_cookie_t        save_arqcookie;
3363      -#ifdef  __sparc
3364      -                mptti_t                 *save_sg;
3365      -#endif  /* __sparc */
3366 3417  
3367 3418                  cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3368 3419  
3369 3420                  if (cmd) {
3370 3421                          save_dma_handle = cmd->cmd_dmahandle;
3371 3422                          save_arq_dma_handle = cmd->cmd_arqhandle;
3372 3423                          save_arq_bp = cmd->cmd_arq_buf;
3373 3424                          save_arqcookie = cmd->cmd_arqcookie;
3374      -#ifdef  __sparc
3375      -                        save_sg = cmd->cmd_sg;
3376      -#endif  /* __sparc */
3377 3425                          bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3378 3426                          cmd->cmd_dmahandle = save_dma_handle;
3379 3427                          cmd->cmd_arqhandle = save_arq_dma_handle;
3380 3428                          cmd->cmd_arq_buf = save_arq_bp;
3381 3429                          cmd->cmd_arqcookie = save_arqcookie;
3382      -#ifdef  __sparc
3383      -                        cmd->cmd_sg = save_sg;
3384      -#endif  /* __sparc */
     3430 +
3385 3431                          pkt = (void *)((uchar_t *)cmd +
3386 3432                              sizeof (struct mptsas_cmd));
3387 3433                          pkt->pkt_ha_private = (opaque_t)cmd;
3388 3434                          pkt->pkt_address = *ap;
3389 3435                          pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3390 3436                          pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3391 3437                          pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3392 3438                          cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3393 3439                          cmd->cmd_cdblen = (uchar_t)cmdlen;
3394 3440                          cmd->cmd_scblen = statuslen;
↓ open down ↓ 22 lines elided ↑ open up ↑
3417 3463                          }
3418 3464                  }
3419 3465                  new_cmd = cmd;
3420 3466  
3421 3467          } else {
3422 3468                  cmd = PKT2CMD(pkt);
3423 3469                  new_cmd = NULL;
3424 3470          }
3425 3471  
3426 3472  
3427      -#ifndef __sparc
3428 3473          /* grab cmd->cmd_cookiec here as oldcookiec */
3429 3474  
3430 3475          oldcookiec = cmd->cmd_cookiec;
3431      -#endif  /* __sparc */
3432 3476  
3433 3477          /*
3434 3478           * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3435 3479           * greater than 0 and we'll need to grab the next dma window
3436 3480           */
3437 3481          /*
3438 3482           * SLM-not doing extra command frame right now; may add later
3439 3483           */
3440 3484  
3441 3485          if (cmd->cmd_nwin > 0) {
↓ open down ↓ 129 lines elided ↑ open up ↑
3571 3615                   * Use the loop below to store physical addresses of
3572 3616                   * DMA segments, from the DMA cookies, into your HBA's
3573 3617                   * scatter-gather list.
3574 3618                   * We need to ensure we have enough kmem alloc'd
3575 3619                   * for the sg entries since we are no longer using an
3576 3620                   * array inside mptsas_cmd_t.
3577 3621                   *
3578 3622                   * We check cmd->cmd_cookiec against oldcookiec so
3579 3623                   * the scatter-gather list is correctly allocated
3580 3624                   */
3581      -#ifndef __sparc
     3625 +
3582 3626                  if (oldcookiec != cmd->cmd_cookiec) {
3583 3627                          if (cmd->cmd_sg != (mptti_t *)NULL) {
3584 3628                                  kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
3585 3629                                      oldcookiec);
3586 3630                                  cmd->cmd_sg = NULL;
3587 3631                          }
3588 3632                  }
3589 3633  
3590 3634                  if (cmd->cmd_sg == (mptti_t *)NULL) {
3591 3635                          cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
↓ open down ↓ 8 lines elided ↑ open up ↑
3600 3644                   * the same way as the rest of this routine
3601 3645                   */
3602 3646  
3603 3647                                  bioerror(bp, ENOMEM);
3604 3648                                  if (new_cmd) {
3605 3649                                          mptsas_scsi_destroy_pkt(ap, pkt);
3606 3650                                  }
3607 3651                                  return ((struct scsi_pkt *)NULL);
3608 3652                          }
3609 3653                  }
3610      -#endif  /* __sparc */
     3654 +
3611 3655                  dmap = cmd->cmd_sg;
3612 3656  
3613 3657                  ASSERT(cmd->cmd_cookie.dmac_size != 0);
3614 3658  
3615 3659                  /*
3616 3660                   * store the first segment into the S/G list
3617 3661                   */
3618 3662                  dmap->count = cmd->cmd_cookie.dmac_size;
3619 3663                  dmap->addr.address64.Low = (uint32_t)
3620 3664                      (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
↓ open down ↓ 59 lines elided ↑ open up ↑
3680 3724          mptsas_cmd_t    *cmd = PKT2CMD(pkt);
3681 3725          mptsas_t        *mpt = ADDR2MPT(ap);
3682 3726  
3683 3727          NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
3684 3728              ap->a_target, (void *)pkt));
3685 3729  
3686 3730          if (cmd->cmd_flags & CFLAG_DMAVALID) {
3687 3731                  (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
3688 3732                  cmd->cmd_flags &= ~CFLAG_DMAVALID;
3689 3733          }
3690      -#ifndef __sparc
     3734 +
3691 3735          if (cmd->cmd_sg) {
3692 3736                  kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
3693 3737                  cmd->cmd_sg = NULL;
3694 3738          }
3695      -#endif  /* __sparc */
     3739 +
3696 3740          mptsas_free_extra_sgl_frame(mpt, cmd);
3697 3741  
3698 3742          if ((cmd->cmd_flags &
3699 3743              (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
3700 3744              CFLAG_SCBEXTERN)) == 0) {
3701 3745                  cmd->cmd_flags = CFLAG_FREE;
3702 3746                  kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
3703 3747          } else {
3704 3748                  mptsas_pkt_destroy_extern(mpt, cmd);
3705 3749          }
↓ open down ↓ 57 lines elided ↑ open up ↑
3763 3807              cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3764 3808              callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) {
3765 3809                  ddi_dma_free_handle(&cmd->cmd_dmahandle);
3766 3810                  ddi_dma_free_handle(&cmd->cmd_arqhandle);
3767 3811                  scsi_free_consistent_buf(cmd->cmd_arq_buf);
3768 3812                  cmd->cmd_dmahandle = NULL;
3769 3813                  cmd->cmd_arqhandle = NULL;
3770 3814                  cmd->cmd_arq_buf = NULL;
3771 3815                  return (-1);
3772 3816          }
3773      -        /*
3774      -         * In sparc, the sgl length in most of the cases would be 1, so we
3775      -         * pre-allocate it in cache. On x86, the max number would be 256,
3776      -         * pre-allocate a maximum would waste a lot of memory especially
3777      -         * when many cmds are put onto waitq.
3778      -         */
3779      -#ifdef  __sparc
3780      -        cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
3781      -            MPTSAS_MAX_CMD_SEGS), KM_SLEEP);
3782      -#endif  /* __sparc */
3783 3817  
3784 3818          return (0);
3785 3819  }
3786 3820  
3787 3821  static void
3788 3822  mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
3789 3823  {
3790 3824  #ifndef __lock_lint
3791 3825          _NOTE(ARGUNUSED(cdrarg))
3792 3826  #endif
↓ open down ↓ 7 lines elided ↑ open up ↑
3800 3834                  cmd->cmd_arqhandle = NULL;
3801 3835          }
3802 3836          if (cmd->cmd_arq_buf) {
3803 3837                  scsi_free_consistent_buf(cmd->cmd_arq_buf);
3804 3838                  cmd->cmd_arq_buf = NULL;
3805 3839          }
3806 3840          if (cmd->cmd_dmahandle) {
3807 3841                  ddi_dma_free_handle(&cmd->cmd_dmahandle);
3808 3842                  cmd->cmd_dmahandle = NULL;
3809 3843          }
3810      -#ifdef  __sparc
3811      -        if (cmd->cmd_sg) {
3812      -                kmem_free(cmd->cmd_sg, sizeof (mptti_t)* MPTSAS_MAX_CMD_SEGS);
3813      -                cmd->cmd_sg = NULL;
3814      -        }
3815      -#endif  /* __sparc */
3816 3844  }
3817 3845  
3818 3846  static int
3819 3847  mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
3820 3848  {
3821 3849          mptsas_cache_frames_t   *p = buf;
3822 3850          mptsas_t                *mpt = cdrarg;
3823 3851          ddi_dma_attr_t          frame_dma_attr;
3824 3852          size_t                  mem_size, alloc_len;
3825 3853          ddi_dma_cookie_t        cookie;
↓ open down ↓ 641 lines elided ↑ open up ↑
4467 4495   * Utility routine.  Poll for status of a command sent to HBA
4468 4496   * without interrupts (a FLAG_NOINTR command).
4469 4497   */
4470 4498  int
4471 4499  mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4472 4500  {
4473 4501          int     rval = TRUE;
4474 4502  
4475 4503          NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4476 4504  
4477      -        /*
4478      -         * In order to avoid using m_mutex in ISR(a new separate mutex
4479      -         * m_intr_mutex is introduced) and keep the same lock logic,
4480      -         * the m_intr_mutex should be used to protect the getting and
4481      -         * setting of the ReplyDescriptorIndex.
4482      -         *
4483      -         * Since the m_intr_mutex would be released during processing the poll
4484      -         * cmd, so we should set the poll flag earlier here to make sure the
4485      -         * polled cmd be handled in this thread/context. A side effect is other
4486      -         * cmds during the period between the flag set and reset are also
4487      -         * handled in this thread and not the ISR. Since the poll cmd is not
4488      -         * so common, so the performance degradation in this case is not a big
4489      -         * issue.
4490      -         */
4491      -        mutex_enter(&mpt->m_intr_mutex);
4492      -        mpt->m_polled_intr = 1;
4493      -        mutex_exit(&mpt->m_intr_mutex);
4494      -
4495 4505          if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4496 4506                  mptsas_restart_hba(mpt);
4497 4507          }
4498 4508  
4499 4509          /*
4500 4510           * Wait, using drv_usecwait(), long enough for the command to
4501 4511           * reasonably return from the target if the target isn't
4502 4512           * "dead".  A polled command may well be sent from scsi_poll, and
4503 4513           * there are retries built in to scsi_poll if the transport
4504 4514           * accepted the packet (TRAN_ACCEPT).  scsi_poll waits 1 second
↓ open down ↓ 6 lines elided ↑ open up ↑
4511 4521           * cmd never gets started but we are still receiving interrupts
4512 4522           */
4513 4523          while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
4514 4524                  if (mptsas_wait_intr(mpt, polltime) == FALSE) {
4515 4525                          NDBG5(("mptsas_poll: command incomplete"));
4516 4526                          rval = FALSE;
4517 4527                          break;
4518 4528                  }
4519 4529          }
4520 4530  
4521      -        mutex_enter(&mpt->m_intr_mutex);
4522      -        mpt->m_polled_intr = 0;
4523      -        mutex_exit(&mpt->m_intr_mutex);
4524      -
4525 4531          if (rval == FALSE) {
4526 4532  
4527 4533                  /*
4528 4534                   * this isn't supposed to happen, the hba must be wedged
4529 4535                   * Mark this cmd as a timeout.
4530 4536                   */
4531 4537                  mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
4532 4538                      (STAT_TIMEOUT|STAT_ABORTED));
4533 4539  
4534 4540                  if (poll_cmd->cmd_queued == FALSE) {
↓ open down ↓ 16 lines elided ↑ open up ↑
4551 4557  }
4552 4558  
4553 4559  /*
4554 4560   * Used for polling cmds and TM function
4555 4561   */
4556 4562  static int
4557 4563  mptsas_wait_intr(mptsas_t *mpt, int polltime)
4558 4564  {
4559 4565          int                             cnt;
4560 4566          pMpi2ReplyDescriptorsUnion_t    reply_desc_union;
4561      -        Mpi2ReplyDescriptorsUnion_t     reply_desc_union_v;
4562 4567          uint32_t                        int_mask;
4563      -        uint8_t reply_type;
4564 4568  
4565 4569          NDBG5(("mptsas_wait_intr"));
4566 4570  
     4571 +        mpt->m_polled_intr = 1;
4567 4572  
4568 4573          /*
4569 4574           * Get the current interrupt mask and disable interrupts.  When
4570 4575           * re-enabling ints, set mask to saved value.
4571 4576           */
4572 4577          int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask);
4573 4578          MPTSAS_DISABLE_INTR(mpt);
4574 4579  
4575 4580          /*
4576 4581           * Keep polling for at least (polltime * 1000) seconds
4577 4582           */
4578 4583          for (cnt = 0; cnt < polltime; cnt++) {
4579      -                mutex_enter(&mpt->m_intr_mutex);
4580 4584                  (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
4581 4585                      DDI_DMA_SYNC_FORCPU);
4582 4586  
4583 4587                  reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
4584 4588                      MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
4585 4589  
4586 4590                  if (ddi_get32(mpt->m_acc_post_queue_hdl,
4587 4591                      &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
4588 4592                      ddi_get32(mpt->m_acc_post_queue_hdl,
4589 4593                      &reply_desc_union->Words.High) == 0xFFFFFFFF) {
4590      -                        mutex_exit(&mpt->m_intr_mutex);
4591 4594                          drv_usecwait(1000);
4592 4595                          continue;
4593 4596                  }
4594 4597  
4595      -                reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
4596      -                    &reply_desc_union->Default.ReplyFlags);
4597      -                reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
4598      -                reply_desc_union_v.Default.ReplyFlags = reply_type;
4599      -                if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
4600      -                        reply_desc_union_v.SCSIIOSuccess.SMID =
4601      -                            ddi_get16(mpt->m_acc_post_queue_hdl,
4602      -                            &reply_desc_union->SCSIIOSuccess.SMID);
4603      -                } else if (reply_type ==
4604      -                    MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
4605      -                        reply_desc_union_v.AddressReply.ReplyFrameAddress =
4606      -                            ddi_get32(mpt->m_acc_post_queue_hdl,
4607      -                            &reply_desc_union->AddressReply.ReplyFrameAddress);
4608      -                        reply_desc_union_v.AddressReply.SMID =
4609      -                            ddi_get16(mpt->m_acc_post_queue_hdl,
4610      -                            &reply_desc_union->AddressReply.SMID);
4611      -                }
4612 4598                  /*
4613      -                 * Clear the reply descriptor for re-use and increment
4614      -                 * index.
     4599 +                 * The reply is valid, process it according to its
     4600 +                 * type.
4615 4601                   */
4616      -                ddi_put64(mpt->m_acc_post_queue_hdl,
4617      -                    &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
4618      -                    0xFFFFFFFFFFFFFFFF);
4619      -                (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
4620      -                    DDI_DMA_SYNC_FORDEV);
     4602 +                mptsas_process_intr(mpt, reply_desc_union);
4621 4603  
4622 4604                  if (++mpt->m_post_index == mpt->m_post_queue_depth) {
4623 4605                          mpt->m_post_index = 0;
4624 4606                  }
4625 4607  
4626 4608                  /*
4627 4609                   * Update the global reply index
4628 4610                   */
4629 4611                  ddi_put32(mpt->m_datap,
4630 4612                      &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
4631      -                mutex_exit(&mpt->m_intr_mutex);
     4613 +                mpt->m_polled_intr = 0;
4632 4614  
4633 4615                  /*
4634      -                 * The reply is valid, process it according to its
4635      -                 * type.
4636      -                 */
4637      -                mptsas_process_intr(mpt, &reply_desc_union_v);
4638      -
4639      -
4640      -                /*
4641 4616                   * Re-enable interrupts and quit.
4642 4617                   */
4643 4618                  ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask,
4644 4619                      int_mask);
4645 4620                  return (TRUE);
4646 4621  
4647 4622          }
4648 4623  
4649 4624          /*
4650 4625           * Clear polling flag, re-enable interrupts and quit.
4651 4626           */
     4627 +        mpt->m_polled_intr = 0;
4652 4628          ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
4653 4629          return (FALSE);
4654 4630  }
4655 4631  
4656      -/*
4657      - * For fastpath, the m_intr_mutex should be held from the begining to the end,
4658      - * so we only treat those cmds that need not release m_intr_mutex(even just for
4659      - * a moment) as candidate for fast processing. otherwise, we don't handle them
4660      - * and just return, then in ISR, those cmds would be handled later with m_mutex
4661      - * held and m_intr_mutex not held.
4662      - */
4663      -static int
4664      -mptsas_handle_io_fastpath(mptsas_t *mpt,
4665      -    uint16_t SMID)
4666      -{
4667      -        mptsas_slots_t                          *slots = mpt->m_active;
4668      -        mptsas_cmd_t                            *cmd = NULL;
4669      -        struct scsi_pkt                         *pkt;
4670      -
4671      -        /*
4672      -         * This is a success reply so just complete the IO.  First, do a sanity
4673      -         * check on the SMID.  The final slot is used for TM requests, which
4674      -         * would not come into this reply handler.
4675      -         */
4676      -        if ((SMID == 0) || (SMID > slots->m_n_slots)) {
4677      -                mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4678      -                    SMID);
4679      -                ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4680      -                return (TRUE);
4681      -        }
4682      -
4683      -        cmd = slots->m_slot[SMID];
4684      -
4685      -        /*
4686      -         * print warning and return if the slot is empty
4687      -         */
4688      -        if (cmd == NULL) {
4689      -                mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
4690      -                    "in slot %d", SMID);
4691      -                return (TRUE);
4692      -        }
4693      -
4694      -        pkt = CMD2PKT(cmd);
4695      -        pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
4696      -            STATE_GOT_STATUS);
4697      -        if (cmd->cmd_flags & CFLAG_DMAVALID) {
4698      -                pkt->pkt_state |= STATE_XFERRED_DATA;
4699      -        }
4700      -        pkt->pkt_resid = 0;
4701      -
4702      -        /*
4703      -         * If the cmd is a IOC, or a passthrough, then we don't process it in
4704      -         * fastpath, and later it would be handled by mptsas_process_intr()
4705      -         * with m_mutex protected.
4706      -         */
4707      -        if (cmd->cmd_flags & (CFLAG_PASSTHRU | CFLAG_CMDIOC)) {
4708      -                return (FALSE);
4709      -        } else {
4710      -                mptsas_remove_cmd0(mpt, cmd);
4711      -        }
4712      -
4713      -        if (cmd->cmd_flags & CFLAG_RETRY) {
4714      -                /*
4715      -                 * The target returned QFULL or busy, do not add tihs
4716      -                 * pkt to the doneq since the hba will retry
4717      -                 * this cmd.
4718      -                 *
4719      -                 * The pkt has already been resubmitted in
4720      -                 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4721      -                 * Remove this cmd_flag here.
4722      -                 */
4723      -                cmd->cmd_flags &= ~CFLAG_RETRY;
4724      -        } else {
4725      -                mptsas_doneq_add0(mpt, cmd);
4726      -        }
4727      -
4728      -        /*
4729      -         * In fastpath, the cmd should only be a context reply, so just check
4730      -         * the post queue of the reply descriptor and the dmahandle of the cmd
4731      -         * is enough. No sense data in this case and no need to check the dma
4732      -         * handle where sense data dma info is saved, the dma handle of the
4733      -         * reply frame, and the dma handle of the reply free queue.
4734      -         * For the dma handle of the request queue. Check fma here since we
4735      -         * are sure the request must have already been sent/DMAed correctly.
4736      -         * otherwise checking in mptsas_scsi_start() is not correct since
4737      -         * at that time the dma may not start.
4738      -         */
4739      -        if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
4740      -            DDI_SUCCESS) ||
4741      -            (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
4742      -            DDI_SUCCESS)) {
4743      -                ddi_fm_service_impact(mpt->m_dip,
4744      -                    DDI_SERVICE_UNAFFECTED);
4745      -                pkt->pkt_reason = CMD_TRAN_ERR;
4746      -                pkt->pkt_statistics = 0;
4747      -        }
4748      -        if (cmd->cmd_dmahandle &&
4749      -            (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
4750      -                ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4751      -                pkt->pkt_reason = CMD_TRAN_ERR;
4752      -                pkt->pkt_statistics = 0;
4753      -        }
4754      -        if ((cmd->cmd_extra_frames &&
4755      -            ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
4756      -            DDI_SUCCESS) ||
4757      -            (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
4758      -            DDI_SUCCESS)))) {
4759      -                ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4760      -                pkt->pkt_reason = CMD_TRAN_ERR;
4761      -                pkt->pkt_statistics = 0;
4762      -        }
4763      -
4764      -        return (TRUE);
4765      -}
4766      -
4767 4632  static void
4768 4633  mptsas_handle_scsi_io_success(mptsas_t *mpt,
4769 4634      pMpi2ReplyDescriptorsUnion_t reply_desc)
4770 4635  {
4771 4636          pMpi2SCSIIOSuccessReplyDescriptor_t     scsi_io_success;
4772 4637          uint16_t                                SMID;
4773 4638          mptsas_slots_t                          *slots = mpt->m_active;
4774 4639          mptsas_cmd_t                            *cmd = NULL;
4775 4640          struct scsi_pkt                         *pkt;
4776 4641  
     4642 +        ASSERT(mutex_owned(&mpt->m_mutex));
     4643 +
4777 4644          scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4778      -        SMID = scsi_io_success->SMID;
     4645 +        SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4779 4646  
4780 4647          /*
4781 4648           * This is a success reply so just complete the IO.  First, do a sanity
4782 4649           * check on the SMID.  The final slot is used for TM requests, which
4783 4650           * would not come into this reply handler.
4784 4651           */
4785 4652          if ((SMID == 0) || (SMID > slots->m_n_slots)) {
4786 4653                  mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4787 4654                      SMID);
4788 4655                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
↓ open down ↓ 54 lines elided ↑ open up ↑
4843 4710          uint16_t                        SMID, iocstatus;
4844 4711          mptsas_slots_t                  *slots = mpt->m_active;
4845 4712          mptsas_cmd_t                    *cmd = NULL;
4846 4713          uint8_t                         function, buffer_type;
4847 4714          m_replyh_arg_t                  *args;
4848 4715          int                             reply_frame_no;
4849 4716  
4850 4717          ASSERT(mutex_owned(&mpt->m_mutex));
4851 4718  
4852 4719          address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
     4720 +        reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
     4721 +            &address_reply->ReplyFrameAddress);
     4722 +        SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
4853 4723  
4854      -        reply_addr = address_reply->ReplyFrameAddress;
4855      -        SMID = address_reply->SMID;
4856 4724          /*
4857 4725           * If reply frame is not in the proper range we should ignore this
4858 4726           * message and exit the interrupt handler.
4859 4727           */
4860 4728          if ((reply_addr < mpt->m_reply_frame_dma_addr) ||
4861 4729              (reply_addr >= (mpt->m_reply_frame_dma_addr +
4862 4730              (mpt->m_reply_frame_size * mpt->m_max_replies))) ||
4863 4731              ((reply_addr - mpt->m_reply_frame_dma_addr) %
4864 4732              mpt->m_reply_frame_size != 0)) {
4865 4733                  mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
↓ open down ↓ 85 lines elided ↑ open up ↑
4951 4819                   * NOT_RESPONDING/ADDED only now
4952 4820                   */
4953 4821                  if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
4954 4822                          /*
4955 4823                           * Would not return main process,
4956 4824                           * just let taskq resolve ack action
4957 4825                           * and ack would be sent in taskq thread
4958 4826                           */
4959 4827                          NDBG20(("send mptsas_handle_event_sync success"));
4960 4828                  }
     4829 +
     4830 +                if (mpt->m_in_reset) {
     4831 +                        NDBG20(("dropping event received during reset"));
     4832 +                        return;
     4833 +                }
     4834 +
4961 4835                  if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
4962 4836                      (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
4963 4837                          mptsas_log(mpt, CE_WARN, "No memory available"
4964 4838                          "for dispatch taskq");
4965 4839                          /*
4966 4840                           * Return the reply frame to the free queue.
4967 4841                           */
4968 4842                          ddi_put32(mpt->m_acc_free_queue_hdl,
4969 4843                              &((uint32_t *)(void *)
4970 4844                              mpt->m_free_queue)[mpt->m_free_index], reply_addr);
↓ open down ↓ 134 lines elided ↑ open up ↑
5105 4979                   */
5106 4980                  *(pkt->pkt_scbp) = STATUS_BUSY;
5107 4981                  return;
5108 4982          }
5109 4983  
5110 4984          if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
5111 4985              ((ioc_status & MPI2_IOCSTATUS_MASK) ==
5112 4986              MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
5113 4987                  pkt->pkt_reason = CMD_INCOMPLETE;
5114 4988                  pkt->pkt_state |= STATE_GOT_BUS;
5115      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
5116 4989                  if (ptgt->m_reset_delay == 0) {
5117 4990                          mptsas_set_throttle(mpt, ptgt,
5118 4991                              DRAIN_THROTTLE);
5119 4992                  }
5120      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
5121 4993                  return;
5122 4994          }
5123 4995  
5124 4996          if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
5125 4997                  responsedata &= 0x000000FF;
5126 4998                  if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
5127 4999                          mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
5128 5000                          pkt->pkt_reason = CMD_TLR_OFF;
5129 5001                          return;
5130 5002                  }
↓ open down ↓ 79 lines elided ↑ open up ↑
5210 5082                                      "for handle SAS dynamic reconfigure"
5211 5083                                      "failed. \n");
5212 5084                          }
5213 5085                  }
5214 5086                  break;
5215 5087          case MPI2_SCSI_STATUS_GOOD:
5216 5088                  switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5217 5089                  case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5218 5090                          pkt->pkt_reason = CMD_DEV_GONE;
5219 5091                          pkt->pkt_state |= STATE_GOT_BUS;
5220      -                        mutex_enter(&ptgt->m_tgt_intr_mutex);
5221 5092                          if (ptgt->m_reset_delay == 0) {
5222 5093                                  mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5223 5094                          }
5224      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
5225 5095                          NDBG31(("lost disk for target%d, command:%x",
5226 5096                              Tgt(cmd), pkt->pkt_cdbp[0]));
5227 5097                          break;
5228 5098                  case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
5229 5099                          NDBG31(("data overrun: xferred=%d", xferred));
5230 5100                          NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5231 5101                          pkt->pkt_reason = CMD_DATA_OVR;
5232 5102                          pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5233 5103                              | STATE_SENT_CMD | STATE_GOT_STATUS
5234 5104                              | STATE_XFERRED_DATA);
↓ open down ↓ 26 lines elided ↑ open up ↑
5261 5131                              cmd, CMD_TERMINATED, STAT_TERMINATED);
5262 5132                          break;
5263 5133                  case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5264 5134                  case MPI2_IOCSTATUS_BUSY:
5265 5135                          /*
5266 5136                           * set throttles to drain
5267 5137                           */
5268 5138                          ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5269 5139                              &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
5270 5140                          while (ptgt != NULL) {
5271      -                                mutex_enter(&ptgt->m_tgt_intr_mutex);
5272 5141                                  mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5273      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
5274 5142  
5275 5143                                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5276 5144                                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
5277 5145                          }
5278 5146  
5279 5147                          /*
5280 5148                           * retry command
5281 5149                           */
5282 5150                          cmd->cmd_flags |= CFLAG_RETRY;
5283 5151                          cmd->cmd_pkt_flags |= FLAG_HEAD;
5284 5152  
5285      -                        mutex_exit(&mpt->m_mutex);
5286 5153                          (void) mptsas_accept_pkt(mpt, cmd);
5287      -                        mutex_enter(&mpt->m_mutex);
5288 5154                          break;
5289 5155                  default:
5290 5156                          mptsas_log(mpt, CE_WARN,
5291 5157                              "unknown ioc_status = %x\n", ioc_status);
5292 5158                          mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5293 5159                              "count = %x, scsi_status = %x", scsi_state,
5294 5160                              xferred, scsi_status);
5295 5161                          break;
5296 5162                  }
5297 5163                  break;
↓ open down ↓ 94 lines elided ↑ open up ↑
5392 5258                  }
5393 5259                  mutex_enter(&item->mutex);
5394 5260          }
5395 5261          mutex_exit(&item->mutex);
5396 5262          mutex_enter(&mpt->m_doneq_mutex);
5397 5263          mpt->m_doneq_thread_n--;
5398 5264          cv_broadcast(&mpt->m_doneq_thread_cv);
5399 5265          mutex_exit(&mpt->m_doneq_mutex);
5400 5266  }
5401 5267  
     5268 +
5402 5269  /*
5403 5270   * mpt interrupt handler.
5404 5271   */
5405 5272  static uint_t
5406 5273  mptsas_intr(caddr_t arg1, caddr_t arg2)
5407 5274  {
5408 5275          mptsas_t                        *mpt = (void *)arg1;
5409 5276          pMpi2ReplyDescriptorsUnion_t    reply_desc_union;
5410 5277          uchar_t                         did_reply = FALSE;
5411      -        int                             i = 0, j;
5412      -        uint8_t                         reply_type;
5413      -        uint16_t                        SMID;
5414 5278  
5415 5279          NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5416 5280  
5417      -        /*
5418      -         * 1.
5419      -         * To avoid using m_mutex in the ISR(ISR referes not only mptsas_intr,
5420      -         * but all of the recursive called functions in it. the same below),
5421      -         * separate mutexs are introduced to protect the elements shown in ISR.
5422      -         * 3 type of mutex are involved here:
5423      -         *      a)per instance mutex m_intr_mutex.
5424      -         *      b)per target mutex m_tgt_intr_mutex.
5425      -         *      c)mutex that protect the free slot.
5426      -         *
5427      -         * a)per instance mutex m_intr_mutex:
5428      -         * used to protect m_options, m_power, m_waitq, etc that would be
5429      -         * checked/modified in ISR; protect the getting and setting the reply
5430      -         * descriptor index; protect the m_slots[];
5431      -         *
5432      -         * b)per target mutex m_tgt_intr_mutex:
5433      -         * used to protect per target element which has relationship to ISR.
5434      -         * contention for the new per target mutex is just as high as it in
5435      -         * sd(7d) driver.
5436      -         *
5437      -         * c)mutexs that protect the free slots:
5438      -         * those mutexs are introduced to minimize the mutex contentions
5439      -         * between the IO request threads where free slots are allocated
5440      -         * for sending cmds and ISR where slots holding outstanding cmds
5441      -         * are returned to the free pool.
5442      -         * the idea is like this:
5443      -         * 1) Partition all of the free slot into NCPU groups. For example,
5444      -         * In system where we have 15 slots, and 4 CPU, then slot s1,s5,s9,s13
5445      -         * are marked belonging to CPU1, s2,s6,s10,s14 to CPU2, s3,s7,s11,s15
5446      -         * to CPU3, and s4,s8,s12 to CPU4.
5447      -         * 2) In each of the group, an alloc/release queue pair is created,
5448      -         * and both the allocq and the releaseq have a dedicated mutex.
5449      -         * 3) When init, all of the slots in a CPU group are inserted into the
5450      -         * allocq of its CPU's pair.
5451      -         * 4) When doing IO,
5452      -         * mptsas_scsi_start()
5453      -         * {
5454      -         *      cpuid = the cpu NO of the cpu where this thread is running on
5455      -         * retry:
5456      -         *      mutex_enter(&allocq[cpuid]);
5457      -         *      if (get free slot = success) {
5458      -         *              remove the slot from the allocq
5459      -         *              mutex_exit(&allocq[cpuid]);
5460      -         *              return(success);
5461      -         *      } else { // exchange allocq and releaseq and try again
5462      -         *              mutex_enter(&releq[cpuid]);
5463      -         *              exchange the allocq and releaseq of this pair;
5464      -         *              mutex_exit(&releq[cpuid]);
5465      -         *              if (try to get free slot again = success) {
5466      -         *                      remove the slot from the allocq
5467      -         *                      mutex_exit(&allocq[cpuid]);
5468      -         *                      return(success);
5469      -         *              } else {
5470      -         *                      MOD(cpuid)++;
5471      -         *                      goto retry;
5472      -         *                      if (all CPU groups tried)
5473      -         *                              mutex_exit(&allocq[cpuid]);
5474      -         *                              return(failure);
5475      -         *              }
5476      -         *      }
5477      -         * }
5478      -         * ISR()
5479      -         * {
5480      -         *              cpuid = the CPU group id where the slot sending the
5481      -         *              cmd belongs;
5482      -         *              mutex_enter(&releq[cpuid]);
5483      -         *              remove the slot from the releaseq
5484      -         *              mutex_exit(&releq[cpuid]);
5485      -         * }
5486      -         * This way, only when the queue pair doing exchange have mutex
5487      -         * contentions.
5488      -         *
5489      -         * For mutex m_intr_mutex and m_tgt_intr_mutex, there are 2 scenarios:
5490      -         *
5491      -         * a)If the elements are only checked but not modified in the ISR, then
5492      -         * only the places where those elements are modifed(outside of ISR)
5493      -         * need to be protected by the new introduced mutex.
5494      -         * For example, data A is only read/checked in ISR, then we need do
5495      -         * like this:
5496      -         * In ISR:
5497      -         * {
5498      -         *      mutex_enter(&new_mutex);
5499      -         *      read(A);
5500      -         *      mutex_exit(&new_mutex);
5501      -         *      //the new_mutex here is either the m_tgt_intr_mutex or
5502      -         *      //the m_intr_mutex.
5503      -         * }
5504      -         * In non-ISR
5505      -         * {
5506      -         *      mutex_enter(&m_mutex); //the stock driver already did this
5507      -         *      mutex_enter(&new_mutex);
5508      -         *      write(A);
5509      -         *      mutex_exit(&new_mutex);
5510      -         *      mutex_exit(&m_mutex); //the stock driver already did this
5511      -         *
5512      -         *      read(A);
5513      -         *      // read(A) in non-ISR is not required to be protected by new
5514      -         *      // mutex since 'A' has already been protected by m_mutex
5515      -         *      // outside of the ISR
5516      -         * }
5517      -         *
5518      -         * Those fields in mptsas_target_t/ptgt which are only read in ISR
5519      -         * fall into this catergory. So they, together with the fields which
5520      -         * are never read in ISR, are not necessary to be protected by
5521      -         * m_tgt_intr_mutex, don't bother.
5522      -         * checking of m_waitq also falls into this catergory. so all of the
5523      -         * place outside of ISR where the m_waitq is modified, such as in
5524      -         * mptsas_waitq_add(), mptsas_waitq_delete(), mptsas_waitq_rm(),
5525      -         * m_intr_mutex should be used.
5526      -         *
5527      -         * b)If the elements are modified in the ISR, then each place where
5528      -         * those elements are referred(outside of ISR) need to be protected
5529      -         * by the new introduced mutex. Of course, if those elements only
5530      -         * appear in the non-key code path, that is, they don't affect
5531      -         * performance, then the m_mutex can still be used as before.
5532      -         * For example, data B is modified in key code path in ISR, and data C
5533      -         * is modified in non-key code path in ISR, then we can do like this:
5534      -         * In ISR:
5535      -         * {
5536      -         *      mutex_enter(&new_mutex);
5537      -         *      wirte(B);
5538      -         *      mutex_exit(&new_mutex);
5539      -         *      if (seldom happen) {
5540      -         *              mutex_enter(&m_mutex);
5541      -         *              write(C);
5542      -         *              mutex_exit(&m_mutex);
5543      -         *      }
5544      -         *      //the new_mutex here is either the m_tgt_intr_mutex or
5545      -         *      //the m_intr_mutex.
5546      -         * }
5547      -         * In non-ISR
5548      -         * {
5549      -         *      mutex_enter(&new_mutex);
5550      -         *      write(B);
5551      -         *      mutex_exit(&new_mutex);
5552      -         *
5553      -         *      mutex_enter(&new_mutex);
5554      -         *      read(B);
5555      -         *      mutex_exit(&new_mutex);
5556      -         *      // both write(B) and read(B) in non-ISR is required to be
5557      -         *      // protected by new mutex outside of the ISR
5558      -         *
5559      -         *      mutex_enter(&m_mutex); //the stock driver already did this
5560      -         *      read(C);
5561      -         *      write(C);
5562      -         *      mutex_exit(&m_mutex); //the stock driver already did this
5563      -         *      // both write(C) and read(C) in non-ISR have been already
5564      -         *      // been protected by m_mutex outside of the ISR
5565      -         * }
5566      -         *
5567      -         * For example, ptgt->m_t_ncmds fall into 'B' of this catergory, and
5568      -         * elements shown in address reply, restart_hba, passthrough, IOC
5569      -         * fall into 'C' of  this catergory.
5570      -         *
5571      -         * In any case where mutexs are nested, make sure in the following
5572      -         * order:
5573      -         *      m_mutex -> m_intr_mutex -> m_tgt_intr_mutex
5574      -         *      m_intr_mutex -> m_tgt_intr_mutex
5575      -         *      m_mutex -> m_intr_mutex
5576      -         *      m_mutex -> m_tgt_intr_mutex
5577      -         *
5578      -         * 2.
5579      -         * Make sure at any time, getting the ReplyDescriptor by m_post_index
5580      -         * and setting m_post_index to the ReplyDescriptorIndex register are
5581      -         * atomic. Since m_mutex is not used for this purpose in ISR, the new
5582      -         * mutex m_intr_mutex must play this role. So mptsas_poll(), where this
5583      -         * kind of getting/setting is also performed, must use m_intr_mutex.
5584      -         * Note, since context reply in ISR/process_intr is the only code path
5585      -         * which affect performance, a fast path is introduced to only handle
5586      -         * the read/write IO having context reply. For other IOs such as
5587      -         * passthrough and IOC with context reply and all address reply, we
5588      -         * use the as-is process_intr() to handle them. In order to keep the
5589      -         * same semantics in process_intr(), make sure any new mutex is not held
5590      -         * before enterring it.
5591      -         */
     5281 +        mutex_enter(&mpt->m_mutex);
5592 5282  
5593      -        mutex_enter(&mpt->m_intr_mutex);
5594      -
5595 5283          /*
5596 5284           * If interrupts are shared by two channels then check whether this
5597 5285           * interrupt is genuinely for this channel by making sure first the
5598 5286           * chip is in high power state.
5599 5287           */
5600 5288          if ((mpt->m_options & MPTSAS_OPT_PM) &&
5601 5289              (mpt->m_power_level != PM_LEVEL_D0)) {
5602      -                mutex_exit(&mpt->m_intr_mutex);
     5290 +                mutex_exit(&mpt->m_mutex);
5603 5291                  return (DDI_INTR_UNCLAIMED);
5604 5292          }
5605 5293  
5606 5294          /*
5607 5295           * If polling, interrupt was triggered by some shared interrupt because
5608 5296           * IOC interrupts are disabled during polling, so polling routine will
5609 5297           * handle any replies.  Considering this, if polling is happening,
5610 5298           * return with interrupt unclaimed.
5611 5299           */
5612 5300          if (mpt->m_polled_intr) {
5613      -                mutex_exit(&mpt->m_intr_mutex);
     5301 +                mutex_exit(&mpt->m_mutex);
5614 5302                  mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt");
5615 5303                  return (DDI_INTR_UNCLAIMED);
5616 5304          }
5617 5305  
5618 5306          /*
5619 5307           * Read the istat register.
5620 5308           */
5621 5309          if ((INTPENDING(mpt)) != 0) {
5622 5310                  /*
5623 5311                   * read fifo until empty.
↓ open down ↓ 14 lines elided ↑ open up ↑
5638 5326                                  break;
5639 5327                          }
5640 5328  
5641 5329                          /*
5642 5330                           * The reply is valid, process it according to its
5643 5331                           * type.  Also, set a flag for updating the reply index
5644 5332                           * after they've all been processed.
5645 5333                           */
5646 5334                          did_reply = TRUE;
5647 5335  
5648      -                        reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5649      -                            &reply_desc_union->Default.ReplyFlags);
5650      -                        reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5651      -                        mpt->m_reply[i].Default.ReplyFlags = reply_type;
5652      -                        if (reply_type ==
5653      -                            MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
5654      -                                SMID = ddi_get16(mpt->m_acc_post_queue_hdl,
5655      -                                    &reply_desc_union->SCSIIOSuccess.SMID);
5656      -                                if (mptsas_handle_io_fastpath(mpt, SMID) !=
5657      -                                    TRUE) {
5658      -                                        mpt->m_reply[i].SCSIIOSuccess.SMID =
5659      -                                            SMID;
5660      -                                        i++;
5661      -                                }
5662      -                        } else if (reply_type ==
5663      -                            MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5664      -                                mpt->m_reply[i].AddressReply.ReplyFrameAddress =
5665      -                                    ddi_get32(mpt->m_acc_post_queue_hdl,
5666      -                                    &reply_desc_union->AddressReply.
5667      -                                    ReplyFrameAddress);
5668      -                                mpt->m_reply[i].AddressReply.SMID =
5669      -                                    ddi_get16(mpt->m_acc_post_queue_hdl,
5670      -                                    &reply_desc_union->AddressReply.SMID);
5671      -                                i++;
5672      -                        }
5673      -                        /*
5674      -                         * Clear the reply descriptor for re-use and increment
5675      -                         * index.
5676      -                         */
5677      -                        ddi_put64(mpt->m_acc_post_queue_hdl,
5678      -                            &((uint64_t *)(void *)mpt->m_post_queue)
5679      -                            [mpt->m_post_index], 0xFFFFFFFFFFFFFFFF);
5680      -                        (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5681      -                            DDI_DMA_SYNC_FORDEV);
     5336 +                        mptsas_process_intr(mpt, reply_desc_union);
5682 5337  
5683 5338                          /*
5684 5339                           * Increment post index and roll over if needed.
5685 5340                           */
5686 5341                          if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5687 5342                                  mpt->m_post_index = 0;
5688 5343                          }
5689      -                        if (i >= MPI_ADDRESS_COALSCE_MAX)
5690      -                                break;
5691 5344                  }
5692 5345  
5693 5346                  /*
5694 5347                   * Update the global reply index if at least one reply was
5695 5348                   * processed.
5696 5349                   */
5697 5350                  if (did_reply) {
5698 5351                          ddi_put32(mpt->m_datap,
5699 5352                              &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5700      -
5701      -                        /*
5702      -                         * For fma, only check the PIO is required and enough
5703      -                         * here. Those cases where fastpath is not hit, the
5704      -                         * mptsas_fma_check() check all of the types of
5705      -                         * fma. That is not necessary and sometimes not
5706      -                         * correct. fma check should only be done after
5707      -                         * the PIO and/or dma is performed.
5708      -                         */
5709      -                        if ((mptsas_check_acc_handle(mpt->m_datap) !=
5710      -                            DDI_SUCCESS)) {
5711      -                                ddi_fm_service_impact(mpt->m_dip,
5712      -                                    DDI_SERVICE_UNAFFECTED);
5713      -                        }
5714      -
5715 5353                  }
5716 5354          } else {
5717      -                mutex_exit(&mpt->m_intr_mutex);
     5355 +                mutex_exit(&mpt->m_mutex);
5718 5356                  return (DDI_INTR_UNCLAIMED);
5719 5357          }
5720 5358          NDBG1(("mptsas_intr complete"));
5721      -        mutex_exit(&mpt->m_intr_mutex);
5722 5359  
5723 5360          /*
5724      -         * Since most of the cmds(read and write IO with success return.)
5725      -         * have already been processed in fast path in which the m_mutex
5726      -         * is not held, handling here the address reply and other context reply
5727      -         * such as passthrough and IOC cmd with m_mutex held should be a big
5728      -         * issue for performance.
5729      -         * If holding m_mutex to process these cmds was still an obvious issue,
5730      -         * we can process them in a taskq.
5731      -         */
5732      -        for (j = 0; j < i; j++) {
5733      -                mutex_enter(&mpt->m_mutex);
5734      -                mptsas_process_intr(mpt, &mpt->m_reply[j]);
5735      -                mutex_exit(&mpt->m_mutex);
5736      -        }
5737      -
5738      -        /*
5739 5361           * If no helper threads are created, process the doneq in ISR. If
5740 5362           * helpers are created, use the doneq length as a metric to measure the
5741 5363           * load on the interrupt CPU. If it is long enough, which indicates the
5742 5364           * load is heavy, then we deliver the IO completions to the helpers.
5743 5365           * This measurement has some limitations, although it is simple and
5744 5366           * straightforward and works well for most of the cases at present.
5745 5367           */
5746      -        if (!mpt->m_doneq_thread_n) {
     5368 +        if (!mpt->m_doneq_thread_n ||
     5369 +            (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
5747 5370                  mptsas_doneq_empty(mpt);
5748 5371          } else {
5749      -                int helper = 1;
5750      -                mutex_enter(&mpt->m_intr_mutex);
5751      -                if (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)
5752      -                        helper = 0;
5753      -                mutex_exit(&mpt->m_intr_mutex);
5754      -                if (helper) {
5755      -                        mptsas_deliver_doneq_thread(mpt);
5756      -                } else {
5757      -                        mptsas_doneq_empty(mpt);
5758      -                }
     5372 +                mptsas_deliver_doneq_thread(mpt);
5759 5373          }
5760 5374  
5761 5375          /*
5762 5376           * If there are queued cmd, start them now.
5763 5377           */
5764      -        mutex_enter(&mpt->m_intr_mutex);
5765 5378          if (mpt->m_waitq != NULL) {
5766      -                mutex_exit(&mpt->m_intr_mutex);
5767      -                mutex_enter(&mpt->m_mutex);
5768      -                mptsas_restart_hba(mpt);
5769      -                mutex_exit(&mpt->m_mutex);
5770      -                return (DDI_INTR_CLAIMED);
     5379 +                mptsas_restart_waitq(mpt);
5771 5380          }
5772      -        mutex_exit(&mpt->m_intr_mutex);
     5381 +
     5382 +        mutex_exit(&mpt->m_mutex);
5773 5383          return (DDI_INTR_CLAIMED);
5774 5384  }
5775 5385  
5776      -/*
5777      - * In ISR, the successfully completed read and write IO are processed in a
5778      - * fast path. This function is only used to handle non-fastpath IO, including
5779      - * all of the address reply, and the context reply for IOC cmd, passthrough,
5780      - * etc.
5781      - * This function is also used to process polled cmd.
5782      - */
5783 5386  static void
5784 5387  mptsas_process_intr(mptsas_t *mpt,
5785 5388      pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5786 5389  {
5787 5390          uint8_t reply_type;
5788 5391  
     5392 +        ASSERT(mutex_owned(&mpt->m_mutex));
     5393 +
5789 5394          /*
5790 5395           * The reply is valid, process it according to its
5791 5396           * type.  Also, set a flag for updated the reply index
5792 5397           * after they've all been processed.
5793 5398           */
5794      -        reply_type = reply_desc_union->Default.ReplyFlags;
     5399 +        reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
     5400 +            &reply_desc_union->Default.ReplyFlags);
     5401 +        reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5795 5402          if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
5796 5403                  mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5797 5404          } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5798 5405                  mptsas_handle_address_reply(mpt, reply_desc_union);
5799 5406          } else {
5800 5407                  mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5801 5408                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5802 5409          }
     5410 +
     5411 +        /*
     5412 +         * Clear the reply descriptor for re-use and increment
     5413 +         * index.
     5414 +         */
     5415 +        ddi_put64(mpt->m_acc_post_queue_hdl,
     5416 +            &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
     5417 +            0xFFFFFFFFFFFFFFFF);
     5418 +        (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
     5419 +            DDI_DMA_SYNC_FORDEV);
5803 5420  }
5804 5421  
5805 5422  /*
5806 5423   * handle qfull condition
5807 5424   */
5808 5425  static void
5809 5426  mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
5810 5427  {
5811 5428          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
5812 5429  
↓ open down ↓ 1 lines elided ↑ open up ↑
5814 5431              (ptgt->m_qfull_retries == 0)) {
5815 5432                  /*
5816 5433                   * We have exhausted the retries on QFULL, or,
5817 5434                   * the target driver has indicated that it
5818 5435                   * wants to handle QFULL itself by setting
5819 5436                   * qfull-retries capability to 0. In either case
5820 5437                   * we want the target driver's QFULL handling
5821 5438                   * to kick in. We do this by having pkt_reason
5822 5439                   * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
5823 5440                   */
5824      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
5825 5441                  mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5826      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
5827 5442          } else {
5828      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
5829 5443                  if (ptgt->m_reset_delay == 0) {
5830 5444                          ptgt->m_t_throttle =
5831 5445                              max((ptgt->m_t_ncmds - 2), 0);
5832 5446                  }
5833      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
5834 5447  
5835 5448                  cmd->cmd_pkt_flags |= FLAG_HEAD;
5836 5449                  cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
5837 5450                  cmd->cmd_flags |= CFLAG_RETRY;
5838 5451  
5839      -                mutex_exit(&mpt->m_mutex);
5840 5452                  (void) mptsas_accept_pkt(mpt, cmd);
5841      -                mutex_enter(&mpt->m_mutex);
5842 5453  
5843 5454                  /*
5844 5455                   * when target gives queue full status with no commands
5845 5456                   * outstanding (m_t_ncmds == 0), throttle is set to 0
5846 5457                   * (HOLD_THROTTLE), and the queue full handling start
5847 5458                   * (see psarc/1994/313); if there are commands outstanding,
5848 5459                   * throttle is set to (m_t_ncmds - 2)
5849 5460                   */
5850      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
5851 5461                  if (ptgt->m_t_throttle == HOLD_THROTTLE) {
5852 5462                          /*
5853 5463                           * By setting throttle to QFULL_THROTTLE, we
5854 5464                           * avoid submitting new commands and in
5855 5465                           * mptsas_restart_cmd find out slots which need
5856 5466                           * their throttles to be cleared.
5857 5467                           */
5858 5468                          mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
5859 5469                          if (mpt->m_restart_cmd_timeid == 0) {
5860 5470                                  mpt->m_restart_cmd_timeid =
5861 5471                                      timeout(mptsas_restart_cmd, mpt,
5862 5472                                      ptgt->m_qfull_retry_interval);
5863 5473                          }
5864 5474                  }
5865      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
5866 5475          }
5867 5476  }
5868 5477  
5869 5478  mptsas_phymask_t
5870 5479  mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
5871 5480  {
5872 5481          mptsas_phymask_t        phy_mask = 0;
5873 5482          uint8_t                 i = 0;
5874 5483  
5875 5484          NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
↓ open down ↓ 277 lines elided ↑ open up ↑
6153 5762                                  mptsas_log(mpt, CE_WARN, "Failed to find an "
6154 5763                                      "iport, should not happen!");
6155 5764                                  goto out;
6156 5765                          }
6157 5766  
6158 5767                  }
6159 5768                  ASSERT(parent);
6160 5769  handle_topo_change:
6161 5770  
6162 5771                  mutex_enter(&mpt->m_mutex);
6163      -
6164      -                mptsas_handle_topo_change(topo_node, parent);
     5772 +                /*
     5773 +                 * If HBA is being reset, don't perform operations depending
     5774 +                 * on the IOC. We must free the topo list, however.
     5775 +                 */
     5776 +                if (!mpt->m_in_reset)
     5777 +                        mptsas_handle_topo_change(topo_node, parent);
     5778 +                else
     5779 +                        NDBG20(("skipping topo change received during reset"));
6165 5780                  save_node = topo_node;
6166 5781                  topo_node = topo_node->next;
6167 5782                  ASSERT(save_node);
6168 5783                  kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
6169 5784                  mutex_exit(&mpt->m_mutex);
6170 5785  
6171 5786                  if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6172 5787                      (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
6173 5788                      (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
6174 5789                          /*
↓ open down ↓ 269 lines elided ↑ open up ↑
6444 6059                              DDI_PROP_SUCCESS) {
6445 6060                                  (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6446 6061                                      MPTSAS_VIRTUAL_PORT);
6447 6062                                  mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6448 6063                                      "prop update failed");
6449 6064                                  break;
6450 6065                          }
6451 6066                  }
6452 6067  
6453 6068                  mutex_enter(&mpt->m_mutex);
6454      -                if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) {
6455      -                        NDBG14(("mptsas: clear LED for tgt %x failed",
6456      -                            ptgt->m_slot_num));
6457      -                }
6458 6069                  if (rval == DDI_SUCCESS) {
6459 6070                          mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6460 6071                              ptgt->m_sas_wwn, ptgt->m_phymask);
6461 6072                          ptgt = NULL;
6462 6073                  } else {
6463 6074                          /*
6464 6075                           * clean DR_INTRANSITION flag to allow I/O down to
6465 6076                           * PHCI driver since failover finished.
6466 6077                           * Invalidate the devhdl
6467 6078                           */
6468      -                        mutex_enter(&ptgt->m_tgt_intr_mutex);
6469 6079                          ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6470 6080                          ptgt->m_tgt_unconfigured = 0;
     6081 +                        mutex_enter(&mpt->m_tx_waitq_mutex);
6471 6082                          ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6472      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
     6083 +                        mutex_exit(&mpt->m_tx_waitq_mutex);
6473 6084                  }
6474 6085  
6475 6086                  /*
6476 6087                   * Send SAS IO Unit Control to free the dev handle
6477 6088                   */
6478 6089                  if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6479 6090                      (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
6480 6091                          rval = mptsas_free_devhdl(mpt, devhdl);
6481 6092  
6482 6093                          NDBG20(("mptsas%d handle_topo_change to remove "
↓ open down ↓ 525 lines elided ↑ open up ↑
7008 6619                                          } else {
7009 6620                                                  topo_tail->next = topo_node;
7010 6621                                                  topo_tail = topo_node;
7011 6622                                          }
7012 6623                                          break;
7013 6624                                  }
7014 6625  
7015 6626                                  /*
7016 6627                                   * Update DR flag immediately avoid I/O failure
7017 6628                                   * before failover finish. Pay attention to the
7018      -                                 * mutex protect, we need grab the per target
7019      -                                 * mutex during set m_dr_flag because the
7020      -                                 * m_mutex would not be held all the time in
7021      -                                 * mptsas_scsi_start().
     6629 +                                 * mutex protect, we need grab m_tx_waitq_mutex
     6630 +                                 * during set m_dr_flag because we won't add
     6631 +                                 * the following command into waitq, instead,
     6632 +                                 * we need return TRAN_BUSY in the tran_start
     6633 +                                 * context.
7022 6634                                   */
7023      -                                mutex_enter(&ptgt->m_tgt_intr_mutex);
     6635 +                                mutex_enter(&mpt->m_tx_waitq_mutex);
7024 6636                                  ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7025      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
     6637 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
7026 6638  
7027 6639                                  topo_node = kmem_zalloc(
7028 6640                                      sizeof (mptsas_topo_change_list_t),
7029 6641                                      KM_SLEEP);
7030 6642                                  topo_node->mpt = mpt;
7031 6643                                  topo_node->un.phymask = ptgt->m_phymask;
7032 6644                                  topo_node->event =
7033 6645                                      MPTSAS_DR_EVENT_OFFLINE_TARGET;
7034 6646                                  topo_node->devhdl = dev_handle;
7035 6647                                  topo_node->flags = flags;
↓ open down ↓ 212 lines elided ↑ open up ↑
7248 6860                                          break;
7249 6861  
7250 6862                                  /*
7251 6863                                   * Clear any flags related to volume
7252 6864                                   */
7253 6865                                  (void) mptsas_delete_volume(mpt, volhandle);
7254 6866  
7255 6867                                  /*
7256 6868                                   * Update DR flag immediately avoid I/O failure
7257 6869                                   */
7258      -                                mutex_enter(&ptgt->m_tgt_intr_mutex);
     6870 +                                mutex_enter(&mpt->m_tx_waitq_mutex);
7259 6871                                  ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7260      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
     6872 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
7261 6873  
7262 6874                                  topo_node = kmem_zalloc(
7263 6875                                      sizeof (mptsas_topo_change_list_t),
7264 6876                                      KM_SLEEP);
7265 6877                                  topo_node->mpt = mpt;
7266 6878                                  topo_node->un.phymask = ptgt->m_phymask;
7267 6879                                  topo_node->event =
7268 6880                                      MPTSAS_DR_EVENT_OFFLINE_TARGET;
7269 6881                                  topo_node->devhdl = volhandle;
7270 6882                                  topo_node->flags =
↓ open down ↓ 11 lines elided ↑ open up ↑
7282 6894                          case MPI2_EVENT_IR_CHANGE_RC_HIDE:
7283 6895                          {
7284 6896                                  ptgt = mptsas_search_by_devhdl(tgttbl,
7285 6897                                      diskhandle);
7286 6898                                  if (ptgt == NULL)
7287 6899                                          break;
7288 6900  
7289 6901                                  /*
7290 6902                                   * Update DR flag immediately avoid I/O failure
7291 6903                                   */
7292      -                                mutex_enter(&ptgt->m_tgt_intr_mutex);
     6904 +                                mutex_enter(&mpt->m_tx_waitq_mutex);
7293 6905                                  ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
7294      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
     6906 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
7295 6907  
7296 6908                                  topo_node = kmem_zalloc(
7297 6909                                      sizeof (mptsas_topo_change_list_t),
7298 6910                                      KM_SLEEP);
7299 6911                                  topo_node->mpt = mpt;
7300 6912                                  topo_node->un.phymask = ptgt->m_phymask;
7301 6913                                  topo_node->event =
7302 6914                                      MPTSAS_DR_EVENT_OFFLINE_TARGET;
7303 6915                                  topo_node->devhdl = diskhandle;
7304 6916                                  topo_node->flags =
↓ open down ↓ 74 lines elided ↑ open up ↑
7379 6991          uint32_t                        status;
7380 6992          uint8_t                         port;
7381 6993          mptsas_t                        *mpt;
7382 6994          uint_t                          iocstatus;
7383 6995  
7384 6996          replyh_arg = (m_replyh_arg_t *)args;
7385 6997          rfm = replyh_arg->rfm;
7386 6998          mpt = replyh_arg->mpt;
7387 6999  
7388 7000          mutex_enter(&mpt->m_mutex);
     7001 +        /*
     7002 +         * If HBA is being reset, drop incoming event.
     7003 +         */
     7004 +        if (mpt->m_in_reset) {
     7005 +                NDBG20(("dropping event received prior to reset"));
     7006 +                mutex_exit(&mpt->m_mutex);
     7007 +                return;
     7008 +        }
7389 7009  
7390 7010          eventreply = (pMpi2EventNotificationReply_t)
7391 7011              (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
7392 7012          event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7393 7013  
7394 7014          if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7395 7015              &eventreply->IOCStatus)) {
7396 7016                  if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7397 7017                          mptsas_log(mpt, CE_WARN,
7398 7018                              "!mptsas_handle_event: IOCStatus=0x%x, "
↓ open down ↓ 540 lines elided ↑ open up ↑
7939 7559          mptsas_t        *mpt = arg;
7940 7560          mptsas_target_t *ptgt = NULL;
7941 7561  
7942 7562          mutex_enter(&mpt->m_mutex);
7943 7563  
7944 7564          mpt->m_restart_cmd_timeid = 0;
7945 7565  
7946 7566          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
7947 7567              MPTSAS_HASH_FIRST);
7948 7568          while (ptgt != NULL) {
7949      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
7950 7569                  if (ptgt->m_reset_delay == 0) {
7951 7570                          if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7952 7571                                  mptsas_set_throttle(mpt, ptgt,
7953 7572                                      MAX_THROTTLE);
7954 7573                          }
7955 7574                  }
7956      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
7957 7575  
7958 7576                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
7959 7577                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
7960 7578          }
7961 7579          mptsas_restart_hba(mpt);
7962 7580          mutex_exit(&mpt->m_mutex);
7963 7581  }
7964 7582  
7965      -/*
7966      - * mptsas_remove_cmd0 is similar to mptsas_remove_cmd except that it is called
7967      - * where m_intr_mutex has already been held.
7968      - */
7969 7583  void
7970 7584  mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7971 7585  {
7972      -        ASSERT(mutex_owned(&mpt->m_mutex));
7973      -
7974      -        /*
7975      -         * With new fine-grained lock mechanism, the outstanding cmd is only
7976      -         * linked to m_active before the dma is triggerred(MPTSAS_START_CMD)
7977      -         * to send it. that is, mptsas_save_cmd() doesn't link the outstanding
7978      -         * cmd now. So when mptsas_remove_cmd is called, a mptsas_save_cmd must
7979      -         * have been called, but the cmd may have not been linked.
7980      -         * For mptsas_remove_cmd0, the cmd must have been linked.
7981      -         * In order to keep the same semantic, we link the cmd to the
7982      -         * outstanding cmd list.
7983      -         */
7984      -        mpt->m_active->m_slot[cmd->cmd_slot] = cmd;
7985      -
7986      -        mutex_enter(&mpt->m_intr_mutex);
7987      -        mptsas_remove_cmd0(mpt, cmd);
7988      -        mutex_exit(&mpt->m_intr_mutex);
7989      -}
7990      -
7991      -static inline void
7992      -mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd)
7993      -{
7994 7586          int             slot;
7995 7587          mptsas_slots_t  *slots = mpt->m_active;
7996 7588          int             t;
7997 7589          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7998      -        mptsas_slot_free_e_t    *pe;
7999 7590  
8000 7591          ASSERT(cmd != NULL);
8001 7592          ASSERT(cmd->cmd_queued == FALSE);
8002 7593  
8003 7594          /*
8004 7595           * Task Management cmds are removed in their own routines.  Also,
8005 7596           * we don't want to modify timeout based on TM cmds.
8006 7597           */
8007 7598          if (cmd->cmd_flags & CFLAG_TM_CMD) {
8008 7599                  return;
8009 7600          }
8010 7601  
8011 7602          t = Tgt(cmd);
8012 7603          slot = cmd->cmd_slot;
8013      -        pe = mpt->m_slot_free_ae + slot - 1;
8014      -        ASSERT(cmd == slots->m_slot[slot]);
8015      -        ASSERT((slot > 0) && slot < (mpt->m_max_requests - 1));
8016 7604  
8017 7605          /*
8018 7606           * remove the cmd.
8019 7607           */
8020      -        mutex_enter(&mpt->m_slot_freeq_pairp[pe->cpuid].
8021      -            m_slot_releq.s.m_fq_mutex);
8022      -        NDBG31(("mptsas_remove_cmd0: removing cmd=0x%p", (void *)cmd));
8023      -        slots->m_slot[slot] = NULL;
8024      -        ASSERT(pe->slot == slot);
8025      -        list_insert_tail(&mpt->m_slot_freeq_pairp[pe->cpuid].
8026      -            m_slot_releq.s.m_fq_list, pe);
8027      -        mpt->m_slot_freeq_pairp[pe->cpuid].m_slot_releq.s.m_fq_n++;
8028      -        ASSERT(mpt->m_slot_freeq_pairp[pe->cpuid].
8029      -            m_slot_releq.s.m_fq_n <= mpt->m_max_requests - 2);
8030      -        mutex_exit(&mpt->m_slot_freeq_pairp[pe->cpuid].
8031      -            m_slot_releq.s.m_fq_mutex);
     7608 +        if (cmd == slots->m_slot[slot]) {
     7609 +                NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd));
     7610 +                slots->m_slot[slot] = NULL;
     7611 +                mpt->m_ncmds--;
8032 7612  
8033      -        /*
8034      -         * only decrement per target ncmds if command
8035      -         * has a target associated with it.
8036      -         */
8037      -        if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
8038      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
8039      -                ptgt->m_t_ncmds--;
8040 7613                  /*
8041      -                 * reset throttle if we just ran an untagged command
8042      -                 * to a tagged target
     7614 +                 * only decrement per target ncmds if command
     7615 +                 * has a target associated with it.
8043 7616                   */
8044      -                if ((ptgt->m_t_ncmds == 0) &&
8045      -                    ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
8046      -                        mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
     7617 +                if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
     7618 +                        ptgt->m_t_ncmds--;
     7619 +                        /*
     7620 +                         * reset throttle if we just ran an untagged command
     7621 +                         * to a tagged target
     7622 +                         */
     7623 +                        if ((ptgt->m_t_ncmds == 0) &&
     7624 +                            ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
     7625 +                                mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
     7626 +                        }
8047 7627                  }
8048      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
     7628 +
8049 7629          }
8050 7630  
8051 7631          /*
8052 7632           * This is all we need to do for ioc commands.
8053      -         * The ioc cmds would never be handled in fastpath in ISR, so we make
8054      -         * sure the mptsas_return_to_pool() would always be called with
8055      -         * m_mutex protected.
8056 7633           */
8057 7634          if (cmd->cmd_flags & CFLAG_CMDIOC) {
8058      -                ASSERT(mutex_owned(&mpt->m_mutex));
8059 7635                  mptsas_return_to_pool(mpt, cmd);
8060 7636                  return;
8061 7637          }
8062 7638  
8063 7639          /*
8064 7640           * Figure out what to set tag Q timeout for...
8065 7641           *
8066 7642           * Optimize: If we have duplicate's of same timeout
8067 7643           * we're using, then we'll use it again until we run
8068 7644           * out of duplicates.  This should be the normal case
8069 7645           * for block and raw I/O.
8070 7646           * If no duplicates, we have to scan through tag que and
8071 7647           * find the longest timeout value and use it.  This is
8072 7648           * going to take a while...
8073 7649           * Add 1 to m_n_slots to account for TM request.
8074 7650           */
8075      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
8076 7651          if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
8077 7652                  if (--(ptgt->m_dups) == 0) {
8078 7653                          if (ptgt->m_t_ncmds) {
8079 7654                                  mptsas_cmd_t *ssp;
8080 7655                                  uint_t n = 0;
8081 7656                                  ushort_t nslots = (slots->m_n_slots + 1);
8082 7657                                  ushort_t i;
8083 7658                                  /*
8084 7659                                   * This crude check assumes we don't do
8085 7660                                   * this too often which seems reasonable
↓ open down ↓ 13 lines elided ↑ open up ↑
8099 7674                                  ptgt->m_timebase = n;
8100 7675                          } else {
8101 7676                                  ptgt->m_dups = 0;
8102 7677                                  ptgt->m_timebase = 0;
8103 7678                          }
8104 7679                  }
8105 7680          }
8106 7681          ptgt->m_timeout = ptgt->m_timebase;
8107 7682  
8108 7683          ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
8109      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
8110 7684  }
8111 7685  
8112 7686  /*
     7687 + * accept all cmds on the tx_waitq if any and then
8113 7688   * start a fresh request from the top of the device queue.
     7689 + *
     7690 + * since there are always cmds queued on the tx_waitq, and rare cmds on
     7691 + * the instance waitq, so this function should not be invoked in the ISR,
     7692 + * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
     7693 + * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
8114 7694   */
8115 7695  static void
8116 7696  mptsas_restart_hba(mptsas_t *mpt)
8117 7697  {
     7698 +        ASSERT(mutex_owned(&mpt->m_mutex));
     7699 +
     7700 +        mutex_enter(&mpt->m_tx_waitq_mutex);
     7701 +        if (mpt->m_tx_waitq) {
     7702 +                mptsas_accept_tx_waitq(mpt);
     7703 +        }
     7704 +        mutex_exit(&mpt->m_tx_waitq_mutex);
     7705 +        mptsas_restart_waitq(mpt);
     7706 +}
     7707 +
     7708 +/*
     7709 + * start a fresh request from the top of the device queue
     7710 + */
     7711 +static void
     7712 +mptsas_restart_waitq(mptsas_t *mpt)
     7713 +{
8118 7714          mptsas_cmd_t    *cmd, *next_cmd;
8119 7715          mptsas_target_t *ptgt = NULL;
8120 7716  
8121      -        NDBG1(("mptsas_restart_hba: mpt=0x%p", (void *)mpt));
     7717 +        NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
8122 7718  
8123 7719          ASSERT(mutex_owned(&mpt->m_mutex));
8124 7720  
8125 7721          /*
8126 7722           * If there is a reset delay, don't start any cmds.  Otherwise, start
8127 7723           * as many cmds as possible.
8128 7724           * Since SMID 0 is reserved and the TM slot is reserved, the actual max
8129 7725           * commands is m_max_requests - 2.
8130 7726           */
8131 7727          cmd = mpt->m_waitq;
↓ open down ↓ 34 lines elided ↑ open up ↑
8166 7762                                   */
8167 7763                                  cmd->cmd_flags |= CFLAG_PREPARED;
8168 7764                                  mptsas_waitq_delete(mpt, cmd);
8169 7765                                  mptsas_start_diag(mpt, cmd);
8170 7766                          }
8171 7767                          cmd = next_cmd;
8172 7768                          continue;
8173 7769                  }
8174 7770  
8175 7771                  ptgt = cmd->cmd_tgt_addr;
8176      -                if (ptgt) {
8177      -                        mutex_enter(&mpt->m_intr_mutex);
8178      -                        mutex_enter(&ptgt->m_tgt_intr_mutex);
8179      -                        if ((ptgt->m_t_throttle == DRAIN_THROTTLE) &&
8180      -                            (ptgt->m_t_ncmds == 0)) {
8181      -                                mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
     7772 +                if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
     7773 +                    (ptgt->m_t_ncmds == 0)) {
     7774 +                        mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
     7775 +                }
     7776 +                if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
     7777 +                    (ptgt && (ptgt->m_reset_delay == 0)) &&
     7778 +                    (ptgt && (ptgt->m_t_ncmds <
     7779 +                    ptgt->m_t_throttle))) {
     7780 +                        if (mptsas_save_cmd(mpt, cmd) == TRUE) {
     7781 +                                mptsas_waitq_delete(mpt, cmd);
     7782 +                                (void) mptsas_start_cmd(mpt, cmd);
8182 7783                          }
8183      -                        if ((ptgt->m_reset_delay == 0) &&
8184      -                            (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
8185      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
8186      -                                mutex_exit(&mpt->m_intr_mutex);
8187      -                                if (mptsas_save_cmd(mpt, cmd) == TRUE) {
8188      -                                        mptsas_waitq_delete(mpt, cmd);
8189      -                                        (void) mptsas_start_cmd(mpt, cmd);
8190      -                                }
8191      -                                goto out;
8192      -                        }
8193      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
8194      -                        mutex_exit(&mpt->m_intr_mutex);
8195 7784                  }
8196      -out:
8197 7785                  cmd = next_cmd;
8198 7786          }
8199 7787  }
8200      -
8201 7788  /*
8202      - * mpt tag type lookup
     7789 + * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
     7790 + * Accept all those queued cmds before new cmd is accept so that the
     7791 + * cmds are sent in order.
8203 7792   */
8204      -static char mptsas_tag_lookup[] =
8205      -        {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
8206      -
8207      -/*
8208      - * mptsas_start_cmd0 is similar to mptsas_start_cmd, except that, it is called
8209      - * without ANY mutex protected, while, mptsas_start_cmd is called with m_mutex
8210      - * protected.
8211      - *
8212      - * the relevant field in ptgt should be protected by m_tgt_intr_mutex in both
8213      - * functions.
8214      - *
8215      - * before the cmds are linked on the slot for monitor as outstanding cmds, they
8216      - * are accessed as slab objects, so slab framework ensures the exclusive access,
8217      - * and no other mutex is requireed. Linking for monitor and the trigger of dma
8218      - * must be done exclusively.
8219      - */
8220      -static int
8221      -mptsas_start_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd)
     7793 +static void
     7794 +mptsas_accept_tx_waitq(mptsas_t *mpt)
8222 7795  {
8223      -        struct scsi_pkt         *pkt = CMD2PKT(cmd);
8224      -        uint32_t                control = 0;
8225      -        int                     n;
8226      -        caddr_t                 mem;
8227      -        pMpi2SCSIIORequest_t    io_request;
8228      -        ddi_dma_handle_t        dma_hdl = mpt->m_dma_req_frame_hdl;
8229      -        ddi_acc_handle_t        acc_hdl = mpt->m_acc_req_frame_hdl;
8230      -        mptsas_target_t         *ptgt = cmd->cmd_tgt_addr;
8231      -        uint16_t                SMID, io_flags = 0;
8232      -        uint32_t                request_desc_low, request_desc_high;
     7796 +        mptsas_cmd_t *cmd;
8233 7797  
8234      -        NDBG1(("mptsas_start_cmd0: cmd=0x%p", (void *)cmd));
     7798 +        ASSERT(mutex_owned(&mpt->m_mutex));
     7799 +        ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
8235 7800  
8236 7801          /*
8237      -         * Set SMID and increment index.  Rollover to 1 instead of 0 if index
8238      -         * is at the max.  0 is an invalid SMID, so we call the first index 1.
     7802 +         * A Bus Reset could occur at any time and flush the tx_waitq,
     7803 +         * so we cannot count on the tx_waitq to contain even one cmd.
     7804 +         * And when the m_tx_waitq_mutex is released and run
     7805 +         * mptsas_accept_pkt(), the tx_waitq may be flushed.
8239 7806           */
8240      -        SMID = cmd->cmd_slot;
8241      -
8242      -        /*
8243      -         * It is possible for back to back device reset to
8244      -         * happen before the reset delay has expired.  That's
8245      -         * ok, just let the device reset go out on the bus.
8246      -         */
8247      -        if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8248      -                ASSERT(ptgt->m_reset_delay == 0);
8249      -        }
8250      -
8251      -        /*
8252      -         * if a non-tagged cmd is submitted to an active tagged target
8253      -         * then drain before submitting this cmd; SCSI-2 allows RQSENSE
8254      -         * to be untagged
8255      -         */
8256      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
8257      -        if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
8258      -            (ptgt->m_t_ncmds > 1) &&
8259      -            ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
8260      -            (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
8261      -                if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8262      -                        NDBG23(("target=%d, untagged cmd, start draining\n",
8263      -                            ptgt->m_devhdl));
8264      -
8265      -                        if (ptgt->m_reset_delay == 0) {
8266      -                                mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
8267      -                        }
8268      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
8269      -
8270      -                        mutex_enter(&mpt->m_mutex);
8271      -                        mptsas_remove_cmd(mpt, cmd);
8272      -                        cmd->cmd_pkt_flags |= FLAG_HEAD;
8273      -                        mptsas_waitq_add(mpt, cmd);
8274      -                        mutex_exit(&mpt->m_mutex);
8275      -                        return (DDI_FAILURE);
8276      -                }
8277      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
8278      -                return (DDI_FAILURE);
8279      -        }
8280      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
8281      -
8282      -        /*
8283      -         * Set correct tag bits.
8284      -         */
8285      -        if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
8286      -                switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
8287      -                    FLAG_TAGMASK) >> 12)]) {
8288      -                case MSG_SIMPLE_QTAG:
8289      -                        control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
     7807 +        cmd = mpt->m_tx_waitq;
     7808 +        for (;;) {
     7809 +                if ((cmd = mpt->m_tx_waitq) == NULL) {
     7810 +                        mpt->m_tx_draining = 0;
8290 7811                          break;
8291      -                case MSG_HEAD_QTAG:
8292      -                        control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
8293      -                        break;
8294      -                case MSG_ORDERED_QTAG:
8295      -                        control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
8296      -                        break;
8297      -                default:
8298      -                        mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
8299      -                        break;
8300 7812                  }
8301      -        } else {
8302      -                if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
8303      -                                ptgt->m_t_throttle = 1;
     7813 +                if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
     7814 +                        mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8304 7815                  }
8305      -                control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
     7816 +                cmd->cmd_linkp = NULL;
     7817 +                mutex_exit(&mpt->m_tx_waitq_mutex);
     7818 +                if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
     7819 +                        cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
     7820 +                            "to accept cmd on queue\n");
     7821 +                mutex_enter(&mpt->m_tx_waitq_mutex);
8306 7822          }
     7823 +}
8307 7824  
8308      -        if (cmd->cmd_pkt_flags & FLAG_TLR) {
8309      -                control |= MPI2_SCSIIO_CONTROL_TLR_ON;
8310      -        }
8311 7825  
8312      -        mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
8313      -        io_request = (pMpi2SCSIIORequest_t)mem;
     7826 +/*
     7827 + * mpt tag type lookup
     7828 + */
     7829 +static char mptsas_tag_lookup[] =
     7830 +        {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
8314 7831  
8315      -        bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
8316      -        ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
8317      -            (MPI2_SCSI_IO_REQUEST, SGL) / 4);
8318      -        mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
8319      -            MPI2_FUNCTION_SCSI_IO_REQUEST);
8320      -
8321      -        (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
8322      -            io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
8323      -
8324      -        io_flags = cmd->cmd_cdblen;
8325      -        ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
8326      -        /*
8327      -         * setup the Scatter/Gather DMA list for this request
8328      -         */
8329      -        if (cmd->cmd_cookiec > 0) {
8330      -                mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
8331      -        } else {
8332      -                ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
8333      -                    ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
8334      -                    MPI2_SGE_FLAGS_END_OF_BUFFER |
8335      -                    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
8336      -                    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
8337      -        }
8338      -
8339      -        /*
8340      -         * save ARQ information
8341      -         */
8342      -        ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen);
8343      -        if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
8344      -            (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
8345      -                ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
8346      -                    cmd->cmd_ext_arqcookie.dmac_address);
8347      -        } else {
8348      -                ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
8349      -                    cmd->cmd_arqcookie.dmac_address);
8350      -        }
8351      -
8352      -        ddi_put32(acc_hdl, &io_request->Control, control);
8353      -
8354      -        NDBG31(("starting message=0x%p, with cmd=0x%p",
8355      -            (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd));
8356      -
8357      -        (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
8358      -
8359      -        /*
8360      -         * Build request descriptor and write it to the request desc post reg.
8361      -         */
8362      -        request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
8363      -        request_desc_high = ptgt->m_devhdl << 16;
8364      -
8365      -        mutex_enter(&mpt->m_mutex);
8366      -        mpt->m_active->m_slot[cmd->cmd_slot] = cmd;
8367      -        MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
8368      -        mutex_exit(&mpt->m_mutex);
8369      -
8370      -        /*
8371      -         * Start timeout.
8372      -         */
8373      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
8374      -#ifdef MPTSAS_TEST
8375      -        /*
8376      -         * Temporarily set timebase = 0;  needed for
8377      -         * timeout torture test.
8378      -         */
8379      -        if (mptsas_test_timeouts) {
8380      -                ptgt->m_timebase = 0;
8381      -        }
8382      -#endif
8383      -        n = pkt->pkt_time - ptgt->m_timebase;
8384      -
8385      -        if (n == 0) {
8386      -                (ptgt->m_dups)++;
8387      -                ptgt->m_timeout = ptgt->m_timebase;
8388      -        } else if (n > 0) {
8389      -                ptgt->m_timeout =
8390      -                    ptgt->m_timebase = pkt->pkt_time;
8391      -                ptgt->m_dups = 1;
8392      -        } else if (n < 0) {
8393      -                ptgt->m_timeout = ptgt->m_timebase;
8394      -        }
8395      -#ifdef MPTSAS_TEST
8396      -        /*
8397      -         * Set back to a number higher than
8398      -         * mptsas_scsi_watchdog_tick
8399      -         * so timeouts will happen in mptsas_watchsubr
8400      -         */
8401      -        if (mptsas_test_timeouts) {
8402      -                ptgt->m_timebase = 60;
8403      -        }
8404      -#endif
8405      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
8406      -
8407      -        if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
8408      -            (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
8409      -                ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8410      -                return (DDI_FAILURE);
8411      -        }
8412      -        return (DDI_SUCCESS);
8413      -}
8414      -
8415 7832  static int
8416 7833  mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
8417 7834  {
8418 7835          struct scsi_pkt         *pkt = CMD2PKT(cmd);
8419 7836          uint32_t                control = 0;
8420 7837          int                     n;
8421 7838          caddr_t                 mem;
8422 7839          pMpi2SCSIIORequest_t    io_request;
8423 7840          ddi_dma_handle_t        dma_hdl = mpt->m_dma_req_frame_hdl;
8424 7841          ddi_acc_handle_t        acc_hdl = mpt->m_acc_req_frame_hdl;
↓ open down ↓ 16 lines elided ↑ open up ↑
8441 7858           */
8442 7859          if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8443 7860                  ASSERT(ptgt->m_reset_delay == 0);
8444 7861          }
8445 7862  
8446 7863          /*
8447 7864           * if a non-tagged cmd is submitted to an active tagged target
8448 7865           * then drain before submitting this cmd; SCSI-2 allows RQSENSE
8449 7866           * to be untagged
8450 7867           */
8451      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
8452 7868          if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
8453 7869              (ptgt->m_t_ncmds > 1) &&
8454 7870              ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
8455 7871              (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
8456 7872                  if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
8457 7873                          NDBG23(("target=%d, untagged cmd, start draining\n",
8458 7874                              ptgt->m_devhdl));
8459 7875  
8460 7876                          if (ptgt->m_reset_delay == 0) {
8461 7877                                  mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
8462 7878                          }
8463      -                        mutex_exit(&ptgt->m_tgt_intr_mutex);
8464 7879  
8465 7880                          mptsas_remove_cmd(mpt, cmd);
8466 7881                          cmd->cmd_pkt_flags |= FLAG_HEAD;
8467 7882                          mptsas_waitq_add(mpt, cmd);
8468      -                        return (DDI_FAILURE);
8469 7883                  }
8470      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
8471 7884                  return (DDI_FAILURE);
8472 7885          }
8473      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
8474 7886  
8475 7887          /*
8476 7888           * Set correct tag bits.
8477 7889           */
8478 7890          if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
8479 7891                  switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
8480 7892                      FLAG_TAGMASK) >> 12)]) {
8481 7893                  case MSG_SIMPLE_QTAG:
8482 7894                          control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
8483 7895                          break;
↓ open down ↓ 63 lines elided ↑ open up ↑
8547 7959          NDBG31(("starting message=0x%p, with cmd=0x%p",
8548 7960              (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd));
8549 7961  
8550 7962          (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
8551 7963  
8552 7964          /*
8553 7965           * Build request descriptor and write it to the request desc post reg.
8554 7966           */
8555 7967          request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
8556 7968          request_desc_high = ptgt->m_devhdl << 16;
8557      -
8558      -        mpt->m_active->m_slot[cmd->cmd_slot] = cmd;
8559 7969          MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
8560 7970  
8561 7971          /*
8562 7972           * Start timeout.
8563 7973           */
8564      -        mutex_enter(&ptgt->m_tgt_intr_mutex);
8565 7974  #ifdef MPTSAS_TEST
8566 7975          /*
8567 7976           * Temporarily set timebase = 0;  needed for
8568 7977           * timeout torture test.
8569 7978           */
8570 7979          if (mptsas_test_timeouts) {
8571 7980                  ptgt->m_timebase = 0;
8572 7981          }
8573 7982  #endif
8574 7983          n = pkt->pkt_time - ptgt->m_timebase;
↓ open down ↓ 11 lines elided ↑ open up ↑
8586 7995  #ifdef MPTSAS_TEST
8587 7996          /*
8588 7997           * Set back to a number higher than
8589 7998           * mptsas_scsi_watchdog_tick
8590 7999           * so timeouts will happen in mptsas_watchsubr
8591 8000           */
8592 8001          if (mptsas_test_timeouts) {
8593 8002                  ptgt->m_timebase = 60;
8594 8003          }
8595 8004  #endif
8596      -        mutex_exit(&ptgt->m_tgt_intr_mutex);
8597 8005  
8598 8006          if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
8599 8007              (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
8600 8008                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8601 8009                  return (DDI_FAILURE);
8602 8010          }
8603 8011          return (DDI_SUCCESS);
8604 8012  }
8605 8013  
8606 8014  /*
↓ open down ↓ 26 lines elided ↑ open up ↑
8633 8041                  }
8634 8042                  mutex_exit(&item->mutex);
8635 8043          }
8636 8044          mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
8637 8045          mptsas_doneq_mv(mpt, t);
8638 8046          cv_signal(&mpt->m_doneq_thread_id[t].cv);
8639 8047          mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
8640 8048  }
8641 8049  
8642 8050  /*
8643      - * move the current global doneq to the doneq of thread[t]
     8051 + * move the current global doneq to the doneq of thead[t]
8644 8052   */
8645 8053  static void
8646 8054  mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
8647 8055  {
8648 8056          mptsas_cmd_t                    *cmd;
8649 8057          mptsas_doneq_thread_list_t      *item = &mpt->m_doneq_thread_id[t];
8650 8058  
8651 8059          ASSERT(mutex_owned(&item->mutex));
8652      -        mutex_enter(&mpt->m_intr_mutex);
8653 8060          while ((cmd = mpt->m_doneq) != NULL) {
8654 8061                  if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
8655 8062                          mpt->m_donetail = &mpt->m_doneq;
8656 8063                  }
8657 8064                  cmd->cmd_linkp = NULL;
8658 8065                  *item->donetail = cmd;
8659 8066                  item->donetail = &cmd->cmd_linkp;
8660 8067                  mpt->m_doneq_len--;
8661 8068                  item->len++;
8662 8069          }
8663      -        mutex_exit(&mpt->m_intr_mutex);
8664 8070  }
8665 8071  
8666 8072  void
8667 8073  mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
8668 8074  {
8669 8075          struct scsi_pkt *pkt = CMD2PKT(cmd);
8670 8076  
8671 8077          /* Check all acc and dma handles */
8672 8078          if ((mptsas_check_acc_handle(mpt->m_datap) !=
8673 8079              DDI_SUCCESS) ||
↓ open down ↓ 54 lines elided ↑ open up ↑
8728 8134          }
8729 8135          if (cmd->cmd_ext_arqhandle &&
8730 8136              (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) {
8731 8137                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
8732 8138                  pkt->pkt_reason = CMD_TRAN_ERR;
8733 8139                  pkt->pkt_statistics = 0;
8734 8140          }
8735 8141  }
8736 8142  
8737 8143  /*
8738      - * mptsas_doneq_add0 is similar to mptsas_doneq_add except that it is called
8739      - * where m_intr_mutex has already been held.
     8144 + * These routines manipulate the queue of commands that
     8145 + * are waiting for their completion routines to be called.
     8146 + * The queue is usually in FIFO order but on an MP system
     8147 + * it's possible for the completion routines to get out
     8148 + * of order. If that's a problem you need to add a global
     8149 + * mutex around the code that calls the completion routine
     8150 + * in the interrupt handler.
8740 8151   */
8741      -static inline void
8742      -mptsas_doneq_add0(mptsas_t *mpt, mptsas_cmd_t *cmd)
     8152 +static void
     8153 +mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8743 8154  {
8744 8155          struct scsi_pkt *pkt = CMD2PKT(cmd);
8745 8156  
8746      -        NDBG31(("mptsas_doneq_add0: cmd=0x%p", (void *)cmd));
     8157 +        NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
8747 8158  
8748 8159          ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
8749 8160          cmd->cmd_linkp = NULL;
8750 8161          cmd->cmd_flags |= CFLAG_FINISHED;
8751 8162          cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
8752 8163  
     8164 +        mptsas_fma_check(mpt, cmd);
     8165 +
8753 8166          /*
8754 8167           * only add scsi pkts that have completion routines to
8755 8168           * the doneq.  no intr cmds do not have callbacks.
8756 8169           */
8757 8170          if (pkt && (pkt->pkt_comp)) {
8758 8171                  *mpt->m_donetail = cmd;
8759 8172                  mpt->m_donetail = &cmd->cmd_linkp;
8760 8173                  mpt->m_doneq_len++;
8761 8174          }
8762 8175  }
8763 8176  
8764      -/*
8765      - * These routines manipulate the queue of commands that
8766      - * are waiting for their completion routines to be called.
8767      - * The queue is usually in FIFO order but on an MP system
8768      - * it's possible for the completion routines to get out
8769      - * of order. If that's a problem you need to add a global
8770      - * mutex around the code that calls the completion routine
8771      - * in the interrupt handler.
8772      - */
8773      -static void
8774      -mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8775      -{
8776      -        ASSERT(mutex_owned(&mpt->m_mutex));
8777      -
8778      -        mptsas_fma_check(mpt, cmd);
8779      -
8780      -        mutex_enter(&mpt->m_intr_mutex);
8781      -        mptsas_doneq_add0(mpt, cmd);
8782      -        mutex_exit(&mpt->m_intr_mutex);
8783      -}
8784      -
8785 8177  static mptsas_cmd_t *
8786 8178  mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
8787 8179  {
8788 8180          mptsas_cmd_t                    *cmd;
8789 8181          mptsas_doneq_thread_list_t      *item = &mpt->m_doneq_thread_id[t];
8790 8182  
8791 8183          /* pop one off the done queue */
8792 8184          if ((cmd = item->doneq) != NULL) {
8793 8185                  /* if the queue is now empty fix the tail pointer */
8794 8186                  NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
↓ open down ↓ 2 lines elided ↑ open up ↑
8797 8189                  }
8798 8190                  cmd->cmd_linkp = NULL;
8799 8191                  item->len--;
8800 8192          }
8801 8193          return (cmd);
8802 8194  }
8803 8195  
8804 8196  static void
8805 8197  mptsas_doneq_empty(mptsas_t *mpt)
8806 8198  {
8807      -        mutex_enter(&mpt->m_intr_mutex);
8808 8199          if (mpt->m_doneq && !mpt->m_in_callback) {
8809 8200                  mptsas_cmd_t    *cmd, *next;
8810 8201                  struct scsi_pkt *pkt;
8811 8202  
8812 8203                  mpt->m_in_callback = 1;
8813 8204                  cmd = mpt->m_doneq;
8814 8205                  mpt->m_doneq = NULL;
8815 8206                  mpt->m_donetail = &mpt->m_doneq;
8816 8207                  mpt->m_doneq_len = 0;
8817 8208  
8818      -                mutex_exit(&mpt->m_intr_mutex);
8819      -
     8209 +                mutex_exit(&mpt->m_mutex);
8820 8210                  /*
8821      -                 * ONLY in ISR, is it called without m_mutex held, otherwise,
8822      -                 * it is always called with m_mutex held.
8823      -                 */
8824      -                if ((curthread->t_flag & T_INTR_THREAD) == 0)
8825      -                        mutex_exit(&mpt->m_mutex);
8826      -                /*
8827 8211                   * run the completion routines of all the
8828 8212                   * completed commands
8829 8213                   */
8830 8214                  while (cmd != NULL) {
8831 8215                          next = cmd->cmd_linkp;
8832 8216                          cmd->cmd_linkp = NULL;
8833 8217                          /* run this command's completion routine */
8834 8218                          cmd->cmd_flags |= CFLAG_COMPLETED;
8835 8219                          pkt = CMD2PKT(cmd);
8836 8220                          mptsas_pkt_comp(pkt, cmd);
8837 8221                          cmd = next;
8838 8222                  }
8839      -                if ((curthread->t_flag & T_INTR_THREAD) == 0)
8840      -                        mutex_enter(&mpt->m_mutex);
     8223 +                mutex_enter(&mpt->m_mutex);
8841 8224                  mpt->m_in_callback = 0;
8842      -                return;
8843 8225          }
8844      -        mutex_exit(&mpt->m_intr_mutex);
8845 8226  }
8846 8227  
8847 8228  /*
8848 8229   * These routines manipulate the target's queue of pending requests
8849 8230   */
8850 8231  void
8851 8232  mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
8852 8233  {
8853 8234          NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
8854 8235          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8855 8236          cmd->cmd_queued = TRUE;
8856 8237          if (ptgt)
8857 8238                  ptgt->m_t_nwait++;
8858 8239          if (cmd->cmd_pkt_flags & FLAG_HEAD) {
8859      -                mutex_enter(&mpt->m_intr_mutex);
8860 8240                  if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
8861 8241                          mpt->m_waitqtail = &cmd->cmd_linkp;
8862 8242                  }
8863 8243                  mpt->m_waitq = cmd;
8864      -                mutex_exit(&mpt->m_intr_mutex);
8865 8244          } else {
8866 8245                  cmd->cmd_linkp = NULL;
8867 8246                  *(mpt->m_waitqtail) = cmd;
8868 8247                  mpt->m_waitqtail = &cmd->cmd_linkp;
8869 8248          }
8870 8249  }
8871 8250  
8872 8251  static mptsas_cmd_t *
8873 8252  mptsas_waitq_rm(mptsas_t *mpt)
8874 8253  {
8875 8254          mptsas_cmd_t    *cmd;
8876 8255          mptsas_target_t *ptgt;
8877 8256          NDBG7(("mptsas_waitq_rm"));
8878 8257  
8879      -        mutex_enter(&mpt->m_intr_mutex);
8880 8258          MPTSAS_WAITQ_RM(mpt, cmd);
8881      -        mutex_exit(&mpt->m_intr_mutex);
8882 8259  
8883 8260          NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
8884 8261          if (cmd) {
8885 8262                  ptgt = cmd->cmd_tgt_addr;
8886 8263                  if (ptgt) {
8887 8264                          ptgt->m_t_nwait--;
8888 8265                          ASSERT(ptgt->m_t_nwait >= 0);
8889 8266                  }
8890 8267          }
8891 8268          return (cmd);
↓ open down ↓ 9 lines elided ↑ open up ↑
8901 8278          mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8902 8279  
8903 8280          NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8904 8281              (void *)mpt, (void *)cmd));
8905 8282          if (ptgt) {
8906 8283                  ptgt->m_t_nwait--;
8907 8284                  ASSERT(ptgt->m_t_nwait >= 0);
8908 8285          }
8909 8286  
8910 8287          if (prevp == cmd) {
8911      -                mutex_enter(&mpt->m_intr_mutex);
8912 8288                  if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
8913 8289                          mpt->m_waitqtail = &mpt->m_waitq;
8914      -                mutex_exit(&mpt->m_intr_mutex);
8915 8290  
8916 8291                  cmd->cmd_linkp = NULL;
8917 8292                  cmd->cmd_queued = FALSE;
8918 8293                  NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8919 8294                      (void *)mpt, (void *)cmd));
8920 8295                  return;
8921 8296          }
8922 8297  
8923 8298          while (prevp != NULL) {
8924 8299                  if (prevp->cmd_linkp == cmd) {
↓ open down ↓ 4 lines elided ↑ open up ↑
8929 8304                          cmd->cmd_queued = FALSE;
8930 8305                          NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8931 8306                              (void *)mpt, (void *)cmd));
8932 8307                          return;
8933 8308                  }
8934 8309                  prevp = prevp->cmd_linkp;
8935 8310          }
8936 8311          cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
8937 8312  }
8938 8313  
     8314 +static mptsas_cmd_t *
     8315 +mptsas_tx_waitq_rm(mptsas_t *mpt)
     8316 +{
     8317 +        mptsas_cmd_t *cmd;
     8318 +        NDBG7(("mptsas_tx_waitq_rm"));
     8319 +
     8320 +        MPTSAS_TX_WAITQ_RM(mpt, cmd);
     8321 +
     8322 +        NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
     8323 +
     8324 +        return (cmd);
     8325 +}
     8326 +
8939 8327  /*
     8328 + * remove specified cmd from the middle of the tx_waitq.
     8329 + */
     8330 +static void
     8331 +mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
     8332 +{
     8333 +        mptsas_cmd_t *prevp = mpt->m_tx_waitq;
     8334 +
     8335 +        NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
     8336 +            (void *)mpt, (void *)cmd));
     8337 +
     8338 +        if (prevp == cmd) {
     8339 +                if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
     8340 +                        mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
     8341 +
     8342 +                cmd->cmd_linkp = NULL;
     8343 +                cmd->cmd_queued = FALSE;
     8344 +                NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
     8345 +                    (void *)mpt, (void *)cmd));
     8346 +                return;
     8347 +        }
     8348 +
     8349 +        while (prevp != NULL) {
     8350 +                if (prevp->cmd_linkp == cmd) {
     8351 +                        if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
     8352 +                                mpt->m_tx_waitqtail = &prevp->cmd_linkp;
     8353 +
     8354 +                        cmd->cmd_linkp = NULL;
     8355 +                        cmd->cmd_queued = FALSE;
     8356 +                        NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
     8357 +                            (void *)mpt, (void *)cmd));
     8358 +                        return;
     8359 +                }
     8360 +                prevp = prevp->cmd_linkp;
     8361 +        }
     8362 +        cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
     8363 +}
     8364 +
     8365 +/*
8940 8366   * device and bus reset handling
8941 8367   *
8942 8368   * Notes:
8943 8369   *      - RESET_ALL:    reset the controller
8944 8370   *      - RESET_TARGET: reset the target specified in scsi_address
8945 8371   */
8946 8372  static int
8947 8373  mptsas_scsi_reset(struct scsi_address *ap, int level)
8948 8374  {
8949 8375          mptsas_t                *mpt = ADDR2MPT(ap);
↓ open down ↓ 142 lines elided ↑ open up ↑
9092 8518          uint_t          stat;
9093 8519  
9094 8520          NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
9095 8521  
9096 8522          /*
9097 8523           * Make sure the I/O Controller has flushed all cmds
9098 8524           * that are associated with this target for a target reset
9099 8525           * and target/lun for abort task set.
9100 8526           * Account for TM requests, which use the last SMID.
9101 8527           */
9102      -        mutex_enter(&mpt->m_intr_mutex);
9103 8528          for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
9104      -                if ((cmd = slots->m_slot[slot]) == NULL) {
     8529 +                if ((cmd = slots->m_slot[slot]) == NULL)
9105 8530                          continue;
9106      -                }
9107 8531                  reason = CMD_RESET;
9108 8532                  stat = STAT_DEV_RESET;
9109 8533                  switch (tasktype) {
9110 8534                  case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9111 8535                          if (Tgt(cmd) == target) {
     8536 +                                if (cmd->cmd_tgt_addr->m_timeout < 0) {
     8537 +                                        /*
     8538 +                                         * When timeout requested, propagate
     8539 +                                         * proper reason and statistics to
     8540 +                                         * target drivers.
     8541 +                                         */
     8542 +                                        reason = CMD_TIMEOUT;
     8543 +                                        stat |= STAT_TIMEOUT;
     8544 +                                }
9112 8545                                  NDBG25(("mptsas_flush_target discovered non-"
9113 8546                                      "NULL cmd in slot %d, tasktype 0x%x", slot,
9114 8547                                      tasktype));
9115 8548                                  mptsas_dump_cmd(mpt, cmd);
9116      -                                mptsas_remove_cmd0(mpt, cmd);
     8549 +                                mptsas_remove_cmd(mpt, cmd);
9117 8550                                  mptsas_set_pkt_reason(mpt, cmd, reason, stat);
9118      -                                mptsas_doneq_add0(mpt, cmd);
     8551 +                                mptsas_doneq_add(mpt, cmd);
9119 8552                          }
9120 8553                          break;
9121 8554                  case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9122 8555                          reason = CMD_ABORTED;
9123 8556                          stat = STAT_ABORTED;
9124 8557                          /*FALLTHROUGH*/
9125 8558                  case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9126 8559                          if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9127 8560  
9128 8561                                  NDBG25(("mptsas_flush_target discovered non-"
9129 8562                                      "NULL cmd in slot %d, tasktype 0x%x", slot,
9130 8563                                      tasktype));
9131 8564                                  mptsas_dump_cmd(mpt, cmd);
9132      -                                mptsas_remove_cmd0(mpt, cmd);
     8565 +                                mptsas_remove_cmd(mpt, cmd);
9133 8566                                  mptsas_set_pkt_reason(mpt, cmd, reason,
9134 8567                                      stat);
9135      -                                mptsas_doneq_add0(mpt, cmd);
     8568 +                                mptsas_doneq_add(mpt, cmd);
9136 8569                          }
9137 8570                          break;
9138 8571                  default:
9139 8572                          break;
9140 8573                  }
9141 8574          }
9142      -        mutex_exit(&mpt->m_intr_mutex);
9143 8575  
9144 8576          /*
9145      -         * Flush the waitq of this target's cmds
     8577 +         * Flush the waitq and tx_waitq of this target's cmds
9146 8578           */
9147 8579          cmd = mpt->m_waitq;
9148 8580  
9149 8581          reason = CMD_RESET;
9150 8582          stat = STAT_DEV_RESET;
9151 8583  
9152 8584          switch (tasktype) {
9153 8585          case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
9154 8586                  while (cmd != NULL) {
9155 8587                          next_cmd = cmd->cmd_linkp;
9156 8588                          if (Tgt(cmd) == target) {
9157 8589                                  mptsas_waitq_delete(mpt, cmd);
9158 8590                                  mptsas_set_pkt_reason(mpt, cmd,
9159 8591                                      reason, stat);
9160 8592                                  mptsas_doneq_add(mpt, cmd);
9161 8593                          }
9162 8594                          cmd = next_cmd;
9163 8595                  }
     8596 +                mutex_enter(&mpt->m_tx_waitq_mutex);
     8597 +                cmd = mpt->m_tx_waitq;
     8598 +                while (cmd != NULL) {
     8599 +                        next_cmd = cmd->cmd_linkp;
     8600 +                        if (Tgt(cmd) == target) {
     8601 +                                mptsas_tx_waitq_delete(mpt, cmd);
     8602 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
     8603 +                                mptsas_set_pkt_reason(mpt, cmd,
     8604 +                                    reason, stat);
     8605 +                                mptsas_doneq_add(mpt, cmd);
     8606 +                                mutex_enter(&mpt->m_tx_waitq_mutex);
     8607 +                        }
     8608 +                        cmd = next_cmd;
     8609 +                }
     8610 +                mutex_exit(&mpt->m_tx_waitq_mutex);
9164 8611                  break;
9165 8612          case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
9166 8613                  reason = CMD_ABORTED;
9167 8614                  stat =  STAT_ABORTED;
9168 8615                  /*FALLTHROUGH*/
9169 8616          case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
9170 8617                  while (cmd != NULL) {
9171 8618                          next_cmd = cmd->cmd_linkp;
9172 8619                          if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
9173 8620                                  mptsas_waitq_delete(mpt, cmd);
9174 8621                                  mptsas_set_pkt_reason(mpt, cmd,
9175 8622                                      reason, stat);
9176 8623                                  mptsas_doneq_add(mpt, cmd);
9177 8624                          }
9178 8625                          cmd = next_cmd;
9179 8626                  }
     8627 +                mutex_enter(&mpt->m_tx_waitq_mutex);
     8628 +                cmd = mpt->m_tx_waitq;
     8629 +                while (cmd != NULL) {
     8630 +                        next_cmd = cmd->cmd_linkp;
     8631 +                        if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
     8632 +                                mptsas_tx_waitq_delete(mpt, cmd);
     8633 +                                mutex_exit(&mpt->m_tx_waitq_mutex);
     8634 +                                mptsas_set_pkt_reason(mpt, cmd,
     8635 +                                    reason, stat);
     8636 +                                mptsas_doneq_add(mpt, cmd);
     8637 +                                mutex_enter(&mpt->m_tx_waitq_mutex);
     8638 +                        }
     8639 +                        cmd = next_cmd;
     8640 +                }
     8641 +                mutex_exit(&mpt->m_tx_waitq_mutex);
9180 8642                  break;
9181 8643          default:
9182 8644                  mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
9183 8645                      tasktype);
9184 8646                  break;
9185 8647          }
9186 8648  }
9187 8649  
9188 8650  /*
9189 8651   * Clean up hba state, abort all outstanding command and commands in waitq
↓ open down ↓ 7 lines elided ↑ open up ↑
9197 8659          int             slot;
9198 8660  
9199 8661          NDBG25(("mptsas_flush_hba"));
9200 8662  
9201 8663          /*
9202 8664           * The I/O Controller should have already sent back
9203 8665           * all commands via the scsi I/O reply frame.  Make
9204 8666           * sure all commands have been flushed.
9205 8667           * Account for TM request, which use the last SMID.
9206 8668           */
9207      -        mutex_enter(&mpt->m_intr_mutex);
9208 8669          for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
9209      -                if ((cmd = slots->m_slot[slot]) == NULL) {
     8670 +                if ((cmd = slots->m_slot[slot]) == NULL)
9210 8671                          continue;
9211      -                }
9212 8672  
9213 8673                  if (cmd->cmd_flags & CFLAG_CMDIOC) {
9214 8674                          /*
9215 8675                           * Need to make sure to tell everyone that might be
9216 8676                           * waiting on this command that it's going to fail.  If
9217 8677                           * we get here, this command will never timeout because
9218 8678                           * the active command table is going to be re-allocated,
9219 8679                           * so there will be nothing to check against a time out.
9220 8680                           * Instead, mark the command as failed due to reset.
9221 8681                           */
↓ open down ↓ 7 lines elided ↑ open up ↑
9229 8689                                  cv_broadcast(&mpt->m_config_cv);
9230 8690                                  cv_broadcast(&mpt->m_fw_diag_cv);
9231 8691                          }
9232 8692                          continue;
9233 8693                  }
9234 8694  
9235 8695                  NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d",
9236 8696                      slot));
9237 8697                  mptsas_dump_cmd(mpt, cmd);
9238 8698  
9239      -                mptsas_remove_cmd0(mpt, cmd);
     8699 +                mptsas_remove_cmd(mpt, cmd);
9240 8700                  mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9241      -                mptsas_doneq_add0(mpt, cmd);
     8701 +                mptsas_doneq_add(mpt, cmd);
9242 8702          }
9243      -        mutex_exit(&mpt->m_intr_mutex);
9244 8703  
9245 8704          /*
9246 8705           * Flush the waitq.
9247 8706           */
9248 8707          while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
9249 8708                  mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
9250 8709                  if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9251 8710                      (cmd->cmd_flags & CFLAG_CONFIG) ||
9252 8711                      (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9253 8712                          cmd->cmd_flags |= CFLAG_FINISHED;
9254 8713                          cv_broadcast(&mpt->m_passthru_cv);
9255 8714                          cv_broadcast(&mpt->m_config_cv);
9256 8715                          cv_broadcast(&mpt->m_fw_diag_cv);
9257 8716                  } else {
9258 8717                          mptsas_doneq_add(mpt, cmd);
9259 8718                  }
9260 8719          }
     8720 +
     8721 +        /*
     8722 +         * Flush the tx_waitq
     8723 +         */
     8724 +        mutex_enter(&mpt->m_tx_waitq_mutex);
     8725 +        while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
     8726 +                mutex_exit(&mpt->m_tx_waitq_mutex);
     8727 +                mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
     8728 +                mptsas_doneq_add(mpt, cmd);
     8729 +                mutex_enter(&mpt->m_tx_waitq_mutex);
     8730 +        }
     8731 +        mutex_exit(&mpt->m_tx_waitq_mutex);
     8732 +
     8733 +        /*
     8734 +         * Drain the taskqs prior to reallocating resources.
     8735 +         */
     8736 +        mutex_exit(&mpt->m_mutex);
     8737 +        ddi_taskq_wait(mpt->m_event_taskq);
     8738 +        ddi_taskq_wait(mpt->m_dr_taskq);
     8739 +        mutex_enter(&mpt->m_mutex);
9261 8740  }
9262 8741  
9263 8742  /*
9264 8743   * set pkt_reason and OR in pkt_statistics flag
9265 8744   */
9266 8745  static void
9267 8746  mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
9268 8747      uint_t stat)
9269 8748  {
9270 8749  #ifndef __lock_lint
↓ open down ↓ 28 lines elided ↑ open up ↑
9299 8778  
9300 8779  static void
9301 8780  mptsas_setup_bus_reset_delay(mptsas_t *mpt)
9302 8781  {
9303 8782          mptsas_target_t *ptgt = NULL;
9304 8783  
9305 8784          NDBG22(("mptsas_setup_bus_reset_delay"));
9306 8785          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9307 8786              MPTSAS_HASH_FIRST);
9308 8787          while (ptgt != NULL) {
9309      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
9310 8788                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9311 8789                  ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
9312      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
9313 8790  
9314 8791                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9315 8792                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9316 8793          }
9317 8794  
9318 8795          mptsas_start_watch_reset_delay();
9319 8796  }
9320 8797  
9321 8798  /*
9322 8799   * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
↓ open down ↓ 37 lines elided ↑ open up ↑
9360 8837          int             restart = 0;
9361 8838          mptsas_target_t *ptgt = NULL;
9362 8839  
9363 8840          NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
9364 8841  
9365 8842          ASSERT(mutex_owned(&mpt->m_mutex));
9366 8843  
9367 8844          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9368 8845              MPTSAS_HASH_FIRST);
9369 8846          while (ptgt != NULL) {
9370      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
9371 8847                  if (ptgt->m_reset_delay != 0) {
9372 8848                          ptgt->m_reset_delay -=
9373 8849                              MPTSAS_WATCH_RESET_DELAY_TICK;
9374 8850                          if (ptgt->m_reset_delay <= 0) {
9375 8851                                  ptgt->m_reset_delay = 0;
9376 8852                                  mptsas_set_throttle(mpt, ptgt,
9377 8853                                      MAX_THROTTLE);
9378 8854                                  restart++;
9379 8855                          } else {
9380 8856                                  done = -1;
9381 8857                          }
9382 8858                  }
9383      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
9384 8859  
9385 8860                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9386 8861                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9387 8862          }
9388 8863  
9389 8864          if (restart > 0) {
9390 8865                  mptsas_restart_hba(mpt);
9391 8866          }
9392 8867          return (done);
9393 8868  }
↓ open down ↓ 75 lines elided ↑ open up ↑
9469 8944                          mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
9470 8945                              STAT_ABORTED);
9471 8946                          mptsas_doneq_add(mpt, sp);
9472 8947                          rval = TRUE;
9473 8948                          goto done;
9474 8949                  }
9475 8950  
9476 8951                  /*
9477 8952                   * Have mpt firmware abort this command
9478 8953                   */
9479      -                mutex_enter(&mpt->m_intr_mutex);
     8954 +
9480 8955                  if (slots->m_slot[sp->cmd_slot] != NULL) {
9481      -                        mutex_exit(&mpt->m_intr_mutex);
9482 8956                          rval = mptsas_ioc_task_management(mpt,
9483 8957                              MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
9484 8958                              lun, NULL, 0, 0);
9485 8959  
9486 8960                          /*
9487 8961                           * The transport layer expects only TRUE and FALSE.
9488 8962                           * Therefore, if mptsas_ioc_task_management returns
9489 8963                           * FAILED we will return FALSE.
9490 8964                           */
9491 8965                          if (rval == FAILED)
9492 8966                                  rval = FALSE;
9493 8967                          goto done;
9494 8968                  }
9495      -                mutex_exit(&mpt->m_intr_mutex);
9496 8969          }
9497 8970  
9498 8971          /*
9499 8972           * If pkt is NULL then abort task set
9500 8973           */
9501 8974          rval = mptsas_ioc_task_management(mpt,
9502 8975              MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0);
9503 8976  
9504 8977          /*
9505 8978           * The transport layer expects only TRUE and FALSE.
↓ open down ↓ 91 lines elided ↑ open up ↑
9597 9070  
9598 9071  /*
9599 9072   * (*tran_setcap).  Set the capability named to the value given.
9600 9073   */
9601 9074  static int
9602 9075  mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
9603 9076  {
9604 9077          mptsas_t        *mpt = ADDR2MPT(ap);
9605 9078          int             ckey;
9606 9079          int             rval = FALSE;
9607      -        mptsas_target_t *ptgt;
9608 9080  
9609 9081          NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
9610 9082              ap->a_target, cap, value, tgtonly));
9611 9083  
9612 9084          if (!tgtonly) {
9613 9085                  return (rval);
9614 9086          }
9615 9087  
9616 9088          mutex_enter(&mpt->m_mutex);
9617 9089  
↓ open down ↓ 19 lines elided ↑ open up ↑
9637 9109                  /*
9638 9110                   * We cannot turn off arq so return false if asked to
9639 9111                   */
9640 9112                  if (value) {
9641 9113                          rval = TRUE;
9642 9114                  } else {
9643 9115                          rval = FALSE;
9644 9116                  }
9645 9117                  break;
9646 9118          case SCSI_CAP_TAGGED_QING:
9647      -                ptgt = ((mptsas_tgt_private_t *)
9648      -                    (ap->a_hba_tran->tran_tgt_private))->t_private;
9649      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
9650      -                mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9651      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
     9119 +                mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
     9120 +                    (ap->a_hba_tran->tran_tgt_private))->t_private,
     9121 +                    MAX_THROTTLE);
9652 9122                  rval = TRUE;
9653 9123                  break;
9654 9124          case SCSI_CAP_QFULL_RETRIES:
9655 9125                  ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
9656 9126                      t_private->m_qfull_retries = (uchar_t)value;
9657 9127                  rval = TRUE;
9658 9128                  break;
9659 9129          case SCSI_CAP_QFULL_RETRY_INTERVAL:
9660 9130                  ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
9661 9131                      t_private->m_qfull_retry_interval =
↓ open down ↓ 23 lines elided ↑ open up ↑
9685 9155          *cidxp = scsi_hba_lookup_capstr(cap);
9686 9156          return (TRUE);
9687 9157  }
9688 9158  
9689 9159  static int
9690 9160  mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
9691 9161  {
9692 9162          mptsas_slots_t  *old_active = mpt->m_active;
9693 9163          mptsas_slots_t  *new_active;
9694 9164          size_t          size;
9695      -        int             rval = -1, nslot, i;
9696      -        mptsas_slot_free_e_t    *pe;
     9165 +        int             rval = -1, i;
9697 9166  
9698      -        if (mptsas_outstanding_cmds_n(mpt)) {
9699      -                NDBG9(("cannot change size of active slots array"));
9700      -                return (rval);
9701      -        }
     9167 +        /*
     9168 +         * if there are active commands, then we cannot
     9169 +         * change size of active slots array.
     9170 +         */
     9171 +        ASSERT(mpt->m_ncmds == 0);
9702 9172  
9703 9173          size = MPTSAS_SLOTS_SIZE(mpt);
9704 9174          new_active = kmem_zalloc(size, flag);
9705 9175          if (new_active == NULL) {
9706 9176                  NDBG1(("new active alloc failed"));
9707 9177                  return (rval);
9708 9178          }
9709 9179          /*
9710 9180           * Since SMID 0 is reserved and the TM slot is reserved, the
9711 9181           * number of slots that can be used at any one time is
9712 9182           * m_max_requests - 2.
9713 9183           */
9714      -        new_active->m_n_slots = nslot = (mpt->m_max_requests - 2);
     9184 +        new_active->m_n_slots = (mpt->m_max_requests - 2);
9715 9185          new_active->m_size = size;
9716 9186          new_active->m_tags = 1;
9717      -
9718 9187          if (old_active) {
9719 9188                  new_active->m_tgttbl = old_active->m_tgttbl;
9720 9189                  new_active->m_smptbl = old_active->m_smptbl;
9721 9190                  new_active->m_num_raid_configs =
9722 9191                      old_active->m_num_raid_configs;
9723 9192                  for (i = 0; i < new_active->m_num_raid_configs; i++) {
9724 9193                          new_active->m_raidconfig[i] =
9725 9194                              old_active->m_raidconfig[i];
9726 9195                  }
9727 9196                  mptsas_free_active_slots(mpt);
9728 9197          }
9729      -
9730      -        if (max_ncpus & (max_ncpus - 1)) {
9731      -                mpt->m_slot_freeq_pair_n = (1 << highbit(max_ncpus));
9732      -        } else {
9733      -                mpt->m_slot_freeq_pair_n = max_ncpus;
9734      -        }
9735      -        mpt->m_slot_freeq_pairp = kmem_zalloc(
9736      -            mpt->m_slot_freeq_pair_n *
9737      -            sizeof (mptsas_slot_freeq_pair_t), KM_SLEEP);
9738      -        for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) {
9739      -                list_create(&mpt->m_slot_freeq_pairp[i].
9740      -                    m_slot_allocq.s.m_fq_list,
9741      -                    sizeof (mptsas_slot_free_e_t),
9742      -                    offsetof(mptsas_slot_free_e_t, node));
9743      -                list_create(&mpt->m_slot_freeq_pairp[i].
9744      -                    m_slot_releq.s.m_fq_list,
9745      -                    sizeof (mptsas_slot_free_e_t),
9746      -                    offsetof(mptsas_slot_free_e_t, node));
9747      -                mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n = 0;
9748      -                mpt->m_slot_freeq_pairp[i].m_slot_releq.s.m_fq_n = 0;
9749      -                mutex_init(&mpt->m_slot_freeq_pairp[i].
9750      -                    m_slot_allocq.s.m_fq_mutex, NULL, MUTEX_DRIVER,
9751      -                    DDI_INTR_PRI(mpt->m_intr_pri));
9752      -                mutex_init(&mpt->m_slot_freeq_pairp[i].
9753      -                    m_slot_releq.s.m_fq_mutex, NULL, MUTEX_DRIVER,
9754      -                    DDI_INTR_PRI(mpt->m_intr_pri));
9755      -        }
9756      -        pe = mpt->m_slot_free_ae = kmem_zalloc(nslot *
9757      -            sizeof (mptsas_slot_free_e_t), KM_SLEEP);
9758      -        /*
9759      -         * An array of Mpi2ReplyDescriptorsUnion_t is defined here.
9760      -         * We are trying to eliminate the m_mutex in the context
9761      -         * reply code path in the ISR. Since the read of the
9762      -         * ReplyDescriptor and update/write of the ReplyIndex must
9763      -         * be atomic (since the poll thread may also update them at
9764      -         * the same time) so we first read out of the ReplyDescriptor
9765      -         * into this array and update the ReplyIndex register with a
9766      -         * separate mutex m_intr_mutex protected, and then release the
9767      -         * mutex and process all of them. the length of the array is
9768      -         * defined as max as 128(128*64=8k), which is
9769      -         * assumed as the maxmium depth of the interrupt coalese.
9770      -         */
9771      -        mpt->m_reply = kmem_zalloc(MPI_ADDRESS_COALSCE_MAX *
9772      -            sizeof (Mpi2ReplyDescriptorsUnion_t), KM_SLEEP);
9773      -        for (i = 0; i < nslot; i++, pe++) {
9774      -                pe->slot = i + 1; /* SMID 0 is reserved */
9775      -                pe->cpuid = i % mpt->m_slot_freeq_pair_n;
9776      -                list_insert_tail(&mpt->m_slot_freeq_pairp
9777      -                    [i % mpt->m_slot_freeq_pair_n]
9778      -                    .m_slot_allocq.s.m_fq_list, pe);
9779      -                mpt->m_slot_freeq_pairp[i % mpt->m_slot_freeq_pair_n]
9780      -                    .m_slot_allocq.s.m_fq_n++;
9781      -                mpt->m_slot_freeq_pairp[i % mpt->m_slot_freeq_pair_n]
9782      -                    .m_slot_allocq.s.m_fq_n_init++;
9783      -        }
9784      -
9785 9198          mpt->m_active = new_active;
9786 9199          rval = 0;
9787 9200  
9788 9201          return (rval);
9789 9202  }
9790 9203  
9791 9204  static void
9792 9205  mptsas_free_active_slots(mptsas_t *mpt)
9793 9206  {
9794 9207          mptsas_slots_t  *active = mpt->m_active;
9795 9208          size_t          size;
9796      -        mptsas_slot_free_e_t    *pe;
9797      -        int     i;
9798 9209  
9799 9210          if (active == NULL)
9800 9211                  return;
9801      -
9802      -        if (mpt->m_slot_freeq_pairp) {
9803      -                for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) {
9804      -                        while ((pe = list_head(&mpt->m_slot_freeq_pairp
9805      -                            [i].m_slot_allocq.s.m_fq_list)) != NULL) {
9806      -                                list_remove(&mpt->m_slot_freeq_pairp[i]
9807      -                                    .m_slot_allocq.s.m_fq_list, pe);
9808      -                        }
9809      -                        list_destroy(&mpt->m_slot_freeq_pairp
9810      -                            [i].m_slot_allocq.s.m_fq_list);
9811      -                        while ((pe = list_head(&mpt->m_slot_freeq_pairp
9812      -                            [i].m_slot_releq.s.m_fq_list)) != NULL) {
9813      -                                list_remove(&mpt->m_slot_freeq_pairp[i]
9814      -                                    .m_slot_releq.s.m_fq_list, pe);
9815      -                        }
9816      -                        list_destroy(&mpt->m_slot_freeq_pairp
9817      -                            [i].m_slot_releq.s.m_fq_list);
9818      -                        mutex_destroy(&mpt->m_slot_freeq_pairp
9819      -                            [i].m_slot_allocq.s.m_fq_mutex);
9820      -                        mutex_destroy(&mpt->m_slot_freeq_pairp
9821      -                            [i].m_slot_releq.s.m_fq_mutex);
9822      -                }
9823      -                kmem_free(mpt->m_slot_freeq_pairp, mpt->m_slot_freeq_pair_n *
9824      -                    sizeof (mptsas_slot_freeq_pair_t));
9825      -        }
9826      -        if (mpt->m_slot_free_ae)
9827      -                kmem_free(mpt->m_slot_free_ae, mpt->m_active->m_n_slots *
9828      -                    sizeof (mptsas_slot_free_e_t));
9829      -
9830      -        if (mpt->m_reply)
9831      -                kmem_free(mpt->m_reply, MPI_ADDRESS_COALSCE_MAX *
9832      -                    sizeof (Mpi2ReplyDescriptorsUnion_t));
9833      -
9834 9212          size = active->m_size;
9835 9213          kmem_free(active, size);
9836 9214          mpt->m_active = NULL;
9837 9215  }
9838 9216  
9839 9217  /*
9840 9218   * Error logging, printing, and debug print routines.
9841 9219   */
9842 9220  static char *mptsas_label = "mpt_sas";
9843 9221  
↓ open down ↓ 126 lines elided ↑ open up ↑
9970 9348  #ifdef MPTSAS_TEST
9971 9349          if (mptsas_enable_untagged) {
9972 9350                  mptsas_test_untagged++;
9973 9351          }
9974 9352  #endif
9975 9353  
9976 9354          /*
9977 9355           * Check for commands stuck in active slot
9978 9356           * Account for TM requests, which use the last SMID.
9979 9357           */
9980      -        mutex_enter(&mpt->m_intr_mutex);
9981 9358          for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
9982 9359                  if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9983 9360                          if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9984 9361                                  cmd->cmd_active_timeout -=
9985 9362                                      mptsas_scsi_watchdog_tick;
9986 9363                                  if (cmd->cmd_active_timeout <= 0) {
9987 9364                                          /*
9988 9365                                           * There seems to be a command stuck
9989 9366                                           * in the active slot.  Drain throttle.
9990 9367                                           */
9991      -                                        ptgt = cmd->cmd_tgt_addr;
9992      -                                        mutex_enter(&ptgt->m_tgt_intr_mutex);
9993      -                                        mptsas_set_throttle(mpt, ptgt,
     9368 +                                        mptsas_set_throttle(mpt,
     9369 +                                            cmd->cmd_tgt_addr,
9994 9370                                              DRAIN_THROTTLE);
9995      -                                        mutex_exit(&ptgt->m_tgt_intr_mutex);
9996 9371                                  }
9997 9372                          }
9998 9373                          if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9999 9374                              (cmd->cmd_flags & CFLAG_CONFIG) ||
10000 9375                              (cmd->cmd_flags & CFLAG_FW_DIAG)) {
10001 9376                                  cmd->cmd_active_timeout -=
10002 9377                                      mptsas_scsi_watchdog_tick;
10003 9378                                  if (cmd->cmd_active_timeout <= 0) {
10004 9379                                          /*
10005 9380                                           * passthrough command timeout
10006 9381                                           */
10007 9382                                          cmd->cmd_flags |= (CFLAG_FINISHED |
10008 9383                                              CFLAG_TIMEOUT);
10009 9384                                          cv_broadcast(&mpt->m_passthru_cv);
10010 9385                                          cv_broadcast(&mpt->m_config_cv);
10011 9386                                          cv_broadcast(&mpt->m_fw_diag_cv);
10012 9387                                  }
10013 9388                          }
10014 9389                  }
10015 9390          }
10016      -        mutex_exit(&mpt->m_intr_mutex);
10017 9391  
10018 9392          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
10019 9393              MPTSAS_HASH_FIRST);
10020 9394          while (ptgt != NULL) {
10021 9395                  /*
10022      -                 * In order to avoid using m_mutex in the key code path in ISR,
10023      -                 * separate mutexs are introduced to protect those elements
10024      -                 * shown in ISR.
10025      -                 */
10026      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
10027      -
10028      -                /*
10029 9396                   * If we were draining due to a qfull condition,
10030 9397                   * go back to full throttle.
10031 9398                   */
10032 9399                  if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
10033 9400                      (ptgt->m_t_throttle > HOLD_THROTTLE) &&
10034 9401                      (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
10035 9402                          mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10036 9403                          mptsas_restart_hba(mpt);
10037 9404                  }
10038 9405  
10039 9406                  if ((ptgt->m_t_ncmds > 0) &&
10040 9407                      (ptgt->m_timebase)) {
10041 9408  
10042 9409                          if (ptgt->m_timebase <=
10043 9410                              mptsas_scsi_watchdog_tick) {
10044 9411                                  ptgt->m_timebase +=
10045 9412                                      mptsas_scsi_watchdog_tick;
10046      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
10047 9413                                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10048 9414                                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10049 9415                                  continue;
10050 9416                          }
10051 9417  
10052 9418                          ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
10053 9419  
     9420 +                        if (ptgt->m_timeout_count > 0) {
     9421 +                                ptgt->m_timeout_interval +=
     9422 +                                    mptsas_scsi_watchdog_tick;
     9423 +                        }
     9424 +                        if (ptgt->m_timeout_interval >
     9425 +                            mptsas_timeout_interval) {
     9426 +                                ptgt->m_timeout_interval = 0;
     9427 +                                ptgt->m_timeout_count = 0;
     9428 +                        }
     9429 +
10054 9430                          if (ptgt->m_timeout < 0) {
10055      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
10056      -                                mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
     9431 +                                ptgt->m_timeout_count++;
     9432 +                                if (ptgt->m_timeout_count >
     9433 +                                    mptsas_timeout_threshold) {
     9434 +                                        ptgt->m_timeout_count = 0;
     9435 +                                        mptsas_kill_target(mpt, ptgt);
     9436 +                                } else {
     9437 +                                        mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
     9438 +                                }
10057 9439                                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10058 9440                                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10059 9441                                  continue;
10060 9442                          }
10061 9443  
10062 9444                          if ((ptgt->m_timeout) <=
10063 9445                              mptsas_scsi_watchdog_tick) {
10064 9446                                  NDBG23(("pending timeout"));
10065 9447                                  mptsas_set_throttle(mpt, ptgt,
10066 9448                                      DRAIN_THROTTLE);
10067 9449                          }
10068 9450                  }
10069      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
     9451 +
10070 9452                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10071 9453                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10072 9454          }
10073 9455  }
10074 9456  
10075 9457  /*
10076 9458   * timeout recovery
10077 9459   */
10078 9460  static void
10079 9461  mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
↓ open down ↓ 8 lines elided ↑ open up ↑
10088 9470           * try to reset that target.
10089 9471           */
10090 9472          NDBG29(("mptsas_cmd_timeout: device reset"));
10091 9473          if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
10092 9474                  mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
10093 9475                      "recovery failed!", devhdl);
10094 9476          }
10095 9477  }
10096 9478  
10097 9479  /*
     9480 + * target causing too many timeouts
     9481 + */
     9482 +static void
     9483 +mptsas_kill_target(mptsas_t *mpt, mptsas_target_t *ptgt)
     9484 +{
     9485 +        mptsas_topo_change_list_t       *topo_node = NULL;
     9486 +
     9487 +        NDBG29(("mptsas_tgt_kill: target=%d", ptgt->m_devhdl));
     9488 +        mptsas_log(mpt, CE_WARN, "timeout threshold exceeded for "
     9489 +            "Target %d", ptgt->m_devhdl);
     9490 +
     9491 +        topo_node = kmem_zalloc(sizeof (mptsas_topo_change_list_t), KM_SLEEP);
     9492 +        topo_node->mpt = mpt;
     9493 +        topo_node->un.phymask = ptgt->m_phymask;
     9494 +        topo_node->event = MPTSAS_DR_EVENT_OFFLINE_TARGET;
     9495 +        topo_node->devhdl = ptgt->m_devhdl;
     9496 +        if (ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
     9497 +                topo_node->flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
     9498 +        else
     9499 +                topo_node->flags = MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
     9500 +        topo_node->object = NULL;
     9501 +
     9502 +        /*
     9503 +         * Launch DR taskq to fake topology change
     9504 +         */
     9505 +        if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
     9506 +            mptsas_handle_dr, (void *)topo_node,
     9507 +            DDI_NOSLEEP)) != DDI_SUCCESS) {
     9508 +                mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
     9509 +                    "for fake offline event failed. \n");
     9510 +        }
     9511 +}
     9512 +
     9513 +/*
10098 9514   * Device / Hotplug control
10099 9515   */
10100 9516  static int
10101 9517  mptsas_scsi_quiesce(dev_info_t *dip)
10102 9518  {
10103 9519          mptsas_t        *mpt;
10104 9520          scsi_hba_tran_t *tran;
10105 9521  
10106 9522          tran = ddi_get_driver_private(dip);
10107 9523          if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
↓ open down ↓ 20 lines elided ↑ open up ↑
10128 9544  {
10129 9545          mptsas_target_t *ptgt = NULL;
10130 9546  
10131 9547          NDBG28(("mptsas_quiesce_bus"));
10132 9548          mutex_enter(&mpt->m_mutex);
10133 9549  
10134 9550          /* Set all the throttles to zero */
10135 9551          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
10136 9552              MPTSAS_HASH_FIRST);
10137 9553          while (ptgt != NULL) {
10138      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
10139 9554                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10140      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
10141 9555  
10142 9556                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10143 9557                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10144 9558          }
10145 9559  
10146 9560          /* If there are any outstanding commands in the queue */
10147      -        mutex_enter(&mpt->m_intr_mutex);
10148      -        if (mptsas_outstanding_cmds_n(mpt)) {
10149      -                mutex_exit(&mpt->m_intr_mutex);
     9561 +        if (mpt->m_ncmds) {
10150 9562                  mpt->m_softstate |= MPTSAS_SS_DRAINING;
10151 9563                  mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10152 9564                      mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
10153 9565                  if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
10154 9566                          /*
10155 9567                           * Quiesce has been interrupted
10156 9568                           */
10157 9569                          mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10158 9570                          ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10159 9571                              &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
10160 9572                          while (ptgt != NULL) {
10161      -                                mutex_enter(&ptgt->m_tgt_intr_mutex);
10162 9573                                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10163      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
10164 9574  
10165 9575                                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10166 9576                                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10167 9577                          }
10168 9578                          mptsas_restart_hba(mpt);
10169 9579                          if (mpt->m_quiesce_timeid != 0) {
10170 9580                                  timeout_id_t tid = mpt->m_quiesce_timeid;
10171 9581                                  mpt->m_quiesce_timeid = 0;
10172 9582                                  mutex_exit(&mpt->m_mutex);
10173 9583                                  (void) untimeout(tid);
↓ open down ↓ 3 lines elided ↑ open up ↑
10177 9587                          return (-1);
10178 9588                  } else {
10179 9589                          /* Bus has been quiesced */
10180 9590                          ASSERT(mpt->m_quiesce_timeid == 0);
10181 9591                          mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
10182 9592                          mpt->m_softstate |= MPTSAS_SS_QUIESCED;
10183 9593                          mutex_exit(&mpt->m_mutex);
10184 9594                          return (0);
10185 9595                  }
10186 9596          }
10187      -        mutex_exit(&mpt->m_intr_mutex);
10188 9597          /* Bus was not busy - QUIESCED */
10189 9598          mutex_exit(&mpt->m_mutex);
10190 9599  
10191 9600          return (0);
10192 9601  }
10193 9602  
10194 9603  static int
10195 9604  mptsas_unquiesce_bus(mptsas_t *mpt)
10196 9605  {
10197 9606          mptsas_target_t *ptgt = NULL;
10198 9607  
10199 9608          NDBG28(("mptsas_unquiesce_bus"));
10200 9609          mutex_enter(&mpt->m_mutex);
10201 9610          mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
10202 9611          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
10203 9612              MPTSAS_HASH_FIRST);
10204 9613          while (ptgt != NULL) {
10205      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
10206 9614                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10207      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
10208 9615  
10209 9616                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10210 9617                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10211 9618          }
10212 9619          mptsas_restart_hba(mpt);
10213 9620          mutex_exit(&mpt->m_mutex);
10214 9621          return (0);
10215 9622  }
10216 9623  
10217 9624  static void
10218 9625  mptsas_ncmds_checkdrain(void *arg)
10219 9626  {
10220 9627          mptsas_t        *mpt = arg;
10221 9628          mptsas_target_t *ptgt = NULL;
10222 9629  
10223 9630          mutex_enter(&mpt->m_mutex);
10224 9631          if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
10225 9632                  mpt->m_quiesce_timeid = 0;
10226      -                mutex_enter(&mpt->m_intr_mutex);
10227      -                if (mptsas_outstanding_cmds_n(mpt)) {
10228      -                        mutex_exit(&mpt->m_intr_mutex);
     9633 +                if (mpt->m_ncmds == 0) {
     9634 +                        /* Command queue has been drained */
     9635 +                        cv_signal(&mpt->m_cv);
     9636 +                } else {
10229 9637                          /*
10230 9638                           * The throttle may have been reset because
10231 9639                           * of a SCSI bus reset
10232 9640                           */
10233 9641                          ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10234 9642                              &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
10235 9643                          while (ptgt != NULL) {
10236      -                                mutex_enter(&ptgt->m_tgt_intr_mutex);
10237 9644                                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10238      -                                mutex_exit(&ptgt->m_tgt_intr_mutex);
10239 9645  
10240 9646                                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10241 9647                                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10242 9648                          }
10243 9649  
10244 9650                          mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
10245 9651                              mpt, (MPTSAS_QUIESCE_TIMEOUT *
10246 9652                              drv_usectohz(1000000)));
10247      -                } else {
10248      -                        mutex_exit(&mpt->m_intr_mutex);
10249      -                        /* Command queue has been drained */
10250      -                        cv_signal(&mpt->m_cv);
10251 9653                  }
10252 9654          }
10253 9655          mutex_exit(&mpt->m_mutex);
10254 9656  }
10255 9657  
10256 9658  /*ARGSUSED*/
10257 9659  static void
10258 9660  mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
10259 9661  {
10260 9662          int     i;
↓ open down ↓ 143 lines elided ↑ open up ↑
10404 9806          }
10405 9807  
10406 9808          /*
10407 9809           * We must wait till the message has been completed before
10408 9810           * beginning the next message so we wait for this one to
10409 9811           * finish.
10410 9812           */
10411 9813          (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
10412 9814          request_desc_low = (cmd->cmd_slot << 16) + desc_type;
10413 9815          cmd->cmd_rfm = NULL;
10414      -        mpt->m_active->m_slot[cmd->cmd_slot] = cmd;
10415 9816          MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
10416 9817          if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
10417 9818              (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
10418 9819                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10419 9820          }
10420 9821  }
10421 9822  
10422 9823  
10423 9824  
10424 9825  static int
↓ open down ↓ 410 lines elided ↑ open up ↑
10835 10236          }
10836 10237  
10837 10238          /*
10838 10239           * Send the message
10839 10240           */
10840 10241          (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
10841 10242              DDI_DMA_SYNC_FORDEV);
10842 10243          request_desc_low = (cmd->cmd_slot << 16) +
10843 10244              MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
10844 10245          cmd->cmd_rfm = NULL;
10845      -        mpt->m_active->m_slot[cmd->cmd_slot] = cmd;
10846 10246          MPTSAS_START_CMD(mpt, request_desc_low, 0);
10847 10247          if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
10848 10248              DDI_SUCCESS) ||
10849 10249              (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
10850 10250              DDI_SUCCESS)) {
10851 10251                  ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10852 10252          }
10853 10253  }
10854 10254  
10855 10255  static int
↓ open down ↓ 1102 lines elided ↑ open up ↑
11958 11358          mptsas_t                *mpt;
11959 11359          mptsas_update_flash_t   flashdata;
11960 11360          mptsas_pass_thru_t      passthru_data;
11961 11361          mptsas_adapter_data_t   adapter_data;
11962 11362          mptsas_pci_info_t       pci_info;
11963 11363          int                     copylen;
11964 11364  
11965 11365          int                     iport_flag = 0;
11966 11366          dev_info_t              *dip = NULL;
11967 11367          mptsas_phymask_t        phymask = 0;
11968      -        struct devctl_iocdata   *dcp = NULL;
11969      -        uint32_t                slotstatus = 0;
11970      -        char                    *addr = NULL;
11971      -        mptsas_target_t         *ptgt = NULL;
11972 11368  
11973 11369          *rval = MPTIOCTL_STATUS_GOOD;
11974 11370          if (secpolicy_sys_config(credp, B_FALSE) != 0) {
11975 11371                  return (EPERM);
11976 11372          }
11977 11373  
11978 11374          mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
11979 11375          if (mpt == NULL) {
11980 11376                  /*
11981 11377                   * Called from iport node, get the states
↓ open down ↓ 21 lines elided ↑ open up ↑
12003 11399                          }
12004 11400                  } else {
12005 11401                          mutex_exit(&mpt->m_mutex);
12006 11402                  }
12007 11403          } else {
12008 11404                  mutex_exit(&mpt->m_mutex);
12009 11405          }
12010 11406  
12011 11407          if (iport_flag) {
12012 11408                  status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval);
12013      -                if (status != 0) {
12014      -                        goto out;
12015      -                }
12016      -                /*
12017      -                 * The following code control the OK2RM LED, it doesn't affect
12018      -                 * the ioctl return status.
12019      -                 */
12020      -                if ((cmd == DEVCTL_DEVICE_ONLINE) ||
12021      -                    (cmd == DEVCTL_DEVICE_OFFLINE)) {
12022      -                        if (ndi_dc_allochdl((void *)data, &dcp) !=
12023      -                            NDI_SUCCESS) {
12024      -                                goto out;
12025      -                        }
12026      -                        addr = ndi_dc_getaddr(dcp);
12027      -                        ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12028      -                        if (ptgt == NULL) {
12029      -                                NDBG14(("mptsas_ioctl led control: tgt %s not "
12030      -                                    "found", addr));
12031      -                                ndi_dc_freehdl(dcp);
12032      -                                goto out;
12033      -                        }
12034      -                        mutex_enter(&mpt->m_mutex);
12035      -                        if (cmd == DEVCTL_DEVICE_ONLINE) {
12036      -                                ptgt->m_tgt_unconfigured = 0;
12037      -                        } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12038      -                                ptgt->m_tgt_unconfigured = 1;
12039      -                        }
12040      -                        slotstatus = 0;
12041      -#ifdef MPTSAS_GET_LED
12042      -                        /*
12043      -                         * The get led status can't get a valid/reasonable
12044      -                         * state, so ignore the get led status, and write the
12045      -                         * required value directly
12046      -                         */
12047      -                        if (mptsas_get_led_status(mpt, ptgt, &slotstatus) !=
12048      -                            DDI_SUCCESS) {
12049      -                                NDBG14(("mptsas_ioctl: get LED for tgt %s "
12050      -                                    "failed %x", addr, slotstatus));
12051      -                                slotstatus = 0;
12052      -                        }
12053      -                        NDBG14(("mptsas_ioctl: LED status %x for %s",
12054      -                            slotstatus, addr));
12055      -#endif
12056      -                        if (cmd == DEVCTL_DEVICE_OFFLINE) {
12057      -                                slotstatus |=
12058      -                                    MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12059      -                        } else {
12060      -                                slotstatus &=
12061      -                                    ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12062      -                        }
12063      -                        if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
12064      -                            DDI_SUCCESS) {
12065      -                                NDBG14(("mptsas_ioctl: set LED for tgt %s "
12066      -                                    "failed %x", addr, slotstatus));
12067      -                        }
12068      -                        mutex_exit(&mpt->m_mutex);
12069      -                        ndi_dc_freehdl(dcp);
12070      -                }
12071 11409                  goto out;
12072 11410          }
12073 11411          switch (cmd) {
12074 11412                  case MPTIOCTL_UPDATE_FLASH:
12075 11413                          if (ddi_copyin((void *)data, &flashdata,
12076 11414                                  sizeof (struct mptsas_update_flash), mode)) {
12077 11415                                  status = EFAULT;
12078 11416                                  break;
12079 11417                          }
12080 11418  
↓ open down ↓ 137 lines elided ↑ open up ↑
12218 11556                          status = mptsas_reg_access(mpt,
12219 11557                              (mptsas_reg_access_t *)data, mode);
12220 11558                          break;
12221 11559                  default:
12222 11560                          status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
12223 11561                              rval);
12224 11562                          break;
12225 11563          }
12226 11564  
12227 11565  out:
12228      -        if (mpt->m_options & MPTSAS_OPT_PM)
12229      -                (void) pm_idle_component(mpt->m_dip, 0);
12230 11566          return (status);
12231 11567  }
12232 11568  
12233 11569  int
12234 11570  mptsas_restart_ioc(mptsas_t *mpt)
12235 11571  {
12236 11572          int             rval = DDI_SUCCESS;
12237 11573          mptsas_target_t *ptgt = NULL;
12238 11574  
12239 11575          ASSERT(mutex_owned(&mpt->m_mutex));
↓ open down ↓ 6 lines elided ↑ open up ↑
12246 11582           * so that they can be retried.
12247 11583           */
12248 11584          mpt->m_in_reset = TRUE;
12249 11585  
12250 11586          /*
12251 11587           * Set all throttles to HOLD
12252 11588           */
12253 11589          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12254 11590              MPTSAS_HASH_FIRST);
12255 11591          while (ptgt != NULL) {
12256      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
12257 11592                  mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
12258      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
12259 11593  
12260 11594                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
12261 11595                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
12262 11596          }
12263 11597  
12264 11598          /*
12265 11599           * Disable interrupts
12266 11600           */
12267 11601          MPTSAS_DISABLE_INTR(mpt);
12268 11602  
12269 11603          /*
12270      -         * Abort all commands: outstanding commands, commands in waitq
     11604 +         * Abort all commands: outstanding commands, commands in waitq and
     11605 +         * tx_waitq.
12271 11606           */
12272 11607          mptsas_flush_hba(mpt);
12273 11608  
12274 11609          /*
12275 11610           * Reinitialize the chip.
12276 11611           */
12277 11612          if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
12278 11613                  rval = DDI_FAILURE;
12279 11614          }
12280 11615  
↓ open down ↓ 8 lines elided ↑ open up ↑
12289 11624          if (rval == DDI_SUCCESS) {
12290 11625                  mptsas_update_driver_data(mpt);
12291 11626          }
12292 11627  
12293 11628          /*
12294 11629           * Reset the throttles
12295 11630           */
12296 11631          ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12297 11632              MPTSAS_HASH_FIRST);
12298 11633          while (ptgt != NULL) {
12299      -                mutex_enter(&ptgt->m_tgt_intr_mutex);
12300 11634                  mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
12301      -                mutex_exit(&ptgt->m_tgt_intr_mutex);
12302 11635  
12303 11636                  ptgt = (mptsas_target_t *)mptsas_hash_traverse(
12304 11637                      &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
12305 11638          }
12306 11639  
12307 11640          mptsas_doneq_empty(mpt);
12308 11641          mptsas_restart_hba(mpt);
12309 11642  
12310 11643          if (rval != DDI_SUCCESS) {
12311 11644                  mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
↓ open down ↓ 289 lines elided ↑ open up ↑
12601 11934          if (!(mpt->m_options & MPTSAS_OPT_PM))
12602 11935                  return (DDI_SUCCESS);
12603 11936          /*
12604 11937           * If power management is supported by this chip, create
12605 11938           * pm-components property for the power management framework
12606 11939           */
12607 11940          (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
12608 11941          pmc[0] = pmc_name;
12609 11942          if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
12610 11943              "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
12611      -                mutex_enter(&mpt->m_intr_mutex);
12612 11944                  mpt->m_options &= ~MPTSAS_OPT_PM;
12613      -                mutex_exit(&mpt->m_intr_mutex);
12614 11945                  mptsas_log(mpt, CE_WARN,
12615 11946                      "mptsas%d: pm-component property creation failed.",
12616 11947                      mpt->m_instance);
12617 11948                  return (DDI_FAILURE);
12618 11949          }
12619 11950  
12620 11951          /*
12621 11952           * Power on device.
12622 11953           */
12623 11954          (void) pm_busy_component(mpt->m_dip, 0);
↓ open down ↓ 2 lines elided ↑ open up ↑
12626 11957          if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
12627 11958                  mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
12628 11959                      mpt->m_instance);
12629 11960                  pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
12630 11961                      PCI_PMCSR_D0);
12631 11962          }
12632 11963          if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
12633 11964                  mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
12634 11965                  return (DDI_FAILURE);
12635 11966          }
12636      -        mutex_enter(&mpt->m_intr_mutex);
12637 11967          mpt->m_power_level = PM_LEVEL_D0;
12638      -        mutex_exit(&mpt->m_intr_mutex);
12639 11968          /*
12640 11969           * Set pm idle delay.
12641 11970           */
12642 11971          mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
12643 11972              mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
12644 11973  
12645 11974          return (DDI_SUCCESS);
12646 11975  }
12647 11976  
12648 11977  static int
↓ open down ↓ 68 lines elided ↑ open up ↑
12717 12046  
12718 12047          /* Get number of available interrupts */
12719 12048          ret = ddi_intr_get_navail(dip, intr_type, &avail);
12720 12049          if ((ret != DDI_SUCCESS) || (avail == 0)) {
12721 12050                  mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
12722 12051                      "ret %d avail %d\n", ret, avail);
12723 12052  
12724 12053                  return (DDI_FAILURE);
12725 12054          }
12726 12055  
12727      -        if (avail < count) {
     12056 +        if (0 && avail < count) {
12728 12057                  mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
12729 12058                      "navail() returned %d", count, avail);
12730 12059          }
12731 12060  
12732 12061          /* Mpt only have one interrupt routine */
12733 12062          if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
12734 12063                  count = 1;
12735 12064          }
12736 12065  
12737 12066          /* Allocate an array of interrupt handles */
↓ open down ↓ 331 lines elided ↑ open up ↑
13069 12398                  mutex_enter(&mpt->m_mutex);
13070 12399                  if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
13071 12400                          sas_wwn = devicename;
13072 12401                  } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
13073 12402                          sas_wwn = 0;
13074 12403                  }
13075 12404          }
13076 12405  
13077 12406          phymask = mptsas_physport_to_phymask(mpt, physport);
13078 12407          *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
13079      -            dev_info, phymask, phynum, mpt);
     12408 +            dev_info, phymask, phynum);
13080 12409          if (*pptgt == NULL) {
13081 12410                  mptsas_log(mpt, CE_WARN, "Failed to allocated target"
13082 12411                      "structure!");
13083 12412                  rval = DEV_INFO_FAIL_ALLOC;
13084 12413                  return (rval);
13085 12414          }
13086 12415          (*pptgt)->m_enclosure = enclosure;
13087 12416          (*pptgt)->m_slot_num = bay_num;
13088 12417          return (DEV_INFO_SUCCESS);
13089 12418  }
↓ open down ↓ 1433 lines elided ↑ open up ↑
14523 13852                      MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
14524 13853                          if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14525 13854                                  /*
14526 13855                                   * Same path back online again.
14527 13856                                   */
14528 13857                                  (void) ddi_prop_free(old_guid);
14529 13858                                  if ((!MDI_PI_IS_ONLINE(*pip)) &&
14530 13859                                      (!MDI_PI_IS_STANDBY(*pip)) &&
14531 13860                                      (ptgt->m_tgt_unconfigured == 0)) {
14532 13861                                          rval = mdi_pi_online(*pip, 0);
14533      -                                        mutex_enter(&mpt->m_mutex);
14534      -                                        (void) mptsas_set_led_status(mpt, ptgt,
14535      -                                            0);
14536      -                                        mutex_exit(&mpt->m_mutex);
14537 13862                                  } else {
14538 13863                                          rval = DDI_SUCCESS;
14539 13864                                  }
14540 13865                                  if (rval != DDI_SUCCESS) {
14541 13866                                          mptsas_log(mpt, CE_WARN, "path:target: "
14542 13867                                              "%x, lun:%x online failed!", target,
14543 13868                                              lun);
14544 13869                                          *pip = NULL;
14545 13870                                          *lun_dip = NULL;
14546 13871                                  }
↓ open down ↓ 233 lines elided ↑ open up ↑
14780 14105                  if (mdi_prop_update_int(*pip, "phy-num",
14781 14106                      ptgt->m_phynum) != DDI_SUCCESS) {
14782 14107                          mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14783 14108                              "create phy-num property for target %d lun %d",
14784 14109                              target, lun);
14785 14110                          mdi_rtn = MDI_FAILURE;
14786 14111                          goto virt_create_done;
14787 14112                  }
14788 14113                  NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
14789 14114                  mdi_rtn = mdi_pi_online(*pip, 0);
14790      -                if (mdi_rtn == MDI_SUCCESS) {
14791      -                        mutex_enter(&mpt->m_mutex);
14792      -                        if (mptsas_set_led_status(mpt, ptgt, 0) !=
14793      -                            DDI_SUCCESS) {
14794      -                                NDBG14(("mptsas: clear LED for slot %x "
14795      -                                    "failed", ptgt->m_slot_num));
14796      -                        }
14797      -                        mutex_exit(&mpt->m_mutex);
14798      -                }
14799 14115                  if (mdi_rtn == MDI_NOT_SUPPORTED) {
14800 14116                          mdi_rtn = MDI_FAILURE;
14801 14117                  }
14802 14118  virt_create_done:
14803 14119                  if (*pip && mdi_rtn != MDI_SUCCESS) {
14804 14120                          (void) mdi_pi_free(*pip, 0);
14805 14121                          *pip = NULL;
14806 14122                          *lun_dip = NULL;
14807 14123                  }
14808 14124          }
↓ open down ↓ 333 lines elided ↑ open up ↑
15142 14458  phys_create_done:
15143 14459                  /*
15144 14460                   * If props were setup ok, online the lun
15145 14461                   */
15146 14462                  if (ndi_rtn == NDI_SUCCESS) {
15147 14463                          /*
15148 14464                           * Try to online the new node
15149 14465                           */
15150 14466                          ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15151 14467                  }
15152      -                if (ndi_rtn == NDI_SUCCESS) {
15153      -                        mutex_enter(&mpt->m_mutex);
15154      -                        if (mptsas_set_led_status(mpt, ptgt, 0) !=
15155      -                            DDI_SUCCESS) {
15156      -                                NDBG14(("mptsas: clear LED for tgt %x "
15157      -                                    "failed", ptgt->m_slot_num));
15158      -                        }
15159      -                        mutex_exit(&mpt->m_mutex);
15160      -                }
15161 14468  
15162 14469                  /*
15163 14470                   * If success set rtn flag, else unwire alloc'd lun
15164 14471                   */
15165 14472                  if (ndi_rtn != NDI_SUCCESS) {
15166 14473                          NDBG12(("mptsas driver unable to online "
15167 14474                              "target %d lun %d", target, lun));
15168 14475                          ndi_prop_remove_all(*lun_dip);
15169 14476                          (void) ndi_devi_free(*lun_dip);
15170 14477                          *lun_dip = NULL;
↓ open down ↓ 606 lines elided ↑ open up ↑
15777 15084                  if (data->devhdl == devhdl) {
15778 15085                          break;
15779 15086                  }
15780 15087                  data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
15781 15088          }
15782 15089          return (data);
15783 15090  }
15784 15091  
15785 15092  mptsas_target_t *
15786 15093  mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
15787      -    uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum, mptsas_t *mpt)
     15094 +    uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
15788 15095  {
15789 15096          mptsas_target_t *tmp_tgt = NULL;
15790 15097  
15791 15098          tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
15792 15099          if (tmp_tgt != NULL) {
15793 15100                  NDBG20(("Hash item already exist"));
15794 15101                  tmp_tgt->m_deviceinfo = devinfo;
15795 15102                  tmp_tgt->m_devhdl = devhdl;
15796 15103                  return (tmp_tgt);
15797 15104          }
↓ open down ↓ 5 lines elided ↑ open up ↑
15803 15110          tmp_tgt->m_devhdl = devhdl;
15804 15111          tmp_tgt->m_sas_wwn = wwid;
15805 15112          tmp_tgt->m_deviceinfo = devinfo;
15806 15113          tmp_tgt->m_phymask = phymask;
15807 15114          tmp_tgt->m_phynum = phynum;
15808 15115          /* Initialized the tgt structure */
15809 15116          tmp_tgt->m_qfull_retries = QFULL_RETRIES;
15810 15117          tmp_tgt->m_qfull_retry_interval =
15811 15118              drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
15812 15119          tmp_tgt->m_t_throttle = MAX_THROTTLE;
15813      -        mutex_init(&tmp_tgt->m_tgt_intr_mutex, NULL, MUTEX_DRIVER,
15814      -            DDI_INTR_PRI(mpt->m_intr_pri));
15815 15120  
15816 15121          mptsas_hash_add(hashtab, tmp_tgt);
15817 15122  
15818 15123          return (tmp_tgt);
15819 15124  }
15820 15125  
15821 15126  static void
15822 15127  mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
15823 15128      mptsas_phymask_t phymask)
15824 15129  {
15825 15130          mptsas_target_t *tmp_tgt;
15826 15131          tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
15827 15132          if (tmp_tgt == NULL) {
15828 15133                  cmn_err(CE_WARN, "Tgt not found, nothing to free");
15829 15134          } else {
15830      -                mutex_destroy(&tmp_tgt->m_tgt_intr_mutex);
15831 15135                  kmem_free(tmp_tgt, sizeof (struct mptsas_target));
15832 15136          }
15833 15137  }
15834 15138  
15835 15139  /*
15836 15140   * Return the entry in the hash table
15837 15141   */
15838 15142  static mptsas_smp_t *
15839 15143  mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
15840 15144  {
↓ open down ↓ 186 lines elided ↑ open up ↑
16027 15331          int             prop;
16028 15332          dip = e_ddi_hold_devi_by_dev(dev, 0);
16029 15333          if (dip == NULL)
16030 15334                  return (dip);
16031 15335          prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
16032 15336              "phymask", 0);
16033 15337          *phymask = (mptsas_phymask_t)prop;
16034 15338          ddi_release_devi(dip);
16035 15339          return (dip);
16036 15340  }
16037      -static mptsas_target_t *
16038      -mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16039      -{
16040      -        uint8_t                 phynum;
16041      -        uint64_t                wwn;
16042      -        int                     lun;
16043      -        mptsas_target_t         *ptgt = NULL;
16044 15341  
16045      -        if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
16046      -                return (NULL);
16047      -        }
16048      -        if (addr[0] == 'w') {
16049      -                ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16050      -        } else {
16051      -                ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16052      -        }
16053      -        return (ptgt);
16054      -}
16055      -
16056      -#ifdef MPTSAS_GET_LED
16057      -static int
16058      -mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
16059      -    uint32_t *slotstatus)
16060      -{
16061      -        return (mptsas_send_sep(mpt, ptgt, slotstatus,
16062      -            MPI2_SEP_REQ_ACTION_READ_STATUS));
16063      -}
16064      -#endif
16065      -static int
16066      -mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus)
16067      -{
16068      -        NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16069      -            slotstatus, ptgt->m_slot_num));
16070      -        return (mptsas_send_sep(mpt, ptgt, &slotstatus,
16071      -            MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16072      -}
16073      -/*
16074      - *  send sep request, use enclosure/slot addressing
16075      - */
16076      -static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
16077      -    uint32_t *status, uint8_t act)
16078      -{
16079      -        Mpi2SepRequest_t        req;
16080      -        Mpi2SepReply_t          rep;
16081      -        int                     ret;
16082      -
16083      -        ASSERT(mutex_owned(&mpt->m_mutex));
16084      -
16085      -        bzero(&req, sizeof (req));
16086      -        bzero(&rep, sizeof (rep));
16087      -
16088      -        /* Do nothing for RAID volumes */
16089      -        if (ptgt->m_phymask == 0) {
16090      -                NDBG14(("mptsas_send_sep: Skip RAID volumes"));
16091      -                return (DDI_FAILURE);
16092      -        }
16093      -
16094      -        req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
16095      -        req.Action = act;
16096      -        req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
16097      -        req.EnclosureHandle = LE_16(ptgt->m_enclosure);
16098      -        req.Slot = LE_16(ptgt->m_slot_num);
16099      -        if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16100      -                req.SlotStatus = LE_32(*status);
16101      -        }
16102      -        ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
16103      -            sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
16104      -        if (ret != 0) {
16105      -                mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
16106      -                    "Processor Request message error %d", ret);
16107      -                return (DDI_FAILURE);
16108      -        }
16109      -        /* do passthrough success, check the ioc status */
16110      -        if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
16111      -                if ((LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) ==
16112      -                    MPI2_IOCSTATUS_INVALID_FIELD) {
16113      -                        mptsas_log(mpt, CE_NOTE, "send sep act %x: Not "
16114      -                            "supported action, loginfo %x", act,
16115      -                            LE_32(rep.IOCLogInfo));
16116      -                        return (DDI_FAILURE);
16117      -                }
16118      -                mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc "
16119      -                    "status:%x", act, LE_16(rep.IOCStatus));
16120      -                return (DDI_FAILURE);
16121      -        }
16122      -        if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
16123      -                *status = LE_32(rep.SlotStatus);
16124      -        }
16125      -
16126      -        return (DDI_SUCCESS);
16127      -}
16128      -
16129 15342  int
16130 15343  mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
16131 15344      ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
16132 15345      uint32_t alloc_size, ddi_dma_cookie_t *cookiep)
16133 15346  {
16134 15347          ddi_dma_cookie_t        new_cookie;
16135 15348          size_t                  alloc_len;
16136 15349          uint_t                  ncookie;
16137 15350  
16138 15351          if (cookiep == NULL)
↓ open down ↓ 28 lines elided ↑ open up ↑
16167 15380  void
16168 15381  mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp)
16169 15382  {
16170 15383          if (*dma_hdp == NULL)
16171 15384                  return;
16172 15385  
16173 15386          (void) ddi_dma_unbind_handle(*dma_hdp);
16174 15387          (void) ddi_dma_mem_free(acc_hdp);
16175 15388          ddi_dma_free_handle(dma_hdp);
16176 15389          dma_hdp = NULL;
16177      -}
16178      -
16179      -static int
16180      -mptsas_outstanding_cmds_n(mptsas_t *mpt)
16181      -{
16182      -        int n = 0, i;
16183      -        for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) {
16184      -                mutex_enter(&mpt->m_slot_freeq_pairp[i].
16185      -                    m_slot_allocq.s.m_fq_mutex);
16186      -                mutex_enter(&mpt->m_slot_freeq_pairp[i].
16187      -                    m_slot_releq.s.m_fq_mutex);
16188      -                n += (mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n_init -
16189      -                    mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n -
16190      -                    mpt->m_slot_freeq_pairp[i].m_slot_releq.s.m_fq_n);
16191      -                mutex_exit(&mpt->m_slot_freeq_pairp[i].
16192      -                    m_slot_releq.s.m_fq_mutex);
16193      -                mutex_exit(&mpt->m_slot_freeq_pairp[i].
16194      -                    m_slot_allocq.s.m_fq_mutex);
16195      -        }
16196      -        if (mpt->m_max_requests - 2 < n)
16197      -                panic("mptsas: free slot allocq and releq crazy");
16198      -        return (n);
16199 15390  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX