Print this page
re #7364 rb2201 "hddisco" hangs after unplugging both cables from JBOD (and NMS too)
re #8346 rb2639 KT disk failures
re #8346 rb2639 KT disk failures
re #10443 rb3479 3.1.3 crash: BAD TRAP: type=e (#pf Page fault)


 220 static void mptsas_flush_hba(mptsas_t *mpt);
 221 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
 222         uint8_t tasktype);
 223 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
 224     uchar_t reason, uint_t stat);
 225 
 226 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
 227 static void mptsas_process_intr(mptsas_t *mpt,
 228     pMpi2ReplyDescriptorsUnion_t reply_desc_union);
 229 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
 230     pMpi2ReplyDescriptorsUnion_t reply_desc);
 231 static void mptsas_handle_address_reply(mptsas_t *mpt,
 232     pMpi2ReplyDescriptorsUnion_t reply_desc);
 233 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
 234 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
 235     uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
 236 
 237 static void mptsas_watch(void *arg);
 238 static void mptsas_watchsubr(mptsas_t *mpt);
 239 static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl);

 240 
 241 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
 242 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
 243     uint8_t *data, uint32_t request_size, uint32_t reply_size,
 244     uint32_t data_size, uint32_t direction, uint8_t *dataout,
 245     uint32_t dataout_size, short timeout, int mode);
 246 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
 247 
 248 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
 249     uint32_t unique_id);
 250 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
 251 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
 252     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
 253 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
 254     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
 255     uint32_t diag_type);
 256 static int mptsas_diag_register(mptsas_t *mpt,
 257     mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
 258 static int mptsas_diag_unregister(mptsas_t *mpt,
 259     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);


 330 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
 331 
 332 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
 333     int *lun);
 334 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
 335 
 336 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask,
 337     uint8_t phy);
 338 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
 339     uint64_t wwid);
 340 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
 341     uint64_t wwid);
 342 
 343 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
 344     uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
 345 
 346 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
 347     uint16_t *handle, mptsas_target_t **pptgt);
 348 static void mptsas_update_phymask(mptsas_t *mpt);
 349 
 350 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
 351     uint32_t *status, uint8_t cmd);
 352 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
 353     mptsas_phymask_t *phymask);
 354 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
 355     mptsas_phymask_t phymask);
 356 static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
 357     uint32_t slotstatus);
 358 
 359 
 360 /*
 361  * Enumeration / DR functions
 362  */
 363 static void mptsas_config_all(dev_info_t *pdip);
 364 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
 365     dev_info_t **lundip);
 366 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
 367     dev_info_t **lundip);
 368 
 369 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
 370 static int mptsas_offline_target(dev_info_t *pdip, char *name);
 371 
 372 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
 373     dev_info_t **dip);
 374 
 375 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
 376 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
 377     dev_info_t **dip, mptsas_target_t *ptgt);


 448  * FMA Prototypes
 449  */
 450 static void mptsas_fm_init(mptsas_t *mpt);
 451 static void mptsas_fm_fini(mptsas_t *mpt);
 452 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
 453 
 454 extern pri_t minclsyspri, maxclsyspri;
 455 
 456 /*
 457  * This device is created by the SCSI pseudo nexus driver (SCSI vHCI).  It is
 458  * under this device that the paths to a physical device are created when
 459  * MPxIO is used.
 460  */
 461 extern dev_info_t       *scsi_vhci_dip;
 462 
 463 /*
 464  * Tunable timeout value for Inquiry VPD page 0x83
 465  * By default the value is 30 seconds.
 466  */
 467 int mptsas_inq83_retry_timeout = 30;








 468 
 469 /*
 470  * This is used to allocate memory for message frame storage, not for
 471  * data I/O DMA. All message frames must be stored in the first 4G of
 472  * physical memory.
 473  */
 474 ddi_dma_attr_t mptsas_dma_attrs = {
 475         DMA_ATTR_V0,    /* attribute layout version             */
 476         0x0ull,         /* address low - should be 0 (longlong) */
 477         0xffffffffull,  /* address high - 32-bit max range      */
 478         0x00ffffffull,  /* count max - max DMA object size      */
 479         4,              /* allocation alignment requirements    */
 480         0x78,           /* burstsizes - binary encoded values   */
 481         1,              /* minxfer - gran. of DMA engine        */
 482         0x00ffffffull,  /* maxxfer - gran. of DMA engine        */
 483         0xffffffffull,  /* max segment size (DMA boundary)      */
 484         MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length      */
 485         512,            /* granularity - device transfer size   */
 486         0               /* flags, set to 0                      */
 487 };


2601 
2602         /*
2603          * Store the reply descriptor post queue memory address.  This chip
2604          * uses this address to write to the reply descriptor post queue.  The
2605          * second address is the address mpt uses to manage the queue.
2606          */
2607         mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
2608         mpt->m_post_queue = memp;
2609 
2610         /*
2611          * Clear the reply post queue memory.
2612          */
2613         bzero(mpt->m_post_queue, mem_size);
2614 
2615         return (DDI_SUCCESS);
2616 }
2617 
2618 static void
2619 mptsas_alloc_reply_args(mptsas_t *mpt)
2620 {
2621         if (mpt->m_replyh_args != NULL) {
2622                 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
2623                     * mpt->m_max_replies);
2624                 mpt->m_replyh_args = NULL;
2625         }
2626         mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
2627             mpt->m_max_replies, KM_SLEEP);

2628 }
2629 
2630 static int
2631 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2632 {
2633         mptsas_cache_frames_t   *frames = NULL;
2634         if (cmd->cmd_extra_frames == NULL) {
2635                 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2636                 if (frames == NULL) {
2637                         return (DDI_FAILURE);
2638                 }
2639                 cmd->cmd_extra_frames = frames;
2640         }
2641         return (DDI_SUCCESS);
2642 }
2643 
2644 static void
2645 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2646 {
2647         if (cmd->cmd_extra_frames) {


4809                 args->rfm = reply_addr;
4810 
4811                 /*
4812                  * Record the event if its type is enabled in
4813                  * this mpt instance by ioctl.
4814                  */
4815                 mptsas_record_event(args);
4816 
4817                 /*
4818                  * Handle time critical events
4819                  * NOT_RESPONDING/ADDED only now
4820                  */
4821                 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
4822                         /*
4823                          * Would not return main process,
4824                          * just let taskq resolve ack action
4825                          * and ack would be sent in taskq thread
4826                          */
4827                         NDBG20(("send mptsas_handle_event_sync success"));
4828                 }






4829                 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
4830                     (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
4831                         mptsas_log(mpt, CE_WARN, "No memory available"
4832                         "for dispatch taskq");
4833                         /*
4834                          * Return the reply frame to the free queue.
4835                          */
4836                         ddi_put32(mpt->m_acc_free_queue_hdl,
4837                             &((uint32_t *)(void *)
4838                             mpt->m_free_queue)[mpt->m_free_index], reply_addr);
4839                         (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4840                             DDI_DMA_SYNC_FORDEV);
4841                         if (++mpt->m_free_index == mpt->m_free_queue_depth) {
4842                                 mpt->m_free_index = 0;
4843                         }
4844 
4845                         ddi_put32(mpt->m_datap,
4846                             &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
4847                 }
4848                 return;


5746                                         mutex_exit(&mpt->m_mutex);
5747 
5748                                         parent = NULL;
5749                                         continue;
5750                                 }
5751                                 (void) sprintf(phy_mask_name, "%x", phymask);
5752                         }
5753                         parent = scsi_hba_iport_find(mpt->m_dip,
5754                             phy_mask_name);
5755                         if (parent == NULL) {
5756                                 mptsas_log(mpt, CE_WARN, "Failed to find an "
5757                                     "iport, should not happen!");
5758                                 goto out;
5759                         }
5760 
5761                 }
5762                 ASSERT(parent);
5763 handle_topo_change:
5764 
5765                 mutex_enter(&mpt->m_mutex);
5766 




5767                 mptsas_handle_topo_change(topo_node, parent);


5768                 save_node = topo_node;
5769                 topo_node = topo_node->next;
5770                 ASSERT(save_node);
5771                 kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
5772                 mutex_exit(&mpt->m_mutex);
5773 
5774                 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5775                     (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
5776                     (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
5777                         /*
5778                          * If direct attached device associated, make sure
5779                          * reset the parent before start the next one. But
5780                          * all devices associated with expander shares the
5781                          * parent.  Also, reset parent if this is for RAID.
5782                          */
5783                         parent = NULL;
5784                 }
5785         }
5786 out:
5787         kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);


6037                             MPTSAS_NUM_PHYS, 0) !=
6038                             DDI_PROP_SUCCESS) {
6039                                 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6040                                     MPTSAS_NUM_PHYS);
6041                                 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6042                                     "prop update failed");
6043                                 break;
6044                         }
6045                         if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6046                             MPTSAS_VIRTUAL_PORT, 1) !=
6047                             DDI_PROP_SUCCESS) {
6048                                 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6049                                     MPTSAS_VIRTUAL_PORT);
6050                                 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6051                                     "prop update failed");
6052                                 break;
6053                         }
6054                 }
6055 
6056                 mutex_enter(&mpt->m_mutex);
6057                 if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) {
6058                         NDBG14(("mptsas: clear LED for tgt %x failed",
6059                             ptgt->m_slot_num));
6060                 }
6061                 if (rval == DDI_SUCCESS) {
6062                         mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6063                             ptgt->m_sas_wwn, ptgt->m_phymask);
6064                         ptgt = NULL;
6065                 } else {
6066                         /*
6067                          * clean DR_INTRANSITION flag to allow I/O down to
6068                          * PHCI driver since failover finished.
6069                          * Invalidate the devhdl
6070                          */
6071                         ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6072                         ptgt->m_tgt_unconfigured = 0;
6073                         mutex_enter(&mpt->m_tx_waitq_mutex);
6074                         ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6075                         mutex_exit(&mpt->m_tx_waitq_mutex);
6076                 }
6077 
6078                 /*
6079                  * Send SAS IO Unit Control to free the dev handle
6080                  */


6973 
6974 /*
6975  * handle events from ioc
6976  */
6977 static void
6978 mptsas_handle_event(void *args)
6979 {
6980         m_replyh_arg_t                  *replyh_arg;
6981         pMpi2EventNotificationReply_t   eventreply;
6982         uint32_t                        event, iocloginfo, rfm;
6983         uint32_t                        status;
6984         uint8_t                         port;
6985         mptsas_t                        *mpt;
6986         uint_t                          iocstatus;
6987 
6988         replyh_arg = (m_replyh_arg_t *)args;
6989         rfm = replyh_arg->rfm;
6990         mpt = replyh_arg->mpt;
6991 
6992         mutex_enter(&mpt->m_mutex);








6993 
6994         eventreply = (pMpi2EventNotificationReply_t)
6995             (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6996         event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6997 
6998         if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6999             &eventreply->IOCStatus)) {
7000                 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7001                         mptsas_log(mpt, CE_WARN,
7002                             "!mptsas_handle_event: IOCStatus=0x%x, "
7003                             "IOCLogInfo=0x%x", iocstatus,
7004                             ddi_get32(mpt->m_acc_reply_frame_hdl,
7005                             &eventreply->IOCLogInfo));
7006                 } else {
7007                         mptsas_log(mpt, CE_WARN,
7008                             "mptsas_handle_event: IOCStatus=0x%x, "
7009                             "IOCLogInfo=0x%x", iocstatus,
7010                             ddi_get32(mpt->m_acc_reply_frame_hdl,
7011                             &eventreply->IOCLogInfo));
7012                 }


8500         int             slot;
8501         uchar_t         reason;
8502         uint_t          stat;
8503 
8504         NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8505 
8506         /*
8507          * Make sure the I/O Controller has flushed all cmds
8508          * that are associated with this target for a target reset
8509          * and target/lun for abort task set.
8510          * Account for TM requests, which use the last SMID.
8511          */
8512         for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8513                 if ((cmd = slots->m_slot[slot]) == NULL)
8514                         continue;
8515                 reason = CMD_RESET;
8516                 stat = STAT_DEV_RESET;
8517                 switch (tasktype) {
8518                 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8519                         if (Tgt(cmd) == target) {










8520                                 NDBG25(("mptsas_flush_target discovered non-"
8521                                     "NULL cmd in slot %d, tasktype 0x%x", slot,
8522                                     tasktype));
8523                                 mptsas_dump_cmd(mpt, cmd);
8524                                 mptsas_remove_cmd(mpt, cmd);
8525                                 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8526                                 mptsas_doneq_add(mpt, cmd);
8527                         }
8528                         break;
8529                 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8530                         reason = CMD_ABORTED;
8531                         stat = STAT_ABORTED;
8532                         /*FALLTHROUGH*/
8533                 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8534                         if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8535 
8536                                 NDBG25(("mptsas_flush_target discovered non-"
8537                                     "NULL cmd in slot %d, tasktype 0x%x", slot,
8538                                     tasktype));
8539                                 mptsas_dump_cmd(mpt, cmd);


8687                         cmd->cmd_flags |= CFLAG_FINISHED;
8688                         cv_broadcast(&mpt->m_passthru_cv);
8689                         cv_broadcast(&mpt->m_config_cv);
8690                         cv_broadcast(&mpt->m_fw_diag_cv);
8691                 } else {
8692                         mptsas_doneq_add(mpt, cmd);
8693                 }
8694         }
8695 
8696         /*
8697          * Flush the tx_waitq
8698          */
8699         mutex_enter(&mpt->m_tx_waitq_mutex);
8700         while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
8701                 mutex_exit(&mpt->m_tx_waitq_mutex);
8702                 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8703                 mptsas_doneq_add(mpt, cmd);
8704                 mutex_enter(&mpt->m_tx_waitq_mutex);
8705         }
8706         mutex_exit(&mpt->m_tx_waitq_mutex);








8707 }
8708 
8709 /*
8710  * set pkt_reason and OR in pkt_statistics flag
8711  */
8712 static void
8713 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
8714     uint_t stat)
8715 {
8716 #ifndef __lock_lint
8717         _NOTE(ARGUNUSED(mpt))
8718 #endif
8719 
8720         NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
8721             (void *)cmd, reason, stat));
8722 
8723         if (cmd) {
8724                 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
8725                         cmd->cmd_pkt->pkt_reason = reason;
8726                 }


9367                     (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9368                     (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9369                         mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9370                         mptsas_restart_hba(mpt);
9371                 }
9372 
9373                 if ((ptgt->m_t_ncmds > 0) &&
9374                     (ptgt->m_timebase)) {
9375 
9376                         if (ptgt->m_timebase <=
9377                             mptsas_scsi_watchdog_tick) {
9378                                 ptgt->m_timebase +=
9379                                     mptsas_scsi_watchdog_tick;
9380                                 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9381                                     &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9382                                 continue;
9383                         }
9384 
9385                         ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9386 









9387                         if (ptgt->m_timeout < 0) {






9388                                 mptsas_cmd_timeout(mpt, ptgt->m_devhdl);

9389                                 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9390                                     &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9391                                 continue;
9392                         }
9393 
9394                         if ((ptgt->m_timeout) <=
9395                             mptsas_scsi_watchdog_tick) {
9396                                 NDBG23(("pending timeout"));
9397                                 mptsas_set_throttle(mpt, ptgt,
9398                                     DRAIN_THROTTLE);
9399                         }
9400                 }
9401 
9402                 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9403                     &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9404         }
9405 }
9406 
9407 /*
9408  * timeout recovery


9410 static void
9411 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9412 {
9413 
9414         NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9415         mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9416             "Target %d", devhdl);
9417 
9418         /*
9419          * If the current target is not the target passed in,
9420          * try to reset that target.
9421          */
9422         NDBG29(("mptsas_cmd_timeout: device reset"));
9423         if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9424                 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
9425                     "recovery failed!", devhdl);
9426         }
9427 }
9428 
9429 /*


































9430  * Device / Hotplug control
9431  */
9432 static int
9433 mptsas_scsi_quiesce(dev_info_t *dip)
9434 {
9435         mptsas_t        *mpt;
9436         scsi_hba_tran_t *tran;
9437 
9438         tran = ddi_get_driver_private(dip);
9439         if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9440                 return (-1);
9441 
9442         return (mptsas_quiesce_bus(mpt));
9443 }
9444 
9445 static int
9446 mptsas_scsi_unquiesce(dev_info_t *dip)
9447 {
9448         mptsas_t                *mpt;
9449         scsi_hba_tran_t *tran;


11309                 (void) pm_busy_component(mpt->m_dip, 0);
11310                 if (mpt->m_power_level != PM_LEVEL_D0) {
11311                         mutex_exit(&mpt->m_mutex);
11312                         if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
11313                             DDI_SUCCESS) {
11314                                 mptsas_log(mpt, CE_WARN,
11315                                     "mptsas%d: mptsas_ioctl: Raise power "
11316                                     "request failed.", mpt->m_instance);
11317                                 (void) pm_idle_component(mpt->m_dip, 0);
11318                                 return (ENXIO);
11319                         }
11320                 } else {
11321                         mutex_exit(&mpt->m_mutex);
11322                 }
11323         } else {
11324                 mutex_exit(&mpt->m_mutex);
11325         }
11326 
11327         if (iport_flag) {
11328                 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval);
11329                 if (status != 0) {
11330                         goto out;
11331                 }
11332                 /*
11333                  * The following code control the OK2RM LED, it doesn't affect
11334                  * the ioctl return status.
11335                  */
11336                 if ((cmd == DEVCTL_DEVICE_ONLINE) ||
11337                     (cmd == DEVCTL_DEVICE_OFFLINE)) {
11338                         if (ndi_dc_allochdl((void *)data, &dcp) !=
11339                             NDI_SUCCESS) {
11340                                 goto out;
11341                         }
11342                         addr = ndi_dc_getaddr(dcp);
11343                         ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
11344                         if (ptgt == NULL) {
11345                                 NDBG14(("mptsas_ioctl led control: tgt %s not "
11346                                     "found", addr));
11347                                 ndi_dc_freehdl(dcp);
11348                                 goto out;
11349                         }
11350                         mutex_enter(&mpt->m_mutex);
11351                         if (cmd == DEVCTL_DEVICE_ONLINE) {
11352                                 ptgt->m_tgt_unconfigured = 0;
11353                         } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
11354                                 ptgt->m_tgt_unconfigured = 1;
11355                         }
11356                         slotstatus = 0;
11357 #ifdef MPTSAS_GET_LED
11358                         /*
11359                          * The get led status can't get a valid/reasonable
11360                          * state, so ignore the get led status, and write the
11361                          * required value directly
11362                          */
11363                         if (mptsas_get_led_status(mpt, ptgt, &slotstatus) !=
11364                             DDI_SUCCESS) {
11365                                 NDBG14(("mptsas_ioctl: get LED for tgt %s "
11366                                     "failed %x", addr, slotstatus));
11367                                 slotstatus = 0;
11368                         }
11369                         NDBG14(("mptsas_ioctl: LED status %x for %s",
11370                             slotstatus, addr));
11371 #endif
11372                         if (cmd == DEVCTL_DEVICE_OFFLINE) {
11373                                 slotstatus |=
11374                                     MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
11375                         } else {
11376                                 slotstatus &=
11377                                     ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
11378                         }
11379                         if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
11380                             DDI_SUCCESS) {
11381                                 NDBG14(("mptsas_ioctl: set LED for tgt %s "
11382                                     "failed %x", addr, slotstatus));
11383                         }
11384                         mutex_exit(&mpt->m_mutex);
11385                         ndi_dc_freehdl(dcp);
11386                 }
11387                 goto out;
11388         }
11389         switch (cmd) {
11390                 case MPTIOCTL_UPDATE_FLASH:
11391                         if (ddi_copyin((void *)data, &flashdata,
11392                                 sizeof (struct mptsas_update_flash), mode)) {
11393                                 status = EFAULT;
11394                                 break;
11395                         }
11396 
11397                         mutex_enter(&mpt->m_mutex);
11398                         if (mptsas_update_flash(mpt,
11399                             (caddr_t)(long)flashdata.PtrBuffer,
11400                             flashdata.ImageSize, flashdata.ImageType, mode)) {
11401                                 status = EFAULT;
11402                         }
11403 
11404                         /*
11405                          * Reset the chip to start using the new
11406                          * firmware.  Reset if failed also.
11407                          */
11408                         mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;


13821                 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13822         } else {
13823                 *pip = mptsas_find_path_phy(pdip, phy);
13824         }
13825 
13826         if (*pip != NULL) {
13827                 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
13828                 ASSERT(*lun_dip != NULL);
13829                 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
13830                     (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
13831                     MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
13832                         if (strncmp(guid, old_guid, strlen(guid)) == 0) {
13833                                 /*
13834                                  * Same path back online again.
13835                                  */
13836                                 (void) ddi_prop_free(old_guid);
13837                                 if ((!MDI_PI_IS_ONLINE(*pip)) &&
13838                                     (!MDI_PI_IS_STANDBY(*pip)) &&
13839                                     (ptgt->m_tgt_unconfigured == 0)) {
13840                                         rval = mdi_pi_online(*pip, 0);
13841                                         mutex_enter(&mpt->m_mutex);
13842                                         (void) mptsas_set_led_status(mpt, ptgt,
13843                                             0);
13844                                         mutex_exit(&mpt->m_mutex);
13845                                 } else {
13846                                         rval = DDI_SUCCESS;
13847                                 }
13848                                 if (rval != DDI_SUCCESS) {
13849                                         mptsas_log(mpt, CE_WARN, "path:target: "
13850                                             "%x, lun:%x online failed!", target,
13851                                             lun);
13852                                         *pip = NULL;
13853                                         *lun_dip = NULL;
13854                                 }
13855                                 return (rval);
13856                         } else {
13857                                 /*
13858                                  * The GUID of the LUN has changed which maybe
13859                                  * because customer mapped another volume to the
13860                                  * same LUN.
13861                                  */
13862                                 mptsas_log(mpt, CE_WARN, "The GUID of the "
13863                                     "target:%x, lun:%x was changed, maybe "
13864                                     "because someone mapped another volume "


14078                                 mptsas_log(mpt, CE_WARN, "mptsas driver"
14079                                     "failed to create pm-capable "
14080                                     "property, target %d", target);
14081                                 mdi_rtn = MDI_FAILURE;
14082                                 goto virt_create_done;
14083                         }
14084                 }
14085                 /*
14086                  * Create the phy-num property
14087                  */
14088                 if (mdi_prop_update_int(*pip, "phy-num",
14089                     ptgt->m_phynum) != DDI_SUCCESS) {
14090                         mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14091                             "create phy-num property for target %d lun %d",
14092                             target, lun);
14093                         mdi_rtn = MDI_FAILURE;
14094                         goto virt_create_done;
14095                 }
14096                 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
14097                 mdi_rtn = mdi_pi_online(*pip, 0);
14098                 if (mdi_rtn == MDI_SUCCESS) {
14099                         mutex_enter(&mpt->m_mutex);
14100                         if (mptsas_set_led_status(mpt, ptgt, 0) !=
14101                             DDI_SUCCESS) {
14102                                 NDBG14(("mptsas: clear LED for slot %x "
14103                                     "failed", ptgt->m_slot_num));
14104                         }
14105                         mutex_exit(&mpt->m_mutex);
14106                 }
14107                 if (mdi_rtn == MDI_NOT_SUPPORTED) {
14108                         mdi_rtn = MDI_FAILURE;
14109                 }
14110 virt_create_done:
14111                 if (*pip && mdi_rtn != MDI_SUCCESS) {
14112                         (void) mdi_pi_free(*pip, 0);
14113                         *pip = NULL;
14114                         *lun_dip = NULL;
14115                 }
14116         }
14117 
14118         scsi_hba_nodename_compatible_free(nodename, compatible);
14119         if (lun_addr != NULL) {
14120                 kmem_free(lun_addr, SCSI_MAXNAMELEN);
14121         }
14122         if (wwn_str != NULL) {
14123                 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
14124         }
14125         if (component != NULL) {
14126                 kmem_free(component, MAXPATHLEN);


14440                         if (ndi_prop_update_int(DDI_DEV_T_NONE,
14441                             *lun_dip, "phy-num", ptgt->m_phynum) !=
14442                             DDI_PROP_SUCCESS) {
14443                                 mptsas_log(mpt, CE_WARN, "mptsas driver "
14444                                     "failed to create phy-num property for "
14445                                     "target %d", target);
14446                                 ndi_rtn = NDI_FAILURE;
14447                                 goto phys_create_done;
14448                         }
14449                 }
14450 phys_create_done:
14451                 /*
14452                  * If props were setup ok, online the lun
14453                  */
14454                 if (ndi_rtn == NDI_SUCCESS) {
14455                         /*
14456                          * Try to online the new node
14457                          */
14458                         ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
14459                 }
14460                 if (ndi_rtn == NDI_SUCCESS) {
14461                         mutex_enter(&mpt->m_mutex);
14462                         if (mptsas_set_led_status(mpt, ptgt, 0) !=
14463                             DDI_SUCCESS) {
14464                                 NDBG14(("mptsas: clear LED for tgt %x "
14465                                     "failed", ptgt->m_slot_num));
14466                         }
14467                         mutex_exit(&mpt->m_mutex);
14468                 }
14469 
14470                 /*
14471                  * If success set rtn flag, else unwire alloc'd lun
14472                  */
14473                 if (ndi_rtn != NDI_SUCCESS) {
14474                         NDBG12(("mptsas driver unable to online "
14475                             "target %d lun %d", target, lun));
14476                         ndi_prop_remove_all(*lun_dip);
14477                         (void) ndi_devi_free(*lun_dip);
14478                         *lun_dip = NULL;
14479                 }
14480         }
14481 
14482         scsi_hba_nodename_compatible_free(nodename, compatible);
14483 
14484         if (wwn_str != NULL) {
14485                 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
14486         }
14487         if (component != NULL) {
14488                 kmem_free(component, MAXPATHLEN);


15341 }
15342 static mptsas_target_t *
15343 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
15344 {
15345         uint8_t                 phynum;
15346         uint64_t                wwn;
15347         int                     lun;
15348         mptsas_target_t         *ptgt = NULL;
15349 
15350         if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
15351                 return (NULL);
15352         }
15353         if (addr[0] == 'w') {
15354                 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
15355         } else {
15356                 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
15357         }
15358         return (ptgt);
15359 }
15360 
15361 #ifdef MPTSAS_GET_LED
15362 static int
15363 mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
15364     uint32_t *slotstatus)
15365 {
15366         return (mptsas_send_sep(mpt, ptgt, slotstatus,
15367             MPI2_SEP_REQ_ACTION_READ_STATUS));
15368 }
15369 #endif
15370 static int
15371 mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus)
15372 {
15373         NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
15374             slotstatus, ptgt->m_slot_num));
15375         return (mptsas_send_sep(mpt, ptgt, &slotstatus,
15376             MPI2_SEP_REQ_ACTION_WRITE_STATUS));
15377 }
15378 /*
15379  *  send sep request, use enclosure/slot addressing
15380  */
15381 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
15382     uint32_t *status, uint8_t act)
15383 {
15384         Mpi2SepRequest_t        req;
15385         Mpi2SepReply_t          rep;
15386         int                     ret;
15387 
15388         ASSERT(mutex_owned(&mpt->m_mutex));
15389 
15390         bzero(&req, sizeof (req));
15391         bzero(&rep, sizeof (rep));
15392 
15393         /* Do nothing for RAID volumes */
15394         if (ptgt->m_phymask == 0) {
15395                 NDBG14(("mptsas_send_sep: Skip RAID volumes"));
15396                 return (DDI_FAILURE);
15397         }
15398 
15399         req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
15400         req.Action = act;
15401         req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
15402         req.EnclosureHandle = LE_16(ptgt->m_enclosure);
15403         req.Slot = LE_16(ptgt->m_slot_num);
15404         if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
15405                 req.SlotStatus = LE_32(*status);
15406         }
15407         ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
15408             sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
15409         if (ret != 0) {
15410                 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
15411                     "Processor Request message error %d", ret);
15412                 return (DDI_FAILURE);
15413         }
15414         /* do passthrough success, check the ioc status */
15415         if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
15416                 if ((LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) ==
15417                     MPI2_IOCSTATUS_INVALID_FIELD) {
15418                         mptsas_log(mpt, CE_NOTE, "send sep act %x: Not "
15419                             "supported action, loginfo %x", act,
15420                             LE_32(rep.IOCLogInfo));
15421                         return (DDI_FAILURE);
15422                 }
15423                 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc "
15424                     "status:%x", act, LE_16(rep.IOCStatus));
15425                 return (DDI_FAILURE);
15426         }
15427         if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
15428                 *status = LE_32(rep.SlotStatus);
15429         }
15430 
15431         return (DDI_SUCCESS);
15432 }
15433 
15434 int
15435 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
15436     ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
15437     uint32_t alloc_size, ddi_dma_cookie_t *cookiep)
15438 {
15439         ddi_dma_cookie_t        new_cookie;
15440         size_t                  alloc_len;
15441         uint_t                  ncookie;
15442 
15443         if (cookiep == NULL)
15444                 cookiep = &new_cookie;
15445 
15446         if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP,
15447             NULL, dma_hdp) != DDI_SUCCESS) {
15448                 dma_hdp = NULL;
15449                 return (FALSE);
15450         }
15451 
15452         if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr,
15453             DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len,




 220 static void mptsas_flush_hba(mptsas_t *mpt);
 221 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
 222         uint8_t tasktype);
 223 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
 224     uchar_t reason, uint_t stat);
 225 
 226 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
 227 static void mptsas_process_intr(mptsas_t *mpt,
 228     pMpi2ReplyDescriptorsUnion_t reply_desc_union);
 229 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
 230     pMpi2ReplyDescriptorsUnion_t reply_desc);
 231 static void mptsas_handle_address_reply(mptsas_t *mpt,
 232     pMpi2ReplyDescriptorsUnion_t reply_desc);
 233 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
 234 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
 235     uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
 236 
 237 static void mptsas_watch(void *arg);
 238 static void mptsas_watchsubr(mptsas_t *mpt);
 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);
 241 
 242 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
 243 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
 244     uint8_t *data, uint32_t request_size, uint32_t reply_size,
 245     uint32_t data_size, uint32_t direction, uint8_t *dataout,
 246     uint32_t dataout_size, short timeout, int mode);
 247 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
 248 
 249 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
 250     uint32_t unique_id);
 251 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
 252 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
 253     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
 254 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
 255     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
 256     uint32_t diag_type);
 257 static int mptsas_diag_register(mptsas_t *mpt,
 258     mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
 259 static int mptsas_diag_unregister(mptsas_t *mpt,
 260     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);


 331 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
 332 
 333 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
 334     int *lun);
 335 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
 336 
 337 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask,
 338     uint8_t phy);
 339 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
 340     uint64_t wwid);
 341 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
 342     uint64_t wwid);
 343 
 344 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
 345     uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
 346 
 347 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
 348     uint16_t *handle, mptsas_target_t **pptgt);
 349 static void mptsas_update_phymask(mptsas_t *mpt);
 350 


 351 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
 352     mptsas_phymask_t *phymask);
 353 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
 354     mptsas_phymask_t phymask);


 355 
 356 
 357 /*
 358  * Enumeration / DR functions
 359  */
 360 static void mptsas_config_all(dev_info_t *pdip);
 361 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
 362     dev_info_t **lundip);
 363 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
 364     dev_info_t **lundip);
 365 
 366 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
 367 static int mptsas_offline_target(dev_info_t *pdip, char *name);
 368 
 369 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
 370     dev_info_t **dip);
 371 
 372 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
 373 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
 374     dev_info_t **dip, mptsas_target_t *ptgt);


 445  * FMA Prototypes
 446  */
 447 static void mptsas_fm_init(mptsas_t *mpt);
 448 static void mptsas_fm_fini(mptsas_t *mpt);
 449 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
 450 
 451 extern pri_t minclsyspri, maxclsyspri;
 452 
 453 /*
 454  * This device is created by the SCSI pseudo nexus driver (SCSI vHCI).  It is
 455  * under this device that the paths to a physical device are created when
 456  * MPxIO is used.
 457  */
 458 extern dev_info_t       *scsi_vhci_dip;
 459 
 460 /*
 461  * Tunable timeout value for Inquiry VPD page 0x83
 462  * By default the value is 30 seconds.
 463  */
 464 int mptsas_inq83_retry_timeout = 30;
 465 /*
 466  * Maximum number of command timeouts (0 - 255) considered acceptable.
 467  */
 468 int mptsas_timeout_threshold = 2;
 469 /*
 470  * Timeouts exceeding threshold within this period are considered excessive.
 471  */
 472 int mptsas_timeout_interval = 30;
 473 
 474 /*
 475  * This is used to allocate memory for message frame storage, not for
 476  * data I/O DMA. All message frames must be stored in the first 4G of
 477  * physical memory.
 478  */
 479 ddi_dma_attr_t mptsas_dma_attrs = {
 480         DMA_ATTR_V0,    /* attribute layout version             */
 481         0x0ull,         /* address low - should be 0 (longlong) */
 482         0xffffffffull,  /* address high - 32-bit max range      */
 483         0x00ffffffull,  /* count max - max DMA object size      */
 484         4,              /* allocation alignment requirements    */
 485         0x78,           /* burstsizes - binary encoded values   */
 486         1,              /* minxfer - gran. of DMA engine        */
 487         0x00ffffffull,  /* maxxfer - gran. of DMA engine        */
 488         0xffffffffull,  /* max segment size (DMA boundary)      */
 489         MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length      */
 490         512,            /* granularity - device transfer size   */
 491         0               /* flags, set to 0                      */
 492 };


2606 
2607         /*
2608          * Store the reply descriptor post queue memory address.  This chip
2609          * uses this address to write to the reply descriptor post queue.  The
2610          * second address is the address mpt uses to manage the queue.
2611          */
2612         mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
2613         mpt->m_post_queue = memp;
2614 
2615         /*
2616          * Clear the reply post queue memory.
2617          */
2618         bzero(mpt->m_post_queue, mem_size);
2619 
2620         return (DDI_SUCCESS);
2621 }
2622 
2623 static void
2624 mptsas_alloc_reply_args(mptsas_t *mpt)
2625 {
2626         if (mpt->m_replyh_args == NULL) {




2627                 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
2628                     mpt->m_max_replies, KM_SLEEP);
2629         }
2630 }
2631 
2632 static int
2633 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2634 {
2635         mptsas_cache_frames_t   *frames = NULL;
2636         if (cmd->cmd_extra_frames == NULL) {
2637                 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2638                 if (frames == NULL) {
2639                         return (DDI_FAILURE);
2640                 }
2641                 cmd->cmd_extra_frames = frames;
2642         }
2643         return (DDI_SUCCESS);
2644 }
2645 
2646 static void
2647 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2648 {
2649         if (cmd->cmd_extra_frames) {


4811                 args->rfm = reply_addr;
4812 
4813                 /*
4814                  * Record the event if its type is enabled in
4815                  * this mpt instance by ioctl.
4816                  */
4817                 mptsas_record_event(args);
4818 
4819                 /*
4820                  * Handle time critical events
4821                  * NOT_RESPONDING/ADDED only now
4822                  */
4823                 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
4824                         /*
4825                          * Would not return main process,
4826                          * just let taskq resolve ack action
4827                          * and ack would be sent in taskq thread
4828                          */
4829                         NDBG20(("send mptsas_handle_event_sync success"));
4830                 }
4831 
4832                 if (mpt->m_in_reset) {
4833                         NDBG20(("dropping event received during reset"));
4834                         return;
4835                 }
4836 
4837                 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
4838                     (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
4839                         mptsas_log(mpt, CE_WARN, "No memory available"
4840                         "for dispatch taskq");
4841                         /*
4842                          * Return the reply frame to the free queue.
4843                          */
4844                         ddi_put32(mpt->m_acc_free_queue_hdl,
4845                             &((uint32_t *)(void *)
4846                             mpt->m_free_queue)[mpt->m_free_index], reply_addr);
4847                         (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4848                             DDI_DMA_SYNC_FORDEV);
4849                         if (++mpt->m_free_index == mpt->m_free_queue_depth) {
4850                                 mpt->m_free_index = 0;
4851                         }
4852 
4853                         ddi_put32(mpt->m_datap,
4854                             &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
4855                 }
4856                 return;


5754                                         mutex_exit(&mpt->m_mutex);
5755 
5756                                         parent = NULL;
5757                                         continue;
5758                                 }
5759                                 (void) sprintf(phy_mask_name, "%x", phymask);
5760                         }
5761                         parent = scsi_hba_iport_find(mpt->m_dip,
5762                             phy_mask_name);
5763                         if (parent == NULL) {
5764                                 mptsas_log(mpt, CE_WARN, "Failed to find an "
5765                                     "iport, should not happen!");
5766                                 goto out;
5767                         }
5768 
5769                 }
5770                 ASSERT(parent);
5771 handle_topo_change:
5772 
5773                 mutex_enter(&mpt->m_mutex);
5774                 /*
5775                  * If HBA is being reset, don't perform operations depending
5776                  * on the IOC. We must free the topo list, however.
5777                  */
5778                 if (!mpt->m_in_reset)
5779                         mptsas_handle_topo_change(topo_node, parent);
5780                 else
5781                         NDBG20(("skipping topo change received during reset"));
5782                 save_node = topo_node;
5783                 topo_node = topo_node->next;
5784                 ASSERT(save_node);
5785                 kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
5786                 mutex_exit(&mpt->m_mutex);
5787 
5788                 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5789                     (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
5790                     (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
5791                         /*
5792                          * If direct attached device associated, make sure
5793                          * reset the parent before start the next one. But
5794                          * all devices associated with expander shares the
5795                          * parent.  Also, reset parent if this is for RAID.
5796                          */
5797                         parent = NULL;
5798                 }
5799         }
5800 out:
5801         kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);


6051                             MPTSAS_NUM_PHYS, 0) !=
6052                             DDI_PROP_SUCCESS) {
6053                                 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6054                                     MPTSAS_NUM_PHYS);
6055                                 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6056                                     "prop update failed");
6057                                 break;
6058                         }
6059                         if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6060                             MPTSAS_VIRTUAL_PORT, 1) !=
6061                             DDI_PROP_SUCCESS) {
6062                                 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6063                                     MPTSAS_VIRTUAL_PORT);
6064                                 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6065                                     "prop update failed");
6066                                 break;
6067                         }
6068                 }
6069 
6070                 mutex_enter(&mpt->m_mutex);




6071                 if (rval == DDI_SUCCESS) {
6072                         mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6073                             ptgt->m_sas_wwn, ptgt->m_phymask);
6074                         ptgt = NULL;
6075                 } else {
6076                         /*
6077                          * clean DR_INTRANSITION flag to allow I/O down to
6078                          * PHCI driver since failover finished.
6079                          * Invalidate the devhdl
6080                          */
6081                         ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6082                         ptgt->m_tgt_unconfigured = 0;
6083                         mutex_enter(&mpt->m_tx_waitq_mutex);
6084                         ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6085                         mutex_exit(&mpt->m_tx_waitq_mutex);
6086                 }
6087 
6088                 /*
6089                  * Send SAS IO Unit Control to free the dev handle
6090                  */


6983 
6984 /*
6985  * handle events from ioc
6986  */
6987 static void
6988 mptsas_handle_event(void *args)
6989 {
6990         m_replyh_arg_t                  *replyh_arg;
6991         pMpi2EventNotificationReply_t   eventreply;
6992         uint32_t                        event, iocloginfo, rfm;
6993         uint32_t                        status;
6994         uint8_t                         port;
6995         mptsas_t                        *mpt;
6996         uint_t                          iocstatus;
6997 
6998         replyh_arg = (m_replyh_arg_t *)args;
6999         rfm = replyh_arg->rfm;
7000         mpt = replyh_arg->mpt;
7001 
7002         mutex_enter(&mpt->m_mutex);
7003         /*
7004          * If HBA is being reset, drop incoming event.
7005          */
7006         if (mpt->m_in_reset) {
7007                 NDBG20(("dropping event received prior to reset"));
7008                 mutex_exit(&mpt->m_mutex);
7009                 return;
7010         }
7011 
7012         eventreply = (pMpi2EventNotificationReply_t)
7013             (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
7014         event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
7015 
7016         if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
7017             &eventreply->IOCStatus)) {
7018                 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
7019                         mptsas_log(mpt, CE_WARN,
7020                             "!mptsas_handle_event: IOCStatus=0x%x, "
7021                             "IOCLogInfo=0x%x", iocstatus,
7022                             ddi_get32(mpt->m_acc_reply_frame_hdl,
7023                             &eventreply->IOCLogInfo));
7024                 } else {
7025                         mptsas_log(mpt, CE_WARN,
7026                             "mptsas_handle_event: IOCStatus=0x%x, "
7027                             "IOCLogInfo=0x%x", iocstatus,
7028                             ddi_get32(mpt->m_acc_reply_frame_hdl,
7029                             &eventreply->IOCLogInfo));
7030                 }


8518         int             slot;
8519         uchar_t         reason;
8520         uint_t          stat;
8521 
8522         NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8523 
8524         /*
8525          * Make sure the I/O Controller has flushed all cmds
8526          * that are associated with this target for a target reset
8527          * and target/lun for abort task set.
8528          * Account for TM requests, which use the last SMID.
8529          */
8530         for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8531                 if ((cmd = slots->m_slot[slot]) == NULL)
8532                         continue;
8533                 reason = CMD_RESET;
8534                 stat = STAT_DEV_RESET;
8535                 switch (tasktype) {
8536                 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8537                         if (Tgt(cmd) == target) {
8538                                 if (cmd->cmd_tgt_addr->m_timeout < 0) {
8539                                         /*
8540                                          * When timeout requested, propagate
8541                                          * proper reason and statistics to
8542                                          * target drivers.
8543                                          */
8544                                         reason = CMD_TIMEOUT;
8545                                         stat |= STAT_TIMEOUT;
8546                                 }
8547                                 
8548                                 NDBG25(("mptsas_flush_target discovered non-"
8549                                     "NULL cmd in slot %d, tasktype 0x%x", slot,
8550                                     tasktype));
8551                                 mptsas_dump_cmd(mpt, cmd);
8552                                 mptsas_remove_cmd(mpt, cmd);
8553                                 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8554                                 mptsas_doneq_add(mpt, cmd);
8555                         }
8556                         break;
8557                 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8558                         reason = CMD_ABORTED;
8559                         stat = STAT_ABORTED;
8560                         /*FALLTHROUGH*/
8561                 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8562                         if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8563 
8564                                 NDBG25(("mptsas_flush_target discovered non-"
8565                                     "NULL cmd in slot %d, tasktype 0x%x", slot,
8566                                     tasktype));
8567                                 mptsas_dump_cmd(mpt, cmd);


8715                         cmd->cmd_flags |= CFLAG_FINISHED;
8716                         cv_broadcast(&mpt->m_passthru_cv);
8717                         cv_broadcast(&mpt->m_config_cv);
8718                         cv_broadcast(&mpt->m_fw_diag_cv);
8719                 } else {
8720                         mptsas_doneq_add(mpt, cmd);
8721                 }
8722         }
8723 
8724         /*
8725          * Flush the tx_waitq
8726          */
8727         mutex_enter(&mpt->m_tx_waitq_mutex);
8728         while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
8729                 mutex_exit(&mpt->m_tx_waitq_mutex);
8730                 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8731                 mptsas_doneq_add(mpt, cmd);
8732                 mutex_enter(&mpt->m_tx_waitq_mutex);
8733         }
8734         mutex_exit(&mpt->m_tx_waitq_mutex);
8735 
8736         /*
8737          * Drain the taskqs prior to reallocating resources.
8738          */
8739         mutex_exit(&mpt->m_mutex);
8740         ddi_taskq_wait(mpt->m_event_taskq);
8741         ddi_taskq_wait(mpt->m_dr_taskq);
8742         mutex_enter(&mpt->m_mutex);
8743 }
8744 
8745 /*
8746  * set pkt_reason and OR in pkt_statistics flag
8747  */
8748 static void
8749 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
8750     uint_t stat)
8751 {
8752 #ifndef __lock_lint
8753         _NOTE(ARGUNUSED(mpt))
8754 #endif
8755 
8756         NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
8757             (void *)cmd, reason, stat));
8758 
8759         if (cmd) {
8760                 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
8761                         cmd->cmd_pkt->pkt_reason = reason;
8762                 }


9403                     (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9404                     (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9405                         mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9406                         mptsas_restart_hba(mpt);
9407                 }
9408 
9409                 if ((ptgt->m_t_ncmds > 0) &&
9410                     (ptgt->m_timebase)) {
9411 
9412                         if (ptgt->m_timebase <=
9413                             mptsas_scsi_watchdog_tick) {
9414                                 ptgt->m_timebase +=
9415                                     mptsas_scsi_watchdog_tick;
9416                                 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9417                                     &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9418                                 continue;
9419                         }
9420 
9421                         ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9422 
9423                         if (ptgt->m_timeout_count > 0) {
9424                                 ptgt->m_timeout_interval +=
9425                                     mptsas_scsi_watchdog_tick;
9426                         }
9427                         if (ptgt->m_timeout_interval > mptsas_timeout_interval) {
9428                                 ptgt->m_timeout_interval = 0;
9429                                 ptgt->m_timeout_count = 0;
9430                         }
9431 
9432                         if (ptgt->m_timeout < 0) {
9433                                 ptgt->m_timeout_count++;
9434                                 if (ptgt->m_timeout_count >
9435                                     mptsas_timeout_threshold) {
9436                                         ptgt->m_timeout_count = 0;
9437                                         mptsas_kill_target(mpt, ptgt);
9438                                 } else {
9439                                         mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
9440                                 }
9441                                 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9442                                     &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9443                                 continue;
9444                         }
9445 
9446                         if ((ptgt->m_timeout) <=
9447                             mptsas_scsi_watchdog_tick) {
9448                                 NDBG23(("pending timeout"));
9449                                 mptsas_set_throttle(mpt, ptgt,
9450                                     DRAIN_THROTTLE);
9451                         }
9452                 }
9453 
9454                 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9455                     &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9456         }
9457 }
9458 
9459 /*
9460  * timeout recovery


9462 static void
9463 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9464 {
9465 
9466         NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9467         mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9468             "Target %d", devhdl);
9469 
9470         /*
9471          * If the current target is not the target passed in,
9472          * try to reset that target.
9473          */
9474         NDBG29(("mptsas_cmd_timeout: device reset"));
9475         if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9476                 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
9477                     "recovery failed!", devhdl);
9478         }
9479 }
9480 
9481 /*
9482  * target causing too many timeouts
9483  */
9484 static void
9485 mptsas_kill_target(mptsas_t *mpt, mptsas_target_t *ptgt)
9486 {
9487         mptsas_topo_change_list_t       *topo_node = NULL;
9488 
9489         NDBG29(("mptsas_tgt_kill: target=%d", ptgt->m_devhdl));
9490         mptsas_log(mpt, CE_WARN, "timeout threshold exceeded for "
9491             "Target %d", ptgt->m_devhdl);
9492 
9493         topo_node = kmem_zalloc(sizeof (mptsas_topo_change_list_t), KM_SLEEP);
9494         topo_node->mpt = mpt;
9495         topo_node->un.phymask = ptgt->m_phymask;
9496         topo_node->event = MPTSAS_DR_EVENT_OFFLINE_TARGET;
9497         topo_node->devhdl = ptgt->m_devhdl;
9498         if (ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED)
9499                 topo_node->flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
9500         else
9501                 topo_node->flags = MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
9502         topo_node->object = NULL;
9503 
9504         /*
9505          * Launch DR taskq to fake topology change
9506          */
9507         if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
9508             mptsas_handle_dr, (void *)topo_node,
9509             DDI_NOSLEEP)) != DDI_SUCCESS) {
9510                 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
9511                     "for fake offline event failed. \n");
9512         }
9513 }
9514 
9515 /*
9516  * Device / Hotplug control
9517  */
9518 static int
9519 mptsas_scsi_quiesce(dev_info_t *dip)
9520 {
9521         mptsas_t        *mpt;
9522         scsi_hba_tran_t *tran;
9523 
9524         tran = ddi_get_driver_private(dip);
9525         if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9526                 return (-1);
9527 
9528         return (mptsas_quiesce_bus(mpt));
9529 }
9530 
9531 static int
9532 mptsas_scsi_unquiesce(dev_info_t *dip)
9533 {
9534         mptsas_t                *mpt;
9535         scsi_hba_tran_t *tran;


11395                 (void) pm_busy_component(mpt->m_dip, 0);
11396                 if (mpt->m_power_level != PM_LEVEL_D0) {
11397                         mutex_exit(&mpt->m_mutex);
11398                         if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
11399                             DDI_SUCCESS) {
11400                                 mptsas_log(mpt, CE_WARN,
11401                                     "mptsas%d: mptsas_ioctl: Raise power "
11402                                     "request failed.", mpt->m_instance);
11403                                 (void) pm_idle_component(mpt->m_dip, 0);
11404                                 return (ENXIO);
11405                         }
11406                 } else {
11407                         mutex_exit(&mpt->m_mutex);
11408                 }
11409         } else {
11410                 mutex_exit(&mpt->m_mutex);
11411         }
11412 
11413         if (iport_flag) {
11414                 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval);

11415                 goto out;
11416         }

























































11417         switch (cmd) {
11418                 case MPTIOCTL_UPDATE_FLASH:
11419                         if (ddi_copyin((void *)data, &flashdata,
11420                                 sizeof (struct mptsas_update_flash), mode)) {
11421                                 status = EFAULT;
11422                                 break;
11423                         }
11424 
11425                         mutex_enter(&mpt->m_mutex);
11426                         if (mptsas_update_flash(mpt,
11427                             (caddr_t)(long)flashdata.PtrBuffer,
11428                             flashdata.ImageSize, flashdata.ImageType, mode)) {
11429                                 status = EFAULT;
11430                         }
11431 
11432                         /*
11433                          * Reset the chip to start using the new
11434                          * firmware.  Reset if failed also.
11435                          */
11436                         mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;


13849                 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13850         } else {
13851                 *pip = mptsas_find_path_phy(pdip, phy);
13852         }
13853 
13854         if (*pip != NULL) {
13855                 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
13856                 ASSERT(*lun_dip != NULL);
13857                 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
13858                     (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
13859                     MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
13860                         if (strncmp(guid, old_guid, strlen(guid)) == 0) {
13861                                 /*
13862                                  * Same path back online again.
13863                                  */
13864                                 (void) ddi_prop_free(old_guid);
13865                                 if ((!MDI_PI_IS_ONLINE(*pip)) &&
13866                                     (!MDI_PI_IS_STANDBY(*pip)) &&
13867                                     (ptgt->m_tgt_unconfigured == 0)) {
13868                                         rval = mdi_pi_online(*pip, 0);




13869                                 } else {
13870                                         rval = DDI_SUCCESS;
13871                                 }
13872                                 if (rval != DDI_SUCCESS) {
13873                                         mptsas_log(mpt, CE_WARN, "path:target: "
13874                                             "%x, lun:%x online failed!", target,
13875                                             lun);
13876                                         *pip = NULL;
13877                                         *lun_dip = NULL;
13878                                 }
13879                                 return (rval);
13880                         } else {
13881                                 /*
13882                                  * The GUID of the LUN has changed which maybe
13883                                  * because customer mapped another volume to the
13884                                  * same LUN.
13885                                  */
13886                                 mptsas_log(mpt, CE_WARN, "The GUID of the "
13887                                     "target:%x, lun:%x was changed, maybe "
13888                                     "because someone mapped another volume "


14102                                 mptsas_log(mpt, CE_WARN, "mptsas driver"
14103                                     "failed to create pm-capable "
14104                                     "property, target %d", target);
14105                                 mdi_rtn = MDI_FAILURE;
14106                                 goto virt_create_done;
14107                         }
14108                 }
14109                 /*
14110                  * Create the phy-num property
14111                  */
14112                 if (mdi_prop_update_int(*pip, "phy-num",
14113                     ptgt->m_phynum) != DDI_SUCCESS) {
14114                         mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14115                             "create phy-num property for target %d lun %d",
14116                             target, lun);
14117                         mdi_rtn = MDI_FAILURE;
14118                         goto virt_create_done;
14119                 }
14120                 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
14121                 mdi_rtn = mdi_pi_online(*pip, 0);









14122                 if (mdi_rtn == MDI_NOT_SUPPORTED) {
14123                         mdi_rtn = MDI_FAILURE;
14124                 }
14125 virt_create_done:
14126                 if (*pip && mdi_rtn != MDI_SUCCESS) {
14127                         (void) mdi_pi_free(*pip, 0);
14128                         *pip = NULL;
14129                         *lun_dip = NULL;
14130                 }
14131         }
14132 
14133         scsi_hba_nodename_compatible_free(nodename, compatible);
14134         if (lun_addr != NULL) {
14135                 kmem_free(lun_addr, SCSI_MAXNAMELEN);
14136         }
14137         if (wwn_str != NULL) {
14138                 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
14139         }
14140         if (component != NULL) {
14141                 kmem_free(component, MAXPATHLEN);


14455                         if (ndi_prop_update_int(DDI_DEV_T_NONE,
14456                             *lun_dip, "phy-num", ptgt->m_phynum) !=
14457                             DDI_PROP_SUCCESS) {
14458                                 mptsas_log(mpt, CE_WARN, "mptsas driver "
14459                                     "failed to create phy-num property for "
14460                                     "target %d", target);
14461                                 ndi_rtn = NDI_FAILURE;
14462                                 goto phys_create_done;
14463                         }
14464                 }
14465 phys_create_done:
14466                 /*
14467                  * If props were setup ok, online the lun
14468                  */
14469                 if (ndi_rtn == NDI_SUCCESS) {
14470                         /*
14471                          * Try to online the new node
14472                          */
14473                         ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
14474                 }









14475 
14476                 /*
14477                  * If success set rtn flag, else unwire alloc'd lun
14478                  */
14479                 if (ndi_rtn != NDI_SUCCESS) {
14480                         NDBG12(("mptsas driver unable to online "
14481                             "target %d lun %d", target, lun));
14482                         ndi_prop_remove_all(*lun_dip);
14483                         (void) ndi_devi_free(*lun_dip);
14484                         *lun_dip = NULL;
14485                 }
14486         }
14487 
14488         scsi_hba_nodename_compatible_free(nodename, compatible);
14489 
14490         if (wwn_str != NULL) {
14491                 kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
14492         }
14493         if (component != NULL) {
14494                 kmem_free(component, MAXPATHLEN);


15347 }
15348 static mptsas_target_t *
15349 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
15350 {
15351         uint8_t                 phynum;
15352         uint64_t                wwn;
15353         int                     lun;
15354         mptsas_target_t         *ptgt = NULL;
15355 
15356         if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
15357                 return (NULL);
15358         }
15359         if (addr[0] == 'w') {
15360                 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
15361         } else {
15362                 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
15363         }
15364         return (ptgt);
15365 }
15366 









































































15367 int
15368 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr,
15369     ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp,
15370     uint32_t alloc_size, ddi_dma_cookie_t *cookiep)
15371 {
15372         ddi_dma_cookie_t        new_cookie;
15373         size_t                  alloc_len;
15374         uint_t                  ncookie;
15375 
15376         if (cookiep == NULL)
15377                 cookiep = &new_cookie;
15378 
15379         if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP,
15380             NULL, dma_hdp) != DDI_SUCCESS) {
15381                 dma_hdp = NULL;
15382                 return (FALSE);
15383         }
15384 
15385         if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr,
15386             DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len,