354 uint8_t phy);
355 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
356 uint64_t wwid);
357 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
358 uint64_t wwid);
359
360 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
361 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
362
363 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
364 uint16_t *handle, mptsas_target_t **pptgt);
365 static void mptsas_update_phymask(mptsas_t *mpt);
366 static inline void mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd);
367
368 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
369 uint32_t *status, uint8_t cmd);
370 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
371 mptsas_phymask_t *phymask);
372 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
373 mptsas_phymask_t phymask);
374 static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
375 uint32_t slotstatus);
376
377
378 /*
379 * Enumeration / DR functions
380 */
381 static void mptsas_config_all(dev_info_t *pdip);
382 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
383 dev_info_t **lundip);
384 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
385 dev_info_t **lundip);
386
387 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
388 static int mptsas_offline_target(dev_info_t *pdip, char *name);
389
390 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
391 dev_info_t **dip);
392
393 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
394 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
395 dev_info_t **dip, mptsas_target_t *ptgt);
6436 MPTSAS_NUM_PHYS, 0) !=
6437 DDI_PROP_SUCCESS) {
6438 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6439 MPTSAS_NUM_PHYS);
6440 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6441 "prop update failed");
6442 break;
6443 }
6444 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6445 MPTSAS_VIRTUAL_PORT, 1) !=
6446 DDI_PROP_SUCCESS) {
6447 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6448 MPTSAS_VIRTUAL_PORT);
6449 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6450 "prop update failed");
6451 break;
6452 }
6453 }
6454
6455 mutex_enter(&mpt->m_mutex);
6456 if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) {
6457 NDBG14(("mptsas: clear LED for tgt %x failed",
6458 ptgt->m_slot_num));
6459 }
6460 if (rval == DDI_SUCCESS) {
6461 mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6462 ptgt->m_sas_wwn, ptgt->m_phymask);
6463 ptgt = NULL;
6464 } else {
6465 /*
6466 * clean DR_INTRANSITION flag to allow I/O down to
6467 * PHCI driver since failover finished.
6468 * Invalidate the devhdl
6469 */
6470 mutex_enter(&ptgt->m_tgt_intr_mutex);
6471 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6472 ptgt->m_tgt_unconfigured = 0;
6473 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6474 mutex_exit(&ptgt->m_tgt_intr_mutex);
6475 }
6476
11936 case REG_MEM_WRITE:
11937 ddi_put32(mpt->m_datap,
11938 (uint32_t *)(void *)mpt->m_reg +
11939 driverdata.RegOffset,
11940 driverdata.RegData);
11941 break;
11942
11943 default:
11944 status = EINVAL;
11945 break;
11946 }
11947 } else {
11948 status = EFAULT;
11949 }
11950
11951 mutex_exit(&mpt->m_mutex);
11952 return (status);
11953 }
11954
11955 static int
11956 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
11957 {
11958 int i = 0;
11959 int count = 0;
11960 int ret = 0;
11961 mptsas_target_t *ptgt;
11962 mptsas_disk_info_t *di;
11963 STRUCT_DECL(mptsas_get_disk_info, gdi);
11964
11965 STRUCT_INIT(gdi, get_udatamodel());
11966
11967 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
11968 mode) != 0) {
11969 return (EFAULT);
11970 }
11971
11972 /* Find out how many targets there are. */
11973 mutex_enter(&mpt->m_mutex);
11974 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11975 MPTSAS_HASH_FIRST);
12112 if ((cmd == DEVCTL_DEVICE_ONLINE) ||
12113 (cmd == DEVCTL_DEVICE_OFFLINE)) {
12114 if (ndi_dc_allochdl((void *)data, &dcp) !=
12115 NDI_SUCCESS) {
12116 goto out;
12117 }
12118 addr = ndi_dc_getaddr(dcp);
12119 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12120 if (ptgt == NULL) {
12121 NDBG14(("mptsas_ioctl led control: tgt %s not "
12122 "found", addr));
12123 ndi_dc_freehdl(dcp);
12124 goto out;
12125 }
12126 mutex_enter(&mpt->m_mutex);
12127 if (cmd == DEVCTL_DEVICE_ONLINE) {
12128 ptgt->m_tgt_unconfigured = 0;
12129 } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12130 ptgt->m_tgt_unconfigured = 1;
12131 }
12132 slotstatus = 0;
12133 #ifdef MPTSAS_GET_LED
12134 /*
12135 * The get led status can't get a valid/reasonable
12136 * state, so ignore the get led status, and write the
12137 * required value directly
12138 */
12139 if (mptsas_get_led_status(mpt, ptgt, &slotstatus) !=
12140 DDI_SUCCESS) {
12141 NDBG14(("mptsas_ioctl: get LED for tgt %s "
12142 "failed %x", addr, slotstatus));
12143 slotstatus = 0;
12144 }
12145 NDBG14(("mptsas_ioctl: LED status %x for %s",
12146 slotstatus, addr));
12147 #endif
12148 if (cmd == DEVCTL_DEVICE_OFFLINE) {
12149 slotstatus |=
12150 MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12151 } else {
12152 slotstatus &=
12153 ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
12154 }
12155 if (mptsas_set_led_status(mpt, ptgt, slotstatus) !=
12156 DDI_SUCCESS) {
12157 NDBG14(("mptsas_ioctl: set LED for tgt %s "
12158 "failed %x", addr, slotstatus));
12159 }
12160 mutex_exit(&mpt->m_mutex);
12161 ndi_dc_freehdl(dcp);
12162 }
12163 goto out;
12164 }
12165 switch (cmd) {
12166 case MPTIOCTL_GET_DISK_INFO:
12167 status = get_disk_info(mpt, data, mode);
12168 break;
12169 case MPTIOCTL_UPDATE_FLASH:
12170 if (ddi_copyin((void *)data, &flashdata,
12171 sizeof (struct mptsas_update_flash), mode)) {
12172 status = EFAULT;
12173 break;
12174 }
12175
12176 mutex_enter(&mpt->m_mutex);
12177 if (mptsas_update_flash(mpt,
12178 (caddr_t)(long)flashdata.PtrBuffer,
12179 flashdata.ImageSize, flashdata.ImageType, mode)) {
12180 status = EFAULT;
12181 }
12182
12183 /*
12184 * Reset the chip to start using the new
12185 * firmware. Reset if failed also.
12186 */
12187 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12188 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
14609 } else {
14610 *pip = mptsas_find_path_phy(pdip, phy);
14611 }
14612
14613 if (*pip != NULL) {
14614 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
14615 ASSERT(*lun_dip != NULL);
14616 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
14617 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
14618 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
14619 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14620 /*
14621 * Same path back online again.
14622 */
14623 (void) ddi_prop_free(old_guid);
14624 if ((!MDI_PI_IS_ONLINE(*pip)) &&
14625 (!MDI_PI_IS_STANDBY(*pip)) &&
14626 (ptgt->m_tgt_unconfigured == 0)) {
14627 rval = mdi_pi_online(*pip, 0);
14628 mutex_enter(&mpt->m_mutex);
14629 (void) mptsas_set_led_status(mpt, ptgt,
14630 0);
14631 mutex_exit(&mpt->m_mutex);
14632 } else {
14633 rval = DDI_SUCCESS;
14634 }
14635 if (rval != DDI_SUCCESS) {
14636 mptsas_log(mpt, CE_WARN, "path:target: "
14637 "%x, lun:%x online failed!", target,
14638 lun);
14639 *pip = NULL;
14640 *lun_dip = NULL;
14641 }
14642 return (rval);
14643 } else {
14644 /*
14645 * The GUID of the LUN has changed which maybe
14646 * because customer mapped another volume to the
14647 * same LUN.
14648 */
14649 mptsas_log(mpt, CE_WARN, "The GUID of the "
14650 "target:%x, lun:%x was changed, maybe "
14867 "property, target %d", target);
14868 mdi_rtn = MDI_FAILURE;
14869 goto virt_create_done;
14870 }
14871 }
14872 /*
14873 * Create the phy-num property
14874 */
14875 if (mdi_prop_update_int(*pip, "phy-num",
14876 ptgt->m_phynum) != DDI_SUCCESS) {
14877 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14878 "create phy-num property for target %d lun %d",
14879 target, lun);
14880 mdi_rtn = MDI_FAILURE;
14881 goto virt_create_done;
14882 }
14883 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
14884 mdi_rtn = mdi_pi_online(*pip, 0);
14885 if (mdi_rtn == MDI_SUCCESS) {
14886 mutex_enter(&mpt->m_mutex);
14887 if (mptsas_set_led_status(mpt, ptgt, 0) !=
14888 DDI_SUCCESS) {
14889 NDBG14(("mptsas: clear LED for slot %x "
14890 "failed", ptgt->m_slot_num));
14891 }
14892 mutex_exit(&mpt->m_mutex);
14893 }
14894 if (mdi_rtn == MDI_NOT_SUPPORTED) {
14895 mdi_rtn = MDI_FAILURE;
14896 }
14897 virt_create_done:
14898 if (*pip && mdi_rtn != MDI_SUCCESS) {
14899 (void) mdi_pi_free(*pip, 0);
14900 *pip = NULL;
14901 *lun_dip = NULL;
14902 }
14903 }
14904
14905 scsi_hba_nodename_compatible_free(nodename, compatible);
14906 if (lun_addr != NULL) {
14907 kmem_free(lun_addr, SCSI_MAXNAMELEN);
14908 }
15229 DDI_PROP_SUCCESS) {
15230 mptsas_log(mpt, CE_WARN, "mptsas driver "
15231 "failed to create phy-num property for "
15232 "target %d", target);
15233 ndi_rtn = NDI_FAILURE;
15234 goto phys_create_done;
15235 }
15236 }
15237 phys_create_done:
15238 /*
15239 * If props were setup ok, online the lun
15240 */
15241 if (ndi_rtn == NDI_SUCCESS) {
15242 /*
15243 * Try to online the new node
15244 */
15245 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15246 }
15247 if (ndi_rtn == NDI_SUCCESS) {
15248 mutex_enter(&mpt->m_mutex);
15249 if (mptsas_set_led_status(mpt, ptgt, 0) !=
15250 DDI_SUCCESS) {
15251 NDBG14(("mptsas: clear LED for tgt %x "
15252 "failed", ptgt->m_slot_num));
15253 }
15254 mutex_exit(&mpt->m_mutex);
15255 }
15256
15257 /*
15258 * If success set rtn flag, else unwire alloc'd lun
15259 */
15260 if (ndi_rtn != NDI_SUCCESS) {
15261 NDBG12(("mptsas driver unable to online "
15262 "target %d lun %d", target, lun));
15263 ndi_prop_remove_all(*lun_dip);
15264 (void) ndi_devi_free(*lun_dip);
15265 *lun_dip = NULL;
15266 }
15267 }
15268
15269 scsi_hba_nodename_compatible_free(nodename, compatible);
15270
16131 }
16132 static mptsas_target_t *
16133 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16134 {
16135 uint8_t phynum;
16136 uint64_t wwn;
16137 int lun;
16138 mptsas_target_t *ptgt = NULL;
16139
16140 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
16141 return (NULL);
16142 }
16143 if (addr[0] == 'w') {
16144 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16145 } else {
16146 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16147 }
16148 return (ptgt);
16149 }
16150
16151 #ifdef MPTSAS_GET_LED
16152 static int
16153 mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt,
16154 uint32_t *slotstatus)
16155 {
16156 return (mptsas_send_sep(mpt, ptgt, slotstatus,
16157 MPI2_SEP_REQ_ACTION_READ_STATUS));
16158 }
16159 #endif
16160 static int
16161 mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus)
16162 {
16163 NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16164 slotstatus, ptgt->m_slot_num));
16165 return (mptsas_send_sep(mpt, ptgt, &slotstatus,
16166 MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16167 }
16168 /*
16169 * send sep request, use enclosure/slot addressing
16170 */
16171 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
16172 uint32_t *status, uint8_t act)
16173 {
16174 Mpi2SepRequest_t req;
16175 Mpi2SepReply_t rep;
16176 int ret;
16177
16178 ASSERT(mutex_owned(&mpt->m_mutex));
16179
16180 bzero(&req, sizeof (req));
16181 bzero(&rep, sizeof (rep));
16182
16183 /* Do nothing for RAID volumes */
16184 if (ptgt->m_phymask == 0) {
16185 NDBG14(("mptsas_send_sep: Skip RAID volumes"));
16186 return (DDI_FAILURE);
16187 }
|
354 uint8_t phy);
355 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
356 uint64_t wwid);
357 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
358 uint64_t wwid);
359
360 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
361 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
362
363 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
364 uint16_t *handle, mptsas_target_t **pptgt);
365 static void mptsas_update_phymask(mptsas_t *mpt);
366 static inline void mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd);
367
368 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
369 uint32_t *status, uint8_t cmd);
370 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
371 mptsas_phymask_t *phymask);
372 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
373 mptsas_phymask_t phymask);
374 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
375
376
377 /*
378 * Enumeration / DR functions
379 */
380 static void mptsas_config_all(dev_info_t *pdip);
381 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
382 dev_info_t **lundip);
383 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
384 dev_info_t **lundip);
385
386 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
387 static int mptsas_offline_target(dev_info_t *pdip, char *name);
388
389 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
390 dev_info_t **dip);
391
392 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
393 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
394 dev_info_t **dip, mptsas_target_t *ptgt);
6435 MPTSAS_NUM_PHYS, 0) !=
6436 DDI_PROP_SUCCESS) {
6437 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6438 MPTSAS_NUM_PHYS);
6439 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6440 "prop update failed");
6441 break;
6442 }
6443 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6444 MPTSAS_VIRTUAL_PORT, 1) !=
6445 DDI_PROP_SUCCESS) {
6446 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6447 MPTSAS_VIRTUAL_PORT);
6448 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6449 "prop update failed");
6450 break;
6451 }
6452 }
6453
6454 mutex_enter(&mpt->m_mutex);
6455 ptgt->m_led_status = 0;
6456 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
6457 NDBG14(("mptsas: clear LED for tgt %x failed",
6458 ptgt->m_slot_num));
6459 }
6460 if (rval == DDI_SUCCESS) {
6461 mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6462 ptgt->m_sas_wwn, ptgt->m_phymask);
6463 ptgt = NULL;
6464 } else {
6465 /*
6466 * clean DR_INTRANSITION flag to allow I/O down to
6467 * PHCI driver since failover finished.
6468 * Invalidate the devhdl
6469 */
6470 mutex_enter(&ptgt->m_tgt_intr_mutex);
6471 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6472 ptgt->m_tgt_unconfigured = 0;
6473 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6474 mutex_exit(&ptgt->m_tgt_intr_mutex);
6475 }
6476
11936 case REG_MEM_WRITE:
11937 ddi_put32(mpt->m_datap,
11938 (uint32_t *)(void *)mpt->m_reg +
11939 driverdata.RegOffset,
11940 driverdata.RegData);
11941 break;
11942
11943 default:
11944 status = EINVAL;
11945 break;
11946 }
11947 } else {
11948 status = EFAULT;
11949 }
11950
11951 mutex_exit(&mpt->m_mutex);
11952 return (status);
11953 }
11954
11955 static int
11956 led_control(mptsas_t *mpt, intptr_t data, int mode)
11957 {
11958 int ret = 0;
11959 mptsas_led_control_t lc;
11960 mptsas_target_t *ptgt;
11961
11962 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
11963 return (EFAULT);
11964 }
11965
11966 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
11967 lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
11968 lc.Led < MPTSAS_LEDCTL_LED_IDENT ||
11969 lc.Led > MPTSAS_LEDCTL_LED_OK2RM ||
11970 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
11971 lc.LedStatus != 1)) {
11972 return (EINVAL);
11973 }
11974
11975 /* Locate the target we're interrogating... */
11976 mutex_enter(&mpt->m_mutex);
11977 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11978 MPTSAS_HASH_FIRST);
11979 while (ptgt != NULL) {
11980 if (ptgt->m_enclosure == lc.Enclosure &&
11981 ptgt->m_slot_num == lc.Slot) {
11982 break;
11983 }
11984 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11985 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11986 }
11987 if (ptgt == NULL) {
11988 /* We could not find a target for that enclosure/slot. */
11989 mutex_exit(&mpt->m_mutex);
11990 return (ENOENT);
11991 }
11992
11993 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
11994 /* Update our internal LED state. */
11995 ptgt->m_led_status &= ~(1 << (lc.Led - 1));
11996 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
11997
11998 /* Flush it to the controller. */
11999 ret = mptsas_flush_led_status(mpt, ptgt);
12000 mutex_exit(&mpt->m_mutex);
12001 return (ret);
12002 }
12003
12004 /* Return our internal LED state. */
12005 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
12006 mutex_exit(&mpt->m_mutex);
12007
12008 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) {
12009 return (EFAULT);
12010 }
12011
12012 return (0);
12013 }
12014
12015 static int
12016 get_disk_info(mptsas_t *mpt, intptr_t data, int mode)
12017 {
12018 int i = 0;
12019 int count = 0;
12020 int ret = 0;
12021 mptsas_target_t *ptgt;
12022 mptsas_disk_info_t *di;
12023 STRUCT_DECL(mptsas_get_disk_info, gdi);
12024
12025 STRUCT_INIT(gdi, get_udatamodel());
12026
12027 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
12028 mode) != 0) {
12029 return (EFAULT);
12030 }
12031
12032 /* Find out how many targets there are. */
12033 mutex_enter(&mpt->m_mutex);
12034 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12035 MPTSAS_HASH_FIRST);
12172 if ((cmd == DEVCTL_DEVICE_ONLINE) ||
12173 (cmd == DEVCTL_DEVICE_OFFLINE)) {
12174 if (ndi_dc_allochdl((void *)data, &dcp) !=
12175 NDI_SUCCESS) {
12176 goto out;
12177 }
12178 addr = ndi_dc_getaddr(dcp);
12179 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask);
12180 if (ptgt == NULL) {
12181 NDBG14(("mptsas_ioctl led control: tgt %s not "
12182 "found", addr));
12183 ndi_dc_freehdl(dcp);
12184 goto out;
12185 }
12186 mutex_enter(&mpt->m_mutex);
12187 if (cmd == DEVCTL_DEVICE_ONLINE) {
12188 ptgt->m_tgt_unconfigured = 0;
12189 } else if (cmd == DEVCTL_DEVICE_OFFLINE) {
12190 ptgt->m_tgt_unconfigured = 1;
12191 }
12192 if (cmd == DEVCTL_DEVICE_OFFLINE) {
12193 ptgt->m_led_status |=
12194 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12195 } else {
12196 ptgt->m_led_status &=
12197 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1));
12198 }
12199 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
12200 NDBG14(("mptsas_ioctl: set LED for tgt %s "
12201 "failed %x", addr, slotstatus));
12202 }
12203 mutex_exit(&mpt->m_mutex);
12204 ndi_dc_freehdl(dcp);
12205 }
12206 goto out;
12207 }
12208 switch (cmd) {
12209 case MPTIOCTL_GET_DISK_INFO:
12210 status = get_disk_info(mpt, data, mode);
12211 break;
12212 case MPTIOCTL_LED_CONTROL:
12213 status = led_control(mpt, data, mode);
12214 break;
12215 case MPTIOCTL_UPDATE_FLASH:
12216 if (ddi_copyin((void *)data, &flashdata,
12217 sizeof (struct mptsas_update_flash), mode)) {
12218 status = EFAULT;
12219 break;
12220 }
12221
12222 mutex_enter(&mpt->m_mutex);
12223 if (mptsas_update_flash(mpt,
12224 (caddr_t)(long)flashdata.PtrBuffer,
12225 flashdata.ImageSize, flashdata.ImageType, mode)) {
12226 status = EFAULT;
12227 }
12228
12229 /*
12230 * Reset the chip to start using the new
12231 * firmware. Reset if failed also.
12232 */
12233 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET;
12234 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
14655 } else {
14656 *pip = mptsas_find_path_phy(pdip, phy);
14657 }
14658
14659 if (*pip != NULL) {
14660 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
14661 ASSERT(*lun_dip != NULL);
14662 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
14663 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
14664 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
14665 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14666 /*
14667 * Same path back online again.
14668 */
14669 (void) ddi_prop_free(old_guid);
14670 if ((!MDI_PI_IS_ONLINE(*pip)) &&
14671 (!MDI_PI_IS_STANDBY(*pip)) &&
14672 (ptgt->m_tgt_unconfigured == 0)) {
14673 rval = mdi_pi_online(*pip, 0);
14674 mutex_enter(&mpt->m_mutex);
14675 ptgt->m_led_status = 0;
14676 (void) mptsas_flush_led_status(mpt,
14677 ptgt);
14678 mutex_exit(&mpt->m_mutex);
14679 } else {
14680 rval = DDI_SUCCESS;
14681 }
14682 if (rval != DDI_SUCCESS) {
14683 mptsas_log(mpt, CE_WARN, "path:target: "
14684 "%x, lun:%x online failed!", target,
14685 lun);
14686 *pip = NULL;
14687 *lun_dip = NULL;
14688 }
14689 return (rval);
14690 } else {
14691 /*
14692 * The GUID of the LUN has changed which maybe
14693 * because customer mapped another volume to the
14694 * same LUN.
14695 */
14696 mptsas_log(mpt, CE_WARN, "The GUID of the "
14697 "target:%x, lun:%x was changed, maybe "
14914 "property, target %d", target);
14915 mdi_rtn = MDI_FAILURE;
14916 goto virt_create_done;
14917 }
14918 }
14919 /*
14920 * Create the phy-num property
14921 */
14922 if (mdi_prop_update_int(*pip, "phy-num",
14923 ptgt->m_phynum) != DDI_SUCCESS) {
14924 mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
14925 "create phy-num property for target %d lun %d",
14926 target, lun);
14927 mdi_rtn = MDI_FAILURE;
14928 goto virt_create_done;
14929 }
14930 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
14931 mdi_rtn = mdi_pi_online(*pip, 0);
14932 if (mdi_rtn == MDI_SUCCESS) {
14933 mutex_enter(&mpt->m_mutex);
14934 ptgt->m_led_status = 0;
14935 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
14936 NDBG14(("mptsas: clear LED for slot %x "
14937 "failed", ptgt->m_slot_num));
14938 }
14939 mutex_exit(&mpt->m_mutex);
14940 }
14941 if (mdi_rtn == MDI_NOT_SUPPORTED) {
14942 mdi_rtn = MDI_FAILURE;
14943 }
14944 virt_create_done:
14945 if (*pip && mdi_rtn != MDI_SUCCESS) {
14946 (void) mdi_pi_free(*pip, 0);
14947 *pip = NULL;
14948 *lun_dip = NULL;
14949 }
14950 }
14951
14952 scsi_hba_nodename_compatible_free(nodename, compatible);
14953 if (lun_addr != NULL) {
14954 kmem_free(lun_addr, SCSI_MAXNAMELEN);
14955 }
15276 DDI_PROP_SUCCESS) {
15277 mptsas_log(mpt, CE_WARN, "mptsas driver "
15278 "failed to create phy-num property for "
15279 "target %d", target);
15280 ndi_rtn = NDI_FAILURE;
15281 goto phys_create_done;
15282 }
15283 }
15284 phys_create_done:
15285 /*
15286 * If props were setup ok, online the lun
15287 */
15288 if (ndi_rtn == NDI_SUCCESS) {
15289 /*
15290 * Try to online the new node
15291 */
15292 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
15293 }
15294 if (ndi_rtn == NDI_SUCCESS) {
15295 mutex_enter(&mpt->m_mutex);
15296 ptgt->m_led_status = 0;
15297 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) {
15298 NDBG14(("mptsas: clear LED for tgt %x "
15299 "failed", ptgt->m_slot_num));
15300 }
15301 mutex_exit(&mpt->m_mutex);
15302 }
15303
15304 /*
15305 * If success set rtn flag, else unwire alloc'd lun
15306 */
15307 if (ndi_rtn != NDI_SUCCESS) {
15308 NDBG12(("mptsas driver unable to online "
15309 "target %d lun %d", target, lun));
15310 ndi_prop_remove_all(*lun_dip);
15311 (void) ndi_devi_free(*lun_dip);
15312 *lun_dip = NULL;
15313 }
15314 }
15315
15316 scsi_hba_nodename_compatible_free(nodename, compatible);
15317
16178 }
16179 static mptsas_target_t *
16180 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
16181 {
16182 uint8_t phynum;
16183 uint64_t wwn;
16184 int lun;
16185 mptsas_target_t *ptgt = NULL;
16186
16187 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) {
16188 return (NULL);
16189 }
16190 if (addr[0] == 'w') {
16191 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn);
16192 } else {
16193 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum);
16194 }
16195 return (ptgt);
16196 }
16197
16198 static int
16199 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt)
16200 {
16201 uint32_t slotstatus = 0;
16202
16203 /* Build an MPI2 Slot Status based on our view of the world */
16204 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1)))
16205 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST;
16206 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1)))
16207 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT;
16208 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)))
16209 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE;
16210
16211 /* Write it to the controller */
16212 NDBG14(("mptsas_ioctl: set LED status %x for slot %x",
16213 slotstatus, ptgt->m_slot_num));
16214 return (mptsas_send_sep(mpt, ptgt, &slotstatus,
16215 MPI2_SEP_REQ_ACTION_WRITE_STATUS));
16216 }
16217
16218 /*
16219 * send sep request, use enclosure/slot addressing
16220 */
16221 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
16222 uint32_t *status, uint8_t act)
16223 {
16224 Mpi2SepRequest_t req;
16225 Mpi2SepReply_t rep;
16226 int ret;
16227
16228 ASSERT(mutex_owned(&mpt->m_mutex));
16229
16230 bzero(&req, sizeof (req));
16231 bzero(&rep, sizeof (rep));
16232
16233 /* Do nothing for RAID volumes */
16234 if (ptgt->m_phymask == 0) {
16235 NDBG14(("mptsas_send_sep: Skip RAID volumes"));
16236 return (DDI_FAILURE);
16237 }
|