Print this page
9702 HBA drivers don't need the redundant devfs_clean step
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>


  85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  90 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
  91 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
  92 #pragma pack()
  93 
  94 /*
  95  * private header files.
  96  *
  97  */
  98 #include <sys/scsi/impl/scsi_reset_notify.h>
  99 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
 100 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
 101 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
 102 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
 103 #include <sys/raidioctl.h>
 104 
 105 #include <sys/fs/dv_node.h>       /* devfs_clean */
 106 
 107 /*
 108  * FMA header files
 109  */
 110 #include <sys/ddifm.h>
 111 #include <sys/fm/protocol.h>
 112 #include <sys/fm/util.h>
 113 #include <sys/fm/io/ddi.h>
 114 
 115 /*
 116  * autoconfiguration data and routines.
 117  */
 118 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
 119 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
 120 static int mptsas_power(dev_info_t *dip, int component, int level);
 121 
 122 /*
 123  * cb_ops function
 124  */
 125 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
 126         cred_t *credp, int *rval);


 380 static int mptsas_offline_target(dev_info_t *pdip, char *name);
 381 
 382 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
 383     dev_info_t **dip);
 384 
 385 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
 386 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
 387     dev_info_t **dip, mptsas_target_t *ptgt);
 388 
 389 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
 390     dev_info_t **dip, mptsas_target_t *ptgt, int lun);
 391 
 392 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
 393     char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
 394 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
 395     char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
 396     int lun);
 397 
 398 static void mptsas_offline_missed_luns(dev_info_t *pdip,
 399     uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
 400 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
 401     mdi_pathinfo_t *rpip, uint_t flags);
 402 
 403 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
 404     dev_info_t **smp_dip);
 405 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
 406     uint_t flags);
 407 
 408 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
 409     int mode, int *rval);
 410 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
 411     int mode, int *rval);
 412 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
 413     int mode, int *rval);
 414 static void mptsas_record_event(void *args);
 415 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
 416     int mode);
 417 
 418 mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t, uint64_t,
 419     uint32_t, mptsas_phymask_t, uint8_t);
 420 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
 421 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
 422     dev_info_t **smp_dip);
 423 
 424 /*
 425  * Power management functions
 426  */


6874 
6875                 mutex_enter(&mpt->m_mutex);
6876                 break;
6877         }
6878         case MPTSAS_DR_EVENT_OFFLINE_SMP:
6879         {
6880                 devhdl = topo_node->devhdl;
6881                 uint32_t dev_info;
6882 
6883                 psmp = refhash_linear_search(mpt->m_smp_targets,
6884                     mptsas_smp_eval_devhdl, &devhdl);
6885                 if (psmp == NULL)
6886                         break;
6887                 /*
6888                  * The mptsas_smp_t data is released only if the dip is offlined
6889                  * successfully.
6890                  */
6891                 mutex_exit(&mpt->m_mutex);
6892 
6893                 ndi_devi_enter(parent, &circ1);
6894                 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6895                 ndi_devi_exit(parent, circ1);
6896 
6897                 dev_info = psmp->m_deviceinfo;
6898                 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6899                     DEVINFO_DIRECT_ATTACHED) {
6900                         if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6901                             MPTSAS_VIRTUAL_PORT, 1) !=
6902                             DDI_PROP_SUCCESS) {
6903                                 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6904                                     MPTSAS_VIRTUAL_PORT);
6905                                 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6906                                     "prop update failed");
6907                                 mutex_enter(&mpt->m_mutex);
6908                                 return;
6909                         }
6910                         /*
6911                          * Check whether the smp connected to the iport,
6912                          */
6913                         if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6914                             MPTSAS_NUM_PHYS, 0) !=


14676 
14677                 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
14678                     DDI_SUCCESS) {
14679                         continue;
14680                 }
14681 
14682                 if (wwid == sas_wwn) {
14683                         for (i = 0; i < lun_cnt; i++) {
14684                                 if (repluns[i] == lun) {
14685                                         find = 1;
14686                                         break;
14687                                 }
14688                         }
14689                 } else {
14690                         continue;
14691                 }
14692                 if (find == 0) {
14693                         /*
14694                          * The lun has not been there already
14695                          */
14696                         (void) mptsas_offline_lun(pdip, savechild, NULL,
14697                             NDI_DEVI_REMOVE);
14698                 }
14699         }
14700 
14701         pip = mdi_get_next_client_path(pdip, NULL);
14702         while (pip) {
14703                 find = 0;
14704                 savepip = pip;
14705                 addr = MDI_PI(pip)->pi_addr;
14706 
14707                 pip = mdi_get_next_client_path(pdip, pip);
14708 
14709                 if (addr == NULL) {
14710                         continue;
14711                 }
14712 
14713                 if (mptsas_parse_address(addr, &sas_wwn, &phy,
14714                     &lun) != DDI_SUCCESS) {
14715                         continue;
14716                 }
14717 
14718                 if (sas_wwn == wwid) {
14719                         for (i = 0; i < lun_cnt; i++) {
14720                                 if (repluns[i] == lun) {
14721                                         find = 1;
14722                                         break;
14723                                 }
14724                         }
14725                 } else {
14726                         continue;
14727                 }
14728 
14729                 if (find == 0) {
14730                         /*
14731                          * The lun has not been there already
14732                          */
14733                         (void) mptsas_offline_lun(pdip, NULL, savepip,
14734                             NDI_DEVI_REMOVE);
14735                 }
14736         }
14737 }
14738 
14739 /*
14740  * If this enclosure doesn't exist in the enclosure list, add it. If it does,
14741  * update it.
14742  */
14743 static void
14744 mptsas_enclosure_update(mptsas_t *mpt, mptsas_enclosure_t *mep)
14745 {
14746         mptsas_enclosure_t *m;
14747 
14748         ASSERT(MUTEX_HELD(&mpt->m_mutex));
14749         m = mptsas_enc_lookup(mpt, mep->me_enchdl);
14750         if (m != NULL) {
14751                 uint8_t *ledp;
14752                 m->me_flags = mep->me_flags;
14753 
14754 


15008 
15009         child = ddi_get_child(pdip);
15010         while (child) {
15011                 addr = ddi_get_name_addr(child);
15012                 prechild = child;
15013                 child = ddi_get_next_sibling(child);
15014 
15015                 if (addr == NULL) {
15016                         continue;
15017                 }
15018                 if ((cp = strchr(addr, ',')) == NULL) {
15019                         continue;
15020                 }
15021 
15022                 s = (uintptr_t)cp - (uintptr_t)addr;
15023 
15024                 if (strncmp(addr, name, s) != 0) {
15025                         continue;
15026                 }
15027 
15028                 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
15029                     NDI_DEVI_REMOVE);
15030                 if (tmp_rval != DDI_SUCCESS) {
15031                         rval = DDI_FAILURE;
15032                         if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15033                             prechild, MPTSAS_DEV_GONE) !=
15034                             DDI_PROP_SUCCESS) {
15035                                 mptsas_log(mpt, CE_WARN, "mptsas driver "
15036                                     "unable to create property for "
15037                                     "SAS %s (MPTSAS_DEV_GONE)", addr);
15038                         }
15039                 }
15040         }
15041 
15042         pip = mdi_get_next_client_path(pdip, NULL);
15043         while (pip) {
15044                 addr = MDI_PI(pip)->pi_addr;
15045                 savepip = pip;
15046                 pip = mdi_get_next_client_path(pdip, pip);
15047                 if (addr == NULL) {
15048                         continue;
15049                 }
15050 
15051                 if ((cp = strchr(addr, ',')) == NULL) {
15052                         continue;
15053                 }
15054 
15055                 s = (uintptr_t)cp - (uintptr_t)addr;
15056 
15057                 if (strncmp(addr, name, s) != 0) {
15058                         continue;
15059                 }
15060 
15061                 (void) mptsas_offline_lun(pdip, NULL, savepip,
15062                     NDI_DEVI_REMOVE);
15063                 /*
15064                  * driver will not invoke mdi_pi_free, so path will not
15065                  * be freed forever, return DDI_FAILURE.
15066                  */
15067                 rval = DDI_FAILURE;
15068         }
15069         return (rval);
15070 }
15071 
15072 static int
15073 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
15074     mdi_pathinfo_t *rpip, uint_t flags)
15075 {
15076         int             rval = DDI_FAILURE;
15077         char            *devname;
15078         dev_info_t      *cdip, *parent;
15079 
15080         if (rpip != NULL) {
15081                 parent = scsi_vhci_dip;
15082                 cdip = mdi_pi_get_client(rpip);
15083         } else if (rdip != NULL) {
15084                 parent = pdip;
15085                 cdip = rdip;
15086         } else {
15087                 return (DDI_FAILURE);
15088         }
15089 
15090         /*
15091          * Make sure node is attached otherwise
15092          * it won't have related cache nodes to
15093          * clean up.  i_ddi_devi_attached is
15094          * similiar to i_ddi_node_state(cdip) >=
15095          * DS_ATTACHED.
15096          */
15097         if (i_ddi_devi_attached(cdip)) {
15098 
15099                 /* Get full devname */
15100                 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
15101                 (void) ddi_deviname(cdip, devname);
15102                 /* Clean cache */
15103                 (void) devfs_clean(parent, devname + 1,
15104                     DV_CLEAN_FORCE);
15105                 kmem_free(devname, MAXNAMELEN + 1);
15106         }
15107         if (rpip != NULL) {
15108                 if (MDI_PI_IS_OFFLINE(rpip)) {
15109                         rval = DDI_SUCCESS;
15110                 } else {
15111                         rval = mdi_pi_offline(rpip, 0);
15112                 }
15113         } else {
15114                 rval = ndi_devi_offline(cdip, flags);

15115         }
15116 
15117         return (rval);
15118 }
15119 
15120 static dev_info_t *
15121 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
15122 {
15123         dev_info_t      *child = NULL;
15124         char            *smp_wwn = NULL;
15125 
15126         child = ddi_get_child(parent);
15127         while (child) {
15128                 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
15129                     DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
15130                     != DDI_SUCCESS) {
15131                         child = ddi_get_next_sibling(child);
15132                         continue;
15133                 }
15134 
15135                 if (strcmp(smp_wwn, str_wwn) == 0) {
15136                         ddi_prop_free(smp_wwn);
15137                         break;
15138                 }
15139                 child = ddi_get_next_sibling(child);
15140                 ddi_prop_free(smp_wwn);
15141         }
15142         return (child);
15143 }
15144 
15145 static int
15146 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
15147 {
15148         int             rval = DDI_FAILURE;
15149         char            *devname;
15150         char            wwn_str[MPTSAS_WWN_STRLEN];
15151         dev_info_t      *cdip;
15152 
15153         (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
15154 
15155         cdip = mptsas_find_smp_child(pdip, wwn_str);
15156 
15157         if (cdip == NULL)
15158                 return (DDI_SUCCESS);
15159 
15160         /*
15161          * Make sure node is attached otherwise
15162          * it won't have related cache nodes to
15163          * clean up.  i_ddi_devi_attached is
15164          * similiar to i_ddi_node_state(cdip) >=
15165          * DS_ATTACHED.
15166          */
15167         if (i_ddi_devi_attached(cdip)) {
15168 
15169                 /* Get full devname */
15170                 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
15171                 (void) ddi_deviname(cdip, devname);
15172                 /* Clean cache */
15173                 (void) devfs_clean(pdip, devname + 1,
15174                     DV_CLEAN_FORCE);
15175                 kmem_free(devname, MAXNAMELEN + 1);
15176         }
15177 
15178         rval = ndi_devi_offline(cdip, flags);
15179 
15180         return (rval);
15181 }
15182 
15183 static dev_info_t *
15184 mptsas_find_child(dev_info_t *pdip, char *name)
15185 {
15186         dev_info_t      *child = NULL;
15187         char            *rname = NULL;
15188         int             rval = DDI_FAILURE;
15189 
15190         rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15191 
15192         child = ddi_get_child(pdip);
15193         while (child) {
15194                 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
15195                 if (rval != DDI_SUCCESS) {
15196                         child = ddi_get_next_sibling(child);
15197                         bzero(rname, SCSI_MAXNAMELEN);
15198                         continue;
15199                 }




  85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
  86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
  87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
  88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
  89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
  90 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
  91 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
  92 #pragma pack()
  93 
  94 /*
  95  * private header files.
  96  *
  97  */
  98 #include <sys/scsi/impl/scsi_reset_notify.h>
  99 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
 100 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
 101 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
 102 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
 103 #include <sys/raidioctl.h>
 104 


 105 /*
 106  * FMA header files
 107  */
 108 #include <sys/ddifm.h>
 109 #include <sys/fm/protocol.h>
 110 #include <sys/fm/util.h>
 111 #include <sys/fm/io/ddi.h>
 112 
 113 /*
 114  * autoconfiguration data and routines.
 115  */
 116 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
 117 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
 118 static int mptsas_power(dev_info_t *dip, int component, int level);
 119 
 120 /*
 121  * cb_ops function
 122  */
 123 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
 124         cred_t *credp, int *rval);


 378 static int mptsas_offline_target(dev_info_t *pdip, char *name);
 379 
 380 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
 381     dev_info_t **dip);
 382 
 383 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
 384 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
 385     dev_info_t **dip, mptsas_target_t *ptgt);
 386 
 387 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
 388     dev_info_t **dip, mptsas_target_t *ptgt, int lun);
 389 
 390 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
 391     char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
 392 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
 393     char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
 394     int lun);
 395 
 396 static void mptsas_offline_missed_luns(dev_info_t *pdip,
 397     uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
 398 static int mptsas_offline_lun(dev_info_t *rdip, mdi_pathinfo_t *rpip);

 399 
 400 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
 401     dev_info_t **smp_dip);
 402 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node);

 403 
 404 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
 405     int mode, int *rval);
 406 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
 407     int mode, int *rval);
 408 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
 409     int mode, int *rval);
 410 static void mptsas_record_event(void *args);
 411 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
 412     int mode);
 413 
 414 mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t, uint64_t,
 415     uint32_t, mptsas_phymask_t, uint8_t);
 416 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
 417 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
 418     dev_info_t **smp_dip);
 419 
 420 /*
 421  * Power management functions
 422  */


6870 
6871                 mutex_enter(&mpt->m_mutex);
6872                 break;
6873         }
6874         case MPTSAS_DR_EVENT_OFFLINE_SMP:
6875         {
6876                 devhdl = topo_node->devhdl;
6877                 uint32_t dev_info;
6878 
6879                 psmp = refhash_linear_search(mpt->m_smp_targets,
6880                     mptsas_smp_eval_devhdl, &devhdl);
6881                 if (psmp == NULL)
6882                         break;
6883                 /*
6884                  * The mptsas_smp_t data is released only if the dip is offlined
6885                  * successfully.
6886                  */
6887                 mutex_exit(&mpt->m_mutex);
6888 
6889                 ndi_devi_enter(parent, &circ1);
6890                 rval = mptsas_offline_smp(parent, psmp);
6891                 ndi_devi_exit(parent, circ1);
6892 
6893                 dev_info = psmp->m_deviceinfo;
6894                 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6895                     DEVINFO_DIRECT_ATTACHED) {
6896                         if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6897                             MPTSAS_VIRTUAL_PORT, 1) !=
6898                             DDI_PROP_SUCCESS) {
6899                                 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6900                                     MPTSAS_VIRTUAL_PORT);
6901                                 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6902                                     "prop update failed");
6903                                 mutex_enter(&mpt->m_mutex);
6904                                 return;
6905                         }
6906                         /*
6907                          * Check whether the smp connected to the iport,
6908                          */
6909                         if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6910                             MPTSAS_NUM_PHYS, 0) !=


14672 
14673                 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
14674                     DDI_SUCCESS) {
14675                         continue;
14676                 }
14677 
14678                 if (wwid == sas_wwn) {
14679                         for (i = 0; i < lun_cnt; i++) {
14680                                 if (repluns[i] == lun) {
14681                                         find = 1;
14682                                         break;
14683                                 }
14684                         }
14685                 } else {
14686                         continue;
14687                 }
14688                 if (find == 0) {
14689                         /*
14690                          * The lun has not been there already
14691                          */
14692                         (void) mptsas_offline_lun(savechild, NULL);

14693                 }
14694         }
14695 
14696         pip = mdi_get_next_client_path(pdip, NULL);
14697         while (pip) {
14698                 find = 0;
14699                 savepip = pip;
14700                 addr = MDI_PI(pip)->pi_addr;
14701 
14702                 pip = mdi_get_next_client_path(pdip, pip);
14703 
14704                 if (addr == NULL) {
14705                         continue;
14706                 }
14707 
14708                 if (mptsas_parse_address(addr, &sas_wwn, &phy,
14709                     &lun) != DDI_SUCCESS) {
14710                         continue;
14711                 }
14712 
14713                 if (sas_wwn == wwid) {
14714                         for (i = 0; i < lun_cnt; i++) {
14715                                 if (repluns[i] == lun) {
14716                                         find = 1;
14717                                         break;
14718                                 }
14719                         }
14720                 } else {
14721                         continue;
14722                 }
14723 
14724                 if (find == 0) {
14725                         /*
14726                          * The lun has not been there already
14727                          */
14728                         (void) mptsas_offline_lun(NULL, savepip);

14729                 }
14730         }
14731 }
14732 
14733 /*
14734  * If this enclosure doesn't exist in the enclosure list, add it. If it does,
14735  * update it.
14736  */
14737 static void
14738 mptsas_enclosure_update(mptsas_t *mpt, mptsas_enclosure_t *mep)
14739 {
14740         mptsas_enclosure_t *m;
14741 
14742         ASSERT(MUTEX_HELD(&mpt->m_mutex));
14743         m = mptsas_enc_lookup(mpt, mep->me_enchdl);
14744         if (m != NULL) {
14745                 uint8_t *ledp;
14746                 m->me_flags = mep->me_flags;
14747 
14748 


15002 
15003         child = ddi_get_child(pdip);
15004         while (child) {
15005                 addr = ddi_get_name_addr(child);
15006                 prechild = child;
15007                 child = ddi_get_next_sibling(child);
15008 
15009                 if (addr == NULL) {
15010                         continue;
15011                 }
15012                 if ((cp = strchr(addr, ',')) == NULL) {
15013                         continue;
15014                 }
15015 
15016                 s = (uintptr_t)cp - (uintptr_t)addr;
15017 
15018                 if (strncmp(addr, name, s) != 0) {
15019                         continue;
15020                 }
15021 
15022                 tmp_rval = mptsas_offline_lun(prechild, NULL);

15023                 if (tmp_rval != DDI_SUCCESS) {
15024                         rval = DDI_FAILURE;
15025                         if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
15026                             prechild, MPTSAS_DEV_GONE) !=
15027                             DDI_PROP_SUCCESS) {
15028                                 mptsas_log(mpt, CE_WARN, "mptsas driver "
15029                                     "unable to create property for "
15030                                     "SAS %s (MPTSAS_DEV_GONE)", addr);
15031                         }
15032                 }
15033         }
15034 
15035         pip = mdi_get_next_client_path(pdip, NULL);
15036         while (pip) {
15037                 addr = MDI_PI(pip)->pi_addr;
15038                 savepip = pip;
15039                 pip = mdi_get_next_client_path(pdip, pip);
15040                 if (addr == NULL) {
15041                         continue;
15042                 }
15043 
15044                 if ((cp = strchr(addr, ',')) == NULL) {
15045                         continue;
15046                 }
15047 
15048                 s = (uintptr_t)cp - (uintptr_t)addr;
15049 
15050                 if (strncmp(addr, name, s) != 0) {
15051                         continue;
15052                 }
15053 
15054                 (void) mptsas_offline_lun(NULL, savepip);

15055                 /*
15056                  * driver will not invoke mdi_pi_free, so path will not
15057                  * be freed forever, return DDI_FAILURE.
15058                  */
15059                 rval = DDI_FAILURE;
15060         }
15061         return (rval);
15062 }
15063 
15064 static int
15065 mptsas_offline_lun(dev_info_t *rdip, mdi_pathinfo_t *rpip)

15066 {
15067         int             rval = DDI_FAILURE;


15068 
15069         if (rpip != NULL) {



























15070                 if (MDI_PI_IS_OFFLINE(rpip)) {
15071                         rval = DDI_SUCCESS;
15072                 } else {
15073                         rval = mdi_pi_offline(rpip, 0);
15074                 }
15075         } else if (rdip != NULL) {
15076                 rval = ndi_devi_offline(rdip,
15077                     NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE);
15078         }
15079 
15080         return (rval);
15081 }
15082 
15083 static dev_info_t *
15084 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
15085 {
15086         dev_info_t      *child = NULL;
15087         char            *smp_wwn = NULL;
15088 
15089         child = ddi_get_child(parent);
15090         while (child) {
15091                 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
15092                     DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
15093                     != DDI_SUCCESS) {
15094                         child = ddi_get_next_sibling(child);
15095                         continue;
15096                 }
15097 
15098                 if (strcmp(smp_wwn, str_wwn) == 0) {
15099                         ddi_prop_free(smp_wwn);
15100                         break;
15101                 }
15102                 child = ddi_get_next_sibling(child);
15103                 ddi_prop_free(smp_wwn);
15104         }
15105         return (child);
15106 }
15107 
15108 static int
15109 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node)
15110 {
15111         int             rval = DDI_FAILURE;

15112         char            wwn_str[MPTSAS_WWN_STRLEN];
15113         dev_info_t      *cdip;
15114 
15115         (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
15116 
15117         cdip = mptsas_find_smp_child(pdip, wwn_str);

15118         if (cdip == NULL)
15119                 return (DDI_SUCCESS);
15120 
15121         rval = ndi_devi_offline(cdip, NDI_DEVFS_CLEAN | NDI_DEVI_REMOVE);







15122 











15123         return (rval);
15124 }
15125 
15126 static dev_info_t *
15127 mptsas_find_child(dev_info_t *pdip, char *name)
15128 {
15129         dev_info_t      *child = NULL;
15130         char            *rname = NULL;
15131         int             rval = DDI_FAILURE;
15132 
15133         rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
15134 
15135         child = ddi_get_child(pdip);
15136         while (child) {
15137                 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
15138                 if (rval != DDI_SUCCESS) {
15139                         child = ddi_get_next_sibling(child);
15140                         bzero(rname, SCSI_MAXNAMELEN);
15141                         continue;
15142                 }