5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
26 * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
27 */
28
29 /*
30 * Copyright (c) 2000 to 2010, LSI Corporation.
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms of all code within
34 * this file that is exclusively owned by LSI, with or without
35 * modification, is permitted provided that, in addition to the CDDL 1.0
36 * License requirements, the following conditions are met:
37 *
38 * Neither the name of the author nor the names of its contributors may be
39 * used to endorse or promote products derived from this software without
40 * specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
45 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
80
81 #pragma pack(1)
82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
90 #pragma pack()
91
92 /*
93 * private header files.
94 *
95 */
96 #include <sys/scsi/impl/scsi_reset_notify.h>
97 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
98 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
99 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
100 #include <sys/raidioctl.h>
101
102 #include <sys/fs/dv_node.h> /* devfs_clean */
103
104 /*
105 * FMA header files
106 */
107 #include <sys/ddifm.h>
108 #include <sys/fm/protocol.h>
109 #include <sys/fm/util.h>
110 #include <sys/fm/io/ddi.h>
111
112 /*
113 * autoconfiguration data and routines.
114 */
115 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
116 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
117 static int mptsas_power(dev_info_t *dip, int component, int level);
118
119 /*
319 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
320
321 /*
322 * helper functions
323 */
324 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
325
326 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
327 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
328 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
329 int lun);
330 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
331 int lun);
332 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
333 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
334
335 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
336 int *lun);
337 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
338
339 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask,
340 uint8_t phy);
341 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask,
342 uint64_t wwid);
343 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask,
344 uint64_t wwid);
345
346 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
347 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
348
349 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
350 uint16_t *handle, mptsas_target_t **pptgt);
351 static void mptsas_update_phymask(mptsas_t *mpt);
352
353 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
354 uint32_t *status, uint8_t cmd);
355 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
356 mptsas_phymask_t *phymask);
357 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
358 mptsas_phymask_t phymask);
359 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
360
361
362 /*
363 * Enumeration / DR functions
364 */
390 static void mptsas_offline_missed_luns(dev_info_t *pdip,
391 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
392 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
393 mdi_pathinfo_t *rpip, uint_t flags);
394
395 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
396 dev_info_t **smp_dip);
397 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
398 uint_t flags);
399
400 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
401 int mode, int *rval);
402 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
403 int mode, int *rval);
404 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
405 int mode, int *rval);
406 static void mptsas_record_event(void *args);
407 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
408 int mode);
409
410 static void mptsas_hash_init(mptsas_hash_table_t *hashtab);
411 static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen);
412 static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data);
413 static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
414 mptsas_phymask_t key2);
415 static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
416 mptsas_phymask_t key2);
417 static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos);
418
419 mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t,
420 uint32_t, mptsas_phymask_t, uint8_t);
421 static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab,
422 mptsas_smp_t *data);
423 static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
424 mptsas_phymask_t phymask);
425 static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t);
426 static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t);
427 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
428 dev_info_t **smp_dip);
429
430 /*
431 * Power management functions
432 */
433 static int mptsas_get_pci_cap(mptsas_t *mpt);
434 static int mptsas_init_pm(mptsas_t *mpt);
435
436 /*
437 * MPT MSI tunable:
438 *
439 * By default MSI is enabled on all supported platforms.
440 */
441 boolean_t mptsas_enable_msi = B_TRUE;
442 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE;
443
444 static int mptsas_register_intrs(mptsas_t *);
445 static void mptsas_unregister_intrs(mptsas_t *);
446 static int mptsas_add_intrs(mptsas_t *, int);
678 mutex_destroy(&mptsas_global_mutex);
679 rw_destroy(&mptsas_global_rwlock);
680 mutex_destroy(&mptsas_log_mutex);
681 }
682 return (status);
683 }
684
685 /*
686 * The loadable-module _info(9E) entry point
687 */
688 int
689 _info(struct modinfo *modinfop)
690 {
691 /* CONSTCOND */
692 ASSERT(NO_COMPETING_THREADS);
693 NDBG0(("mptsas _info"));
694
695 return (mod_info(&modlinkage, modinfop));
696 }
697
698
699 static int
700 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
701 {
702 dev_info_t *pdip;
703 mptsas_t *mpt;
704 scsi_hba_tran_t *hba_tran;
705 char *iport = NULL;
706 char phymask[MPTSAS_MAX_PHYS];
707 mptsas_phymask_t phy_mask = 0;
708 int dynamic_port = 0;
709 uint32_t page_address;
710 char initiator_wwnstr[MPTSAS_WWN_STRLEN];
711 int rval = DDI_FAILURE;
712 int i = 0;
713 uint8_t numphys = 0;
714 uint8_t phy_id;
715 uint8_t phy_port = 0;
716 uint16_t attached_devhdl = 0;
717 uint32_t dev_info;
718 uint64_t attached_sas_wwn;
719 uint16_t dev_hdl;
1387
1388 if (mptsas_timeout_id && (mptsas_head == NULL)) {
1389 timeout_id_t tid = mptsas_timeout_id;
1390 mptsas_timeouts_enabled = 0;
1391 mptsas_timeout_id = 0;
1392 mutex_exit(&mptsas_global_mutex);
1393 (void) untimeout(tid);
1394 mutex_enter(&mptsas_global_mutex);
1395 }
1396 mutex_exit(&mptsas_global_mutex);
1397 /* deallocate in reverse order */
1398 mptsas_cache_destroy(mpt);
1399
1400 if (smp_attach_setup) {
1401 mptsas_smp_teardown(mpt);
1402 }
1403 if (hba_attach_setup) {
1404 mptsas_hba_teardown(mpt);
1405 }
1406
1407 if (mpt->m_active) {
1408 mptsas_hash_uninit(&mpt->m_active->m_smptbl,
1409 sizeof (mptsas_smp_t));
1410 mptsas_hash_uninit(&mpt->m_active->m_tgttbl,
1411 sizeof (mptsas_target_t));
1412 mptsas_free_active_slots(mpt);
1413 }
1414 if (intr_added) {
1415 mptsas_unregister_intrs(mpt);
1416 }
1417
1418 if (doneq_thread_create) {
1419 mutex_enter(&mpt->m_doneq_mutex);
1420 doneq_thread_num = mpt->m_doneq_thread_n;
1421 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1422 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1423 mpt->m_doneq_thread_id[j].flag &=
1424 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1425 cv_signal(&mpt->m_doneq_thread_id[j].cv);
1426 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1427 }
1428 while (mpt->m_doneq_thread_n) {
1429 cv_wait(&mpt->m_doneq_thread_cv,
1430 &mpt->m_doneq_mutex);
1431 }
1824 mptsas_timeout_id = 0;
1825 mutex_exit(&mptsas_global_mutex);
1826 (void) untimeout(tid);
1827 mutex_enter(&mptsas_global_mutex);
1828 }
1829 if (mptsas_reset_watch) {
1830 tid = mptsas_reset_watch;
1831 mptsas_reset_watch = 0;
1832 mutex_exit(&mptsas_global_mutex);
1833 (void) untimeout(tid);
1834 mutex_enter(&mptsas_global_mutex);
1835 }
1836 }
1837 mutex_exit(&mptsas_global_mutex);
1838
1839 /*
1840 * Delete Phy stats
1841 */
1842 mptsas_destroy_phy_stats(mpt);
1843
1844 /*
1845 * Delete nt_active.
1846 */
1847 mutex_enter(&mpt->m_mutex);
1848 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t));
1849 mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t));
1850 mptsas_free_active_slots(mpt);
1851 mutex_exit(&mpt->m_mutex);
1852
1853 /* deallocate everything that was allocated in mptsas_attach */
1854 mptsas_cache_destroy(mpt);
1855
1856 mptsas_hba_fini(mpt);
1857 mptsas_cfg_fini(mpt);
1858
1859 /* Lower the power informing PM Framework */
1860 if (mpt->m_options & MPTSAS_OPT_PM) {
1861 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
1862 mptsas_log(mpt, CE_WARN,
1863 "!mptsas%d: Lower power request failed "
1864 "during detach, ignoring.",
1865 mpt->m_instance);
1866 }
1867
1868 mutex_destroy(&mpt->m_tx_waitq_mutex);
1869 mutex_destroy(&mpt->m_passthru_mutex);
2090 (void) scsi_hba_iport_register(mpt->m_dip, "v0");
2091
2092 }
2093
2094 static int
2095 mptsas_smp_setup(mptsas_t *mpt)
2096 {
2097 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip);
2098 ASSERT(mpt->m_smptran != NULL);
2099 mpt->m_smptran->smp_tran_hba_private = mpt;
2100 mpt->m_smptran->smp_tran_start = mptsas_smp_start;
2101 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) {
2102 mptsas_log(mpt, CE_WARN, "smp attach setup failed");
2103 smp_hba_tran_free(mpt->m_smptran);
2104 mpt->m_smptran = NULL;
2105 return (FALSE);
2106 }
2107 /*
2108 * Initialize smp hash table
2109 */
2110 mptsas_hash_init(&mpt->m_active->m_smptbl);
2111 mpt->m_smp_devhdl = 0xFFFF;
2112
2113 return (TRUE);
2114 }
2115
2116 static void
2117 mptsas_smp_teardown(mptsas_t *mpt)
2118 {
2119 (void) smp_hba_detach(mpt->m_dip);
2120 if (mpt->m_smptran != NULL) {
2121 smp_hba_tran_free(mpt->m_smptran);
2122 mpt->m_smptran = NULL;
2123 }
2124 mpt->m_smp_devhdl = 0;
2125 }
2126
2127 static int
2128 mptsas_cache_create(mptsas_t *mpt)
2129 {
2130 int instance = mpt->m_instance;
2733 {
2734 #ifndef __lock_lint
2735 _NOTE(ARGUNUSED(hba_tran))
2736 #endif
2737
2738 /*
2739 * At this point, the scsi_device structure already exists
2740 * and has been initialized.
2741 *
2742 * Use this function to allocate target-private data structures,
2743 * if needed by this HBA. Add revised flow-control and queue
2744 * properties for child here, if desired and if you can tell they
2745 * support tagged queueing by now.
2746 */
2747 mptsas_t *mpt;
2748 int lun = sd->sd_address.a_lun;
2749 mdi_pathinfo_t *pip = NULL;
2750 mptsas_tgt_private_t *tgt_private = NULL;
2751 mptsas_target_t *ptgt = NULL;
2752 char *psas_wwn = NULL;
2753 int phymask = 0;
2754 uint64_t sas_wwn = 0;
2755 mpt = SDEV2MPT(sd);
2756
2757 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
2758
2759 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
2760 (void *)hba_dip, (void *)tgt_dip, lun));
2761
2762 if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
2763 (void) ndi_merge_node(tgt_dip, mptsas_name_child);
2764 ddi_set_name_addr(tgt_dip, NULL);
2765 return (DDI_FAILURE);
2766 }
2767 /*
2768 * phymask is 0 means the virtual port for RAID
2769 */
2770 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
2771 "phymask", 0);
2772 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2773 if ((pip = (void *)(sd->sd_private)) == NULL) {
2774 /*
2775 * Very bad news if this occurs. Somehow scsi_vhci has
2776 * lost the pathinfo node for this target.
2777 */
2778 return (DDI_NOT_WELL_FORMED);
2779 }
2780
2781 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
2782 DDI_PROP_SUCCESS) {
2783 mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
2784 return (DDI_FAILURE);
2785 }
2786
2787 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
2788 &psas_wwn) == MDI_SUCCESS) {
2789 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2790 sas_wwn = 0;
2791 }
2792 (void) mdi_prop_free(psas_wwn);
2793 }
2794 } else {
2795 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
2796 DDI_PROP_DONTPASS, LUN_PROP, 0);
2797 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
2798 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
2799 DDI_PROP_SUCCESS) {
2800 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2801 sas_wwn = 0;
2802 }
2803 ddi_prop_free(psas_wwn);
2804 } else {
2805 sas_wwn = 0;
2806 }
2807 }
2808 ASSERT((sas_wwn != 0) || (phymask != 0));
2809 mutex_enter(&mpt->m_mutex);
2810 ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask);
2811 mutex_exit(&mpt->m_mutex);
2812 if (ptgt == NULL) {
2813 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
2814 "gone already! phymask:%x, saswwn %"PRIx64, phymask,
2815 sas_wwn);
2816 return (DDI_FAILURE);
2817 }
2818 if (hba_tran->tran_tgt_private == NULL) {
2819 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
2820 KM_SLEEP);
2821 tgt_private->t_lun = lun;
2822 tgt_private->t_private = ptgt;
2823 hba_tran->tran_tgt_private = tgt_private;
2824 }
2825
2826 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2827 return (DDI_SUCCESS);
2828 }
2829 mutex_enter(&mpt->m_mutex);
2830
3221
3222 if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3223 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3224
3225 /*
3226 * Only flush the doneq if this is not a TM
3227 * cmd. For TM cmds the flushing of the
3228 * doneq will be done in those routines.
3229 */
3230 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3231 mptsas_doneq_empty(mpt);
3232 }
3233 }
3234 }
3235 return (rval);
3236 }
3237
3238 int
3239 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3240 {
3241 mptsas_slots_t *slots;
3242 int slot;
3243 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3244
3245 ASSERT(mutex_owned(&mpt->m_mutex));
3246 slots = mpt->m_active;
3247
3248 /*
3249 * Account for reserved TM request slot and reserved SMID of 0.
3250 */
3251 ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2));
3252
3253 /*
3254 * m_tags is equivalent to the SMID when sending requests. Since the
3255 * SMID cannot be 0, start out at one if rolling over past the size
3256 * of the request queue depth. Also, don't use the last SMID, which is
3257 * reserved for TM requests.
3258 */
3259 slot = (slots->m_tags)++;
3260 if (slots->m_tags > slots->m_n_slots) {
3261 slots->m_tags = 1;
3262 }
3263
3264 alloc_tag:
3265 /* Validate tag, should never fail. */
3266 if (slots->m_slot[slot] == NULL) {
3267 /*
3268 * Make sure SMID is not using reserved value of 0
3269 * and the TM request slot.
3270 */
3271 ASSERT((slot > 0) && (slot <= slots->m_n_slots));
3272 cmd->cmd_slot = slot;
3273 slots->m_slot[slot] = cmd;
3274 mpt->m_ncmds++;
3275
3276 /*
3277 * only increment per target ncmds if this is not a
3278 * command that has no target associated with it (i.e. a
3279 * event acknoledgment)
3280 */
3281 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3282 ptgt->m_t_ncmds++;
3283 }
3284 cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
3285
3286 /*
3287 * If initial timout is less than or equal to one tick, bump
3288 * the timeout by a tick so that command doesn't timeout before
3289 * its allotted time.
3290 */
3291 if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
3292 cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
3293 }
3294 return (TRUE);
3295 } else {
3296 int i;
3297
3298 /*
3299 * If slot in use, scan until a free one is found. Don't use 0
3300 * or final slot, which is reserved for TM requests.
3301 */
3302 for (i = 0; i < slots->m_n_slots; i++) {
3303 slot = slots->m_tags;
3304 if (++(slots->m_tags) > slots->m_n_slots) {
3305 slots->m_tags = 1;
3306 }
3307 if (slots->m_slot[slot] == NULL) {
3308 NDBG22(("found free slot %d", slot));
3309 goto alloc_tag;
3310 }
3311 }
3312 }
3313 return (FALSE);
3314 }
3315
3316 /*
3317 * prepare the pkt:
3318 * the pkt may have been resubmitted or just reused so
3319 * initialize some fields and do some checks.
3320 */
3321 static int
3322 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3323 {
3324 struct scsi_pkt *pkt = CMD2PKT(cmd);
3325
3326 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3327
3328 /*
3329 * Reinitialize some fields that need it; the packet may
3330 * have been resubmitted
3331 */
3332 pkt->pkt_reason = CMD_CMPLT;
3333 pkt->pkt_state = 0;
4634 static void
4635 mptsas_handle_scsi_io_success(mptsas_t *mpt,
4636 pMpi2ReplyDescriptorsUnion_t reply_desc)
4637 {
4638 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success;
4639 uint16_t SMID;
4640 mptsas_slots_t *slots = mpt->m_active;
4641 mptsas_cmd_t *cmd = NULL;
4642 struct scsi_pkt *pkt;
4643
4644 ASSERT(mutex_owned(&mpt->m_mutex));
4645
4646 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4647 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4648
4649 /*
4650 * This is a success reply so just complete the IO. First, do a sanity
4651 * check on the SMID. The final slot is used for TM requests, which
4652 * would not come into this reply handler.
4653 */
4654 if ((SMID == 0) || (SMID > slots->m_n_slots)) {
4655 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4656 SMID);
4657 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4658 return;
4659 }
4660
4661 cmd = slots->m_slot[SMID];
4662
4663 /*
4664 * print warning and return if the slot is empty
4665 */
4666 if (cmd == NULL) {
4667 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
4668 "in slot %d", SMID);
4669 return;
4670 }
4671
4672 pkt = CMD2PKT(cmd);
4673 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
4674 STATE_GOT_STATUS);
4737 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4738 return;
4739 }
4740
4741 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
4742 DDI_DMA_SYNC_FORCPU);
4743 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
4744 mpt->m_reply_frame_dma_addr));
4745 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
4746
4747 /*
4748 * don't get slot information and command for events since these values
4749 * don't exist
4750 */
4751 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
4752 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
4753 /*
4754 * This could be a TM reply, which use the last allocated SMID,
4755 * so allow for that.
4756 */
4757 if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) {
4758 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
4759 "%d\n", SMID);
4760 ddi_fm_service_impact(mpt->m_dip,
4761 DDI_SERVICE_UNAFFECTED);
4762 return;
4763 }
4764
4765 cmd = slots->m_slot[SMID];
4766
4767 /*
4768 * print warning and return if the slot is empty
4769 */
4770 if (cmd == NULL) {
4771 mptsas_log(mpt, CE_WARN, "?NULL command for address "
4772 "reply in slot %d", SMID);
4773 return;
4774 }
4775 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
4776 (cmd->cmd_flags & CFLAG_CONFIG) ||
4777 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
5054 */
5055 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5056 (scsi_sense_asc(sensedata) == 0x3F) &&
5057 (scsi_sense_ascq(sensedata) == 0x0E)) ||
5058 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5059 (scsi_sense_asc(sensedata) == 0x25) &&
5060 (scsi_sense_ascq(sensedata) == 0x00))) {
5061 mptsas_topo_change_list_t *topo_node = NULL;
5062
5063 topo_node = kmem_zalloc(
5064 sizeof (mptsas_topo_change_list_t),
5065 KM_NOSLEEP);
5066 if (topo_node == NULL) {
5067 mptsas_log(mpt, CE_NOTE, "No memory"
5068 "resource for handle SAS dynamic"
5069 "reconfigure.\n");
5070 break;
5071 }
5072 topo_node->mpt = mpt;
5073 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5074 topo_node->un.phymask = ptgt->m_phymask;
5075 topo_node->devhdl = ptgt->m_devhdl;
5076 topo_node->object = (void *)ptgt;
5077 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5078
5079 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5080 mptsas_handle_dr,
5081 (void *)topo_node,
5082 DDI_NOSLEEP)) != DDI_SUCCESS) {
5083 mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5084 "for handle SAS dynamic reconfigure"
5085 "failed. \n");
5086 }
5087 }
5088 break;
5089 case MPI2_SCSI_STATUS_GOOD:
5090 switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5091 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5092 pkt->pkt_reason = CMD_DEV_GONE;
5093 pkt->pkt_state |= STATE_GOT_BUS;
5094 if (ptgt->m_reset_delay == 0) {
5120 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5121 mptsas_set_pkt_reason(mpt,
5122 cmd, CMD_RESET, STAT_BUS_RESET);
5123 break;
5124 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5125 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5126 mptsas_set_pkt_reason(mpt,
5127 cmd, CMD_RESET, STAT_DEV_RESET);
5128 break;
5129 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5130 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5131 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5132 mptsas_set_pkt_reason(mpt,
5133 cmd, CMD_TERMINATED, STAT_TERMINATED);
5134 break;
5135 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5136 case MPI2_IOCSTATUS_BUSY:
5137 /*
5138 * set throttles to drain
5139 */
5140 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5141 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
5142 while (ptgt != NULL) {
5143 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5144
5145 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5146 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
5147 }
5148
5149 /*
5150 * retry command
5151 */
5152 cmd->cmd_flags |= CFLAG_RETRY;
5153 cmd->cmd_pkt_flags |= FLAG_HEAD;
5154
5155 (void) mptsas_accept_pkt(mpt, cmd);
5156 break;
5157 default:
5158 mptsas_log(mpt, CE_WARN,
5159 "unknown ioc_status = %x\n", ioc_status);
5160 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5161 "count = %x, scsi_status = %x", scsi_state,
5162 xferred, scsi_status);
5163 break;
5164 }
5165 break;
5166 case MPI2_SCSI_STATUS_TASK_SET_FULL:
5817 char *addr = NULL;
5818 dev_info_t *lundip;
5819 int circ = 0, circ1 = 0;
5820 char attached_wwnstr[MPTSAS_WWN_STRLEN];
5821
5822 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance));
5823
5824 ASSERT(mutex_owned(&mpt->m_mutex));
5825
5826 switch (topo_node->event) {
5827 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5828 {
5829 char *phy_mask_name;
5830 mptsas_phymask_t phymask = 0;
5831
5832 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5833 /*
5834 * Get latest RAID info.
5835 */
5836 (void) mptsas_get_raid_info(mpt);
5837 ptgt = mptsas_search_by_devhdl(
5838 &mpt->m_active->m_tgttbl, topo_node->devhdl);
5839 if (ptgt == NULL)
5840 break;
5841 } else {
5842 ptgt = (void *)topo_node->object;
5843 }
5844
5845 if (ptgt == NULL) {
5846 /*
5847 * If a Phys Disk was deleted, RAID info needs to be
5848 * updated to reflect the new topology.
5849 */
5850 (void) mptsas_get_raid_info(mpt);
5851
5852 /*
5853 * Get sas device page 0 by DevHandle to make sure if
5854 * SSP/SATA end device exist.
5855 */
5856 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
5857 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
5858 topo_node->devhdl;
5867 } else if (rval == DEV_INFO_FAIL_ALLOC) {
5868 mptsas_log(mpt, CE_NOTE,
5869 "mptsas_handle_topo_change: could not "
5870 "allocate memory. \n");
5871 }
5872 /*
5873 * If rval is DEV_INFO_PHYS_DISK than there is nothing
5874 * else to do, just leave.
5875 */
5876 if (rval != DEV_INFO_SUCCESS) {
5877 return;
5878 }
5879 }
5880
5881 ASSERT(ptgt->m_devhdl == topo_node->devhdl);
5882
5883 mutex_exit(&mpt->m_mutex);
5884 flags = topo_node->flags;
5885
5886 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
5887 phymask = ptgt->m_phymask;
5888 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
5889 (void) sprintf(phy_mask_name, "%x", phymask);
5890 parent = scsi_hba_iport_find(mpt->m_dip,
5891 phy_mask_name);
5892 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
5893 if (parent == NULL) {
5894 mptsas_log(mpt, CE_WARN, "Failed to find a "
5895 "iport for PD, should not happen!");
5896 mutex_enter(&mpt->m_mutex);
5897 break;
5898 }
5899 }
5900
5901 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5902 ndi_devi_enter(parent, &circ1);
5903 (void) mptsas_config_raid(parent, topo_node->devhdl,
5904 &lundip);
5905 ndi_devi_exit(parent, circ1);
5906 } else {
5907 /*
5908 * hold nexus for bus configure
5909 */
5910 ndi_devi_enter(scsi_vhci_dip, &circ);
5911 ndi_devi_enter(parent, &circ1);
5912 rval = mptsas_config_target(parent, ptgt);
5913 /*
5914 * release nexus for bus configure
5915 */
5916 ndi_devi_exit(parent, circ1);
5917 ndi_devi_exit(scsi_vhci_dip, circ);
5918
5919 /*
5920 * Add parent's props for SMHBA support
5921 */
5922 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
5923 bzero(attached_wwnstr,
5924 sizeof (attached_wwnstr));
5925 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
5926 ptgt->m_sas_wwn);
5927 if (ddi_prop_update_string(DDI_DEV_T_NONE,
5928 parent,
5929 SCSI_ADDR_PROP_ATTACHED_PORT,
5930 attached_wwnstr)
5931 != DDI_PROP_SUCCESS) {
5932 (void) ddi_prop_remove(DDI_DEV_T_NONE,
5933 parent,
5934 SCSI_ADDR_PROP_ATTACHED_PORT);
5935 mptsas_log(mpt, CE_WARN, "Failed to"
5936 "attached-port props");
5937 return;
5938 }
5939 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
5940 MPTSAS_NUM_PHYS, 1) !=
5941 DDI_PROP_SUCCESS) {
5942 (void) ddi_prop_remove(DDI_DEV_T_NONE,
5943 parent, MPTSAS_NUM_PHYS);
5944 mptsas_log(mpt, CE_WARN, "Failed to"
5945 " create num-phys props");
5946 return;
5964 */
5965 mptsas_smhba_set_one_phy_props(mpt, parent,
5966 topo_node->un.physport, &attached_devhdl);
5967
5968 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
5969 MPTSAS_VIRTUAL_PORT, 0) !=
5970 DDI_PROP_SUCCESS) {
5971 (void) ddi_prop_remove(DDI_DEV_T_NONE,
5972 parent, MPTSAS_VIRTUAL_PORT);
5973 mptsas_log(mpt, CE_WARN,
5974 "mptsas virtual-port"
5975 "port prop update failed");
5976 return;
5977 }
5978 }
5979 }
5980 mutex_enter(&mpt->m_mutex);
5981
5982 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
5983 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
5984 ptgt->m_phymask));
5985 break;
5986 }
5987 case MPTSAS_DR_EVENT_OFFLINE_TARGET:
5988 {
5989 mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl;
5990 devhdl = topo_node->devhdl;
5991 ptgt = mptsas_search_by_devhdl(tgttbl, devhdl);
5992 if (ptgt == NULL)
5993 break;
5994
5995 sas_wwn = ptgt->m_sas_wwn;
5996 phy = ptgt->m_phynum;
5997
5998 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
5999
6000 if (sas_wwn) {
6001 (void) sprintf(addr, "w%016"PRIx64, sas_wwn);
6002 } else {
6003 (void) sprintf(addr, "p%x", phy);
6004 }
6005 ASSERT(ptgt->m_devhdl == devhdl);
6006
6007 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) ||
6008 (topo_node->flags ==
6009 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6010 /*
6011 * Get latest RAID info if RAID volume status changes
6012 * or Phys Disk status changes
6013 */
6014 (void) mptsas_get_raid_info(mpt);
6015 }
6016 /*
6017 * Abort all outstanding command on the device
6018 */
6019 rval = mptsas_do_scsi_reset(mpt, devhdl);
6020 if (rval) {
6021 NDBG20(("mptsas%d handle_topo_change to reset target "
6022 "before offline devhdl:%x, phymask:%x, rval:%x",
6023 mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask,
6024 rval));
6025 }
6026
6027 mutex_exit(&mpt->m_mutex);
6028
6029 ndi_devi_enter(scsi_vhci_dip, &circ);
6030 ndi_devi_enter(parent, &circ1);
6031 rval = mptsas_offline_target(parent, addr);
6032 ndi_devi_exit(parent, circ1);
6033 ndi_devi_exit(scsi_vhci_dip, circ);
6034 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
6035 "phymask:%x, rval:%x", mpt->m_instance,
6036 ptgt->m_devhdl, ptgt->m_phymask, rval));
6037
6038 kmem_free(addr, SCSI_MAXNAMELEN);
6039
6040 /*
6041 * Clear parent's props for SMHBA support
6042 */
6043 flags = topo_node->flags;
6044 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6045 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6046 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6047 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6048 DDI_PROP_SUCCESS) {
6049 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6050 SCSI_ADDR_PROP_ATTACHED_PORT);
6051 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6052 "prop update failed");
6053 break;
6054 }
6055 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6056 MPTSAS_NUM_PHYS, 0) !=
6059 MPTSAS_NUM_PHYS);
6060 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6061 "prop update failed");
6062 break;
6063 }
6064 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6065 MPTSAS_VIRTUAL_PORT, 1) !=
6066 DDI_PROP_SUCCESS) {
6067 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6068 MPTSAS_VIRTUAL_PORT);
6069 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6070 "prop update failed");
6071 break;
6072 }
6073 }
6074
6075 mutex_enter(&mpt->m_mutex);
6076 ptgt->m_led_status = 0;
6077 (void) mptsas_flush_led_status(mpt, ptgt);
6078 if (rval == DDI_SUCCESS) {
6079 mptsas_tgt_free(&mpt->m_active->m_tgttbl,
6080 ptgt->m_sas_wwn, ptgt->m_phymask);
6081 ptgt = NULL;
6082 } else {
6083 /*
6084 * clean DR_INTRANSITION flag to allow I/O down to
6085 * PHCI driver since failover finished.
6086 * Invalidate the devhdl
6087 */
6088 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6089 ptgt->m_tgt_unconfigured = 0;
6090 mutex_enter(&mpt->m_tx_waitq_mutex);
6091 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6092 mutex_exit(&mpt->m_tx_waitq_mutex);
6093 }
6094
6095 /*
6096 * Send SAS IO Unit Control to free the dev handle
6097 */
6098 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6099 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
6100 rval = mptsas_free_devhdl(mpt, devhdl);
6117 if (rval) {
6118 NDBG20(("mpt%d reset target before remove "
6119 "devhdl:%x, rval:%x", mpt->m_instance,
6120 devhdl, rval));
6121 }
6122 }
6123
6124 /*
6125 * Send SAS IO Unit Control to free the dev handle
6126 */
6127 rval = mptsas_free_devhdl(mpt, devhdl);
6128 NDBG20(("mptsas%d handle_topo_change to remove "
6129 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6130 rval));
6131 break;
6132 }
6133 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6134 {
6135 mptsas_smp_t smp;
6136 dev_info_t *smpdip;
6137 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6138
6139 devhdl = topo_node->devhdl;
6140
6141 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6142 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6143 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6144 if (rval != DDI_SUCCESS) {
6145 mptsas_log(mpt, CE_WARN, "failed to online smp, "
6146 "handle %x", devhdl);
6147 return;
6148 }
6149
6150 psmp = mptsas_smp_alloc(smptbl, &smp);
6151 if (psmp == NULL) {
6152 return;
6153 }
6154
6155 mutex_exit(&mpt->m_mutex);
6156 ndi_devi_enter(parent, &circ1);
6157 (void) mptsas_online_smp(parent, psmp, &smpdip);
6158 ndi_devi_exit(parent, circ1);
6159
6160 mutex_enter(&mpt->m_mutex);
6161 break;
6162 }
6163 case MPTSAS_DR_EVENT_OFFLINE_SMP:
6164 {
6165 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6166 devhdl = topo_node->devhdl;
6167 uint32_t dev_info;
6168
6169 psmp = mptsas_search_by_devhdl(smptbl, devhdl);
6170 if (psmp == NULL)
6171 break;
6172 /*
6173 * The mptsas_smp_t data is released only if the dip is offlined
6174 * successfully.
6175 */
6176 mutex_exit(&mpt->m_mutex);
6177
6178 ndi_devi_enter(parent, &circ1);
6179 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6180 ndi_devi_exit(parent, circ1);
6181
6182 dev_info = psmp->m_deviceinfo;
6183 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6184 DEVINFO_DIRECT_ATTACHED) {
6185 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6186 MPTSAS_VIRTUAL_PORT, 1) !=
6187 DDI_PROP_SUCCESS) {
6188 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6189 MPTSAS_VIRTUAL_PORT);
6205 }
6206 /*
6207 * Clear parent's attached-port props
6208 */
6209 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6210 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6211 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6212 DDI_PROP_SUCCESS) {
6213 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6214 SCSI_ADDR_PROP_ATTACHED_PORT);
6215 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6216 "prop update failed");
6217 return;
6218 }
6219 }
6220
6221 mutex_enter(&mpt->m_mutex);
6222 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6223 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6224 if (rval == DDI_SUCCESS) {
6225 mptsas_smp_free(smptbl, psmp->m_sasaddr,
6226 psmp->m_phymask);
6227 } else {
6228 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6229 }
6230
6231 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6232
6233 break;
6234 }
6235 default:
6236 return;
6237 }
6238 }
6239
6240 /*
6241 * Record the event if its type is enabled in mpt instance by ioctl.
6242 */
6243 static void
6244 mptsas_record_event(void *args)
6245 {
6246 m_replyh_arg_t *replyh_arg;
6365 }
6366
6367 /*
6368 * figure out what kind of event we got and handle accordingly
6369 */
6370 switch (event) {
6371 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6372 {
6373 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list;
6374 uint8_t num_entries, expstatus, phy;
6375 uint8_t phystatus, physport, state, i;
6376 uint8_t start_phy_num, link_rate;
6377 uint16_t dev_handle, reason_code;
6378 uint16_t enc_handle, expd_handle;
6379 char string[80], curr[80], prev[80];
6380 mptsas_topo_change_list_t *topo_head = NULL;
6381 mptsas_topo_change_list_t *topo_tail = NULL;
6382 mptsas_topo_change_list_t *topo_node = NULL;
6383 mptsas_target_t *ptgt;
6384 mptsas_smp_t *psmp;
6385 mptsas_hash_table_t *tgttbl, *smptbl;
6386 uint8_t flags = 0, exp_flag;
6387 smhba_info_t *pSmhba = NULL;
6388
6389 NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6390
6391 tgttbl = &mpt->m_active->m_tgttbl;
6392 smptbl = &mpt->m_active->m_smptbl;
6393
6394 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6395 eventreply->EventData;
6396
6397 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6398 &sas_topo_change_list->EnclosureHandle);
6399 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6400 &sas_topo_change_list->ExpanderDevHandle);
6401 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6402 &sas_topo_change_list->NumEntries);
6403 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
6404 &sas_topo_change_list->StartPhyNum);
6405 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6406 &sas_topo_change_list->ExpStatus);
6407 physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
6408 &sas_topo_change_list->PhysicalPort);
6409
6410 string[0] = 0;
6411 if (expd_handle) {
6412 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
6413 switch (expstatus) {
6419 mpt->m_port_chng = 1;
6420 topo_node = kmem_zalloc(
6421 sizeof (mptsas_topo_change_list_t),
6422 KM_SLEEP);
6423 topo_node->mpt = mpt;
6424 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
6425 topo_node->un.physport = physport;
6426 topo_node->devhdl = expd_handle;
6427 topo_node->flags = flags;
6428 topo_node->object = NULL;
6429 if (topo_head == NULL) {
6430 topo_head = topo_tail = topo_node;
6431 } else {
6432 topo_tail->next = topo_node;
6433 topo_tail = topo_node;
6434 }
6435 break;
6436 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6437 (void) sprintf(string, " not responding, "
6438 "removed");
6439 psmp = mptsas_search_by_devhdl(smptbl,
6440 expd_handle);
6441 if (psmp == NULL)
6442 break;
6443
6444 topo_node = kmem_zalloc(
6445 sizeof (mptsas_topo_change_list_t),
6446 KM_SLEEP);
6447 topo_node->mpt = mpt;
6448 topo_node->un.phymask = psmp->m_phymask;
6449 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6450 topo_node->devhdl = expd_handle;
6451 topo_node->flags = flags;
6452 topo_node->object = NULL;
6453 if (topo_head == NULL) {
6454 topo_head = topo_tail = topo_node;
6455 } else {
6456 topo_tail->next = topo_node;
6457 topo_tail = topo_node;
6458 }
6459 break;
6460 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
6461 break;
6462 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
6463 (void) sprintf(string, " not responding, "
6464 "delaying removal");
6465 break;
6466 default:
6467 break;
6468 }
6579 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
6580 {
6581 NDBG20(("mptsas%d phy %d physical_port %d "
6582 "dev_handle %d removed", mpt->m_instance,
6583 phy, physport, dev_handle));
6584 /*
6585 * Set association flag according to if an
6586 * expander is used or not.
6587 */
6588 exp_flag =
6589 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6590 if (flags ==
6591 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6592 flags = exp_flag;
6593 }
6594 /*
6595 * Target device is removed from the system
6596 * Before the device is really offline from
6597 * from system.
6598 */
6599 ptgt = mptsas_search_by_devhdl(tgttbl,
6600 dev_handle);
6601 /*
6602 * If ptgt is NULL here, it means that the
6603 * DevHandle is not in the hash table. This is
6604 * reasonable sometimes. For example, if a
6605 * disk was pulled, then added, then pulled
6606 * again, the disk will not have been put into
6607 * the hash table because the add event will
6608 * have an invalid phymask. BUT, this does not
6609 * mean that the DevHandle is invalid. The
6610 * controller will still have a valid DevHandle
6611 * that must be removed. To do this, use the
6612 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
6613 */
6614 if (ptgt == NULL) {
6615 topo_node = kmem_zalloc(
6616 sizeof (mptsas_topo_change_list_t),
6617 KM_SLEEP);
6618 topo_node->mpt = mpt;
6619 topo_node->un.phymask = 0;
6620 topo_node->event =
6632 break;
6633 }
6634
6635 /*
6636 * Update DR flag immediately avoid I/O failure
6637 * before failover finish. Pay attention to the
6638 * mutex protect, we need grab m_tx_waitq_mutex
6639 * during set m_dr_flag because we won't add
6640 * the following command into waitq, instead,
6641 * we need return TRAN_BUSY in the tran_start
6642 * context.
6643 */
6644 mutex_enter(&mpt->m_tx_waitq_mutex);
6645 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6646 mutex_exit(&mpt->m_tx_waitq_mutex);
6647
6648 topo_node = kmem_zalloc(
6649 sizeof (mptsas_topo_change_list_t),
6650 KM_SLEEP);
6651 topo_node->mpt = mpt;
6652 topo_node->un.phymask = ptgt->m_phymask;
6653 topo_node->event =
6654 MPTSAS_DR_EVENT_OFFLINE_TARGET;
6655 topo_node->devhdl = dev_handle;
6656 topo_node->flags = flags;
6657 topo_node->object = NULL;
6658 if (topo_head == NULL) {
6659 topo_head = topo_tail = topo_node;
6660 } else {
6661 topo_tail->next = topo_node;
6662 topo_tail = topo_node;
6663 }
6664 break;
6665 }
6666 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
6667 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6668 &sas_topo_change_list->PHY[i].LinkRate);
6669 state = (link_rate &
6670 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6671 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6672 pSmhba = &mpt->m_phy_info[i].smhba_info;
6792 if (topo_head != NULL) {
6793 /*
6794 * Launch DR taskq to handle topology change
6795 */
6796 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6797 mptsas_handle_dr, (void *)topo_head,
6798 DDI_NOSLEEP)) != DDI_SUCCESS) {
6799 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6800 "for handle SAS DR event failed. \n");
6801 }
6802 }
6803 break;
6804 }
6805 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6806 {
6807 Mpi2EventDataIrConfigChangeList_t *irChangeList;
6808 mptsas_topo_change_list_t *topo_head = NULL;
6809 mptsas_topo_change_list_t *topo_tail = NULL;
6810 mptsas_topo_change_list_t *topo_node = NULL;
6811 mptsas_target_t *ptgt;
6812 mptsas_hash_table_t *tgttbl;
6813 uint8_t num_entries, i, reason;
6814 uint16_t volhandle, diskhandle;
6815
6816 irChangeList = (pMpi2EventDataIrConfigChangeList_t)
6817 eventreply->EventData;
6818 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6819 &irChangeList->NumElements);
6820
6821 tgttbl = &mpt->m_active->m_tgttbl;
6822
6823 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
6824 mpt->m_instance));
6825
6826 for (i = 0; i < num_entries; i++) {
6827 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
6828 &irChangeList->ConfigElement[i].ReasonCode);
6829 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6830 &irChangeList->ConfigElement[i].VolDevHandle);
6831 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6832 &irChangeList->ConfigElement[i].PhysDiskDevHandle);
6833
6834 switch (reason) {
6835 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6836 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6837 {
6838 NDBG20(("mptsas %d volume added\n",
6839 mpt->m_instance));
6840
6841 topo_node = kmem_zalloc(
6842 sizeof (mptsas_topo_change_list_t),
6846 topo_node->event =
6847 MPTSAS_DR_EVENT_RECONFIG_TARGET;
6848 topo_node->un.physport = 0xff;
6849 topo_node->devhdl = volhandle;
6850 topo_node->flags =
6851 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6852 topo_node->object = NULL;
6853 if (topo_head == NULL) {
6854 topo_head = topo_tail = topo_node;
6855 } else {
6856 topo_tail->next = topo_node;
6857 topo_tail = topo_node;
6858 }
6859 break;
6860 }
6861 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6862 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6863 {
6864 NDBG20(("mptsas %d volume deleted\n",
6865 mpt->m_instance));
6866 ptgt = mptsas_search_by_devhdl(tgttbl,
6867 volhandle);
6868 if (ptgt == NULL)
6869 break;
6870
6871 /*
6872 * Clear any flags related to volume
6873 */
6874 (void) mptsas_delete_volume(mpt, volhandle);
6875
6876 /*
6877 * Update DR flag immediately avoid I/O failure
6878 */
6879 mutex_enter(&mpt->m_tx_waitq_mutex);
6880 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6881 mutex_exit(&mpt->m_tx_waitq_mutex);
6882
6883 topo_node = kmem_zalloc(
6884 sizeof (mptsas_topo_change_list_t),
6885 KM_SLEEP);
6886 topo_node->mpt = mpt;
6887 topo_node->un.phymask = ptgt->m_phymask;
6888 topo_node->event =
6889 MPTSAS_DR_EVENT_OFFLINE_TARGET;
6890 topo_node->devhdl = volhandle;
6891 topo_node->flags =
6892 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6893 topo_node->object = (void *)ptgt;
6894 if (topo_head == NULL) {
6895 topo_head = topo_tail = topo_node;
6896 } else {
6897 topo_tail->next = topo_node;
6898 topo_tail = topo_node;
6899 }
6900 break;
6901 }
6902 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6903 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6904 {
6905 ptgt = mptsas_search_by_devhdl(tgttbl,
6906 diskhandle);
6907 if (ptgt == NULL)
6908 break;
6909
6910 /*
6911 * Update DR flag immediately avoid I/O failure
6912 */
6913 mutex_enter(&mpt->m_tx_waitq_mutex);
6914 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6915 mutex_exit(&mpt->m_tx_waitq_mutex);
6916
6917 topo_node = kmem_zalloc(
6918 sizeof (mptsas_topo_change_list_t),
6919 KM_SLEEP);
6920 topo_node->mpt = mpt;
6921 topo_node->un.phymask = ptgt->m_phymask;
6922 topo_node->event =
6923 MPTSAS_DR_EVENT_OFFLINE_TARGET;
6924 topo_node->devhdl = diskhandle;
6925 topo_node->flags =
6926 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6927 topo_node->object = (void *)ptgt;
6928 if (topo_head == NULL) {
6929 topo_head = topo_tail = topo_node;
6930 } else {
6931 topo_tail->next = topo_node;
6932 topo_tail = topo_node;
6933 }
6934 break;
6935 }
6936 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
6937 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
6938 {
6939 /*
6940 * The physical drive is released by a IR
6941 * volume. But we cannot get the the physport
7326 SAS_PORT_BROADCAST_D27_4,
7327 &mpt->m_phy_info[phy_num].smhba_info);
7328 break;
7329 default:
7330 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE"
7331 " %x received",
7332 mpt->m_instance, primitive));
7333 break;
7334 }
7335 NDBG20(("mptsas%d sas broadcast primitive: "
7336 "\tprimitive(0x%04x), phy(%d) complete\n",
7337 mpt->m_instance, primitive, phy_num));
7338 break;
7339 }
7340 case MPI2_EVENT_IR_VOLUME:
7341 {
7342 Mpi2EventDataIrVolume_t *irVolume;
7343 uint16_t devhandle;
7344 uint32_t state;
7345 int config, vol;
7346 mptsas_slots_t *slots = mpt->m_active;
7347 uint8_t found = FALSE;
7348
7349 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
7350 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7351 &irVolume->NewValue);
7352 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7353 &irVolume->VolDevHandle);
7354
7355 NDBG20(("EVENT_IR_VOLUME event is received"));
7356
7357 /*
7358 * Get latest RAID info and then find the DevHandle for this
7359 * event in the configuration. If the DevHandle is not found
7360 * just exit the event.
7361 */
7362 (void) mptsas_get_raid_info(mpt);
7363 for (config = 0; (config < slots->m_num_raid_configs) &&
7364 (!found); config++) {
7365 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
7366 if (slots->m_raidconfig[config].m_raidvol[vol].
7367 m_raidhandle == devhandle) {
7368 found = TRUE;
7369 break;
7370 }
7371 }
7372 }
7373 if (!found) {
7374 break;
7375 }
7376
7377 switch (irVolume->ReasonCode) {
7378 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
7379 {
7380 uint32_t i;
7381 slots->m_raidconfig[config].m_raidvol[vol].m_settings =
7382 state;
7383
7384 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
7385 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
7386 ", auto-config of hot-swap drives is %s"
7387 ", write caching is %s"
7388 ", hot-spare pool mask is %02x\n",
7389 vol, state &
7390 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
7391 ? "disabled" : "enabled",
7392 i == MPI2_RAIDVOL0_SETTING_UNCHANGED
7393 ? "controlled by member disks" :
7394 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7395 ? "disabled" :
7396 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7397 ? "enabled" :
7398 "incorrectly set",
7399 (state >> 16) & 0xff);
7400 break;
7401 }
7402 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7403 {
7404 slots->m_raidconfig[config].m_raidvol[vol].m_state =
7405 (uint8_t)state;
7406
7407 mptsas_log(mpt, CE_NOTE,
7408 "Volume %d is now %s\n", vol,
7409 state == MPI2_RAID_VOL_STATE_OPTIMAL
7410 ? "optimal" :
7411 state == MPI2_RAID_VOL_STATE_DEGRADED
7412 ? "degraded" :
7413 state == MPI2_RAID_VOL_STATE_ONLINE
7414 ? "online" :
7415 state == MPI2_RAID_VOL_STATE_INITIALIZING
7416 ? "initializing" :
7417 state == MPI2_RAID_VOL_STATE_FAILED
7418 ? "failed" :
7419 state == MPI2_RAID_VOL_STATE_MISSING
7420 ? "missing" :
7421 "state unknown");
7422 break;
7423 }
7424 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7425 {
7426 slots->m_raidconfig[config].m_raidvol[vol].
7427 m_statusflags = state;
7428
7429 mptsas_log(mpt, CE_NOTE,
7430 " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7431 vol,
7432 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7433 ? ", enabled" : ", disabled",
7434 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7435 ? ", quiesced" : "",
7436 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
7437 ? ", inactive" : ", active",
7438 state &
7439 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
7440 ? ", bad block table is full" : "",
7441 state &
7442 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
7443 ? ", resync in progress" : "",
7444 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
7445 ? ", background initialization in progress" : "",
7446 state &
7555 mpt->m_free_index = 0;
7556 }
7557 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
7558 mpt->m_free_index);
7559 mutex_exit(&mpt->m_mutex);
7560 }
7561
7562 /*
7563 * invoked from timeout() to restart qfull cmds with throttle == 0
7564 */
7565 static void
7566 mptsas_restart_cmd(void *arg)
7567 {
7568 mptsas_t *mpt = arg;
7569 mptsas_target_t *ptgt = NULL;
7570
7571 mutex_enter(&mpt->m_mutex);
7572
7573 mpt->m_restart_cmd_timeid = 0;
7574
7575 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
7576 MPTSAS_HASH_FIRST);
7577 while (ptgt != NULL) {
7578 if (ptgt->m_reset_delay == 0) {
7579 if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7580 mptsas_set_throttle(mpt, ptgt,
7581 MAX_THROTTLE);
7582 }
7583 }
7584
7585 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
7586 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
7587 }
7588 mptsas_restart_hba(mpt);
7589 mutex_exit(&mpt->m_mutex);
7590 }
7591
7592 void
7593 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7594 {
7595 int slot;
7596 mptsas_slots_t *slots = mpt->m_active;
7597 int t;
7598 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7599
7600 ASSERT(cmd != NULL);
7601 ASSERT(cmd->cmd_queued == FALSE);
7602
7603 /*
7604 * Task Management cmds are removed in their own routines. Also,
7605 * we don't want to modify timeout based on TM cmds.
7606 */
7638 }
7639
7640 /*
7641 * This is all we need to do for ioc commands.
7642 */
7643 if (cmd->cmd_flags & CFLAG_CMDIOC) {
7644 mptsas_return_to_pool(mpt, cmd);
7645 return;
7646 }
7647
7648 /*
7649 * Figure out what to set tag Q timeout for...
7650 *
7651 * Optimize: If we have duplicate's of same timeout
7652 * we're using, then we'll use it again until we run
7653 * out of duplicates. This should be the normal case
7654 * for block and raw I/O.
7655 * If no duplicates, we have to scan through tag que and
7656 * find the longest timeout value and use it. This is
7657 * going to take a while...
7658 * Add 1 to m_n_slots to account for TM request.
7659 */
7660 if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
7661 if (--(ptgt->m_dups) == 0) {
7662 if (ptgt->m_t_ncmds) {
7663 mptsas_cmd_t *ssp;
7664 uint_t n = 0;
7665 ushort_t nslots = (slots->m_n_slots + 1);
7666 ushort_t i;
7667 /*
7668 * This crude check assumes we don't do
7669 * this too often which seems reasonable
7670 * for block and raw I/O.
7671 */
7672 for (i = 0; i < nslots; i++) {
7673 ssp = slots->m_slot[i];
7674 if (ssp && (Tgt(ssp) == t) &&
7675 (ssp->cmd_pkt->pkt_time > n)) {
7676 n = ssp->cmd_pkt->pkt_time;
7677 ptgt->m_dups = 1;
7678 } else if (ssp && (Tgt(ssp) == t) &&
7679 (ssp->cmd_pkt->pkt_time == n)) {
7680 ptgt->m_dups++;
7681 }
7682 }
7683 ptgt->m_timebase = n;
7684 } else {
7685 ptgt->m_dups = 0;
8404 drv_usecwait(mpt->m_scsi_reset_delay * 1000);
8405 }
8406 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
8407 mutex_exit(&mpt->m_mutex);
8408
8409 /*
8410 * The transport layer expect to only see TRUE and
8411 * FALSE. Therefore, we will adjust the return value
8412 * if mptsas_do_scsi_reset returns FAILED.
8413 */
8414 if (rval == FAILED)
8415 rval = FALSE;
8416 return (rval);
8417 }
8418
8419 static int
8420 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8421 {
8422 int rval = FALSE;
8423 uint8_t config, disk;
8424 mptsas_slots_t *slots = mpt->m_active;
8425
8426 ASSERT(mutex_owned(&mpt->m_mutex));
8427
8428 if (mptsas_debug_resets) {
8429 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8430 devhdl);
8431 }
8432
8433 /*
8434 * Issue a Target Reset message to the target specified but not to a
8435 * disk making up a raid volume. Just look through the RAID config
8436 * Phys Disk list of DevHandles. If the target's DevHandle is in this
8437 * list, then don't reset this target.
8438 */
8439 for (config = 0; config < slots->m_num_raid_configs; config++) {
8440 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8441 if (devhdl == slots->m_raidconfig[config].
8442 m_physdisk_devhdl[disk]) {
8443 return (TRUE);
8444 }
8445 }
8446 }
8447
8448 rval = mptsas_ioc_task_management(mpt,
8449 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0);
8450
8451 mptsas_doneq_empty(mpt);
8452 return (rval);
8453 }
8454
8455 static int
8456 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
8457 void (*callback)(caddr_t), caddr_t arg)
8458 {
8459 mptsas_t *mpt = ADDR2MPT(ap);
8460
8461 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
8517 * commands for a particular target. For the case of abort task set, this
8518 * function clears the waitq of all commonds for a particular target/lun.
8519 */
8520 static void
8521 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
8522 {
8523 mptsas_slots_t *slots = mpt->m_active;
8524 mptsas_cmd_t *cmd, *next_cmd;
8525 int slot;
8526 uchar_t reason;
8527 uint_t stat;
8528
8529 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8530
8531 /*
8532 * Make sure the I/O Controller has flushed all cmds
8533 * that are associated with this target for a target reset
8534 * and target/lun for abort task set.
8535 * Account for TM requests, which use the last SMID.
8536 */
8537 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8538 if ((cmd = slots->m_slot[slot]) == NULL)
8539 continue;
8540 reason = CMD_RESET;
8541 stat = STAT_DEV_RESET;
8542 switch (tasktype) {
8543 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8544 if (Tgt(cmd) == target) {
8545 NDBG25(("mptsas_flush_target discovered non-"
8546 "NULL cmd in slot %d, tasktype 0x%x", slot,
8547 tasktype));
8548 mptsas_dump_cmd(mpt, cmd);
8549 mptsas_remove_cmd(mpt, cmd);
8550 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8551 mptsas_doneq_add(mpt, cmd);
8552 }
8553 break;
8554 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8555 reason = CMD_ABORTED;
8556 stat = STAT_ABORTED;
8557 /*FALLTHROUGH*/
8649
8650 /*
8651 * Clean up hba state, abort all outstanding command and commands in waitq
8652 * reset timeout of all targets.
8653 */
8654 static void
8655 mptsas_flush_hba(mptsas_t *mpt)
8656 {
8657 mptsas_slots_t *slots = mpt->m_active;
8658 mptsas_cmd_t *cmd;
8659 int slot;
8660
8661 NDBG25(("mptsas_flush_hba"));
8662
8663 /*
8664 * The I/O Controller should have already sent back
8665 * all commands via the scsi I/O reply frame. Make
8666 * sure all commands have been flushed.
8667 * Account for TM request, which use the last SMID.
8668 */
8669 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8670 if ((cmd = slots->m_slot[slot]) == NULL)
8671 continue;
8672
8673 if (cmd->cmd_flags & CFLAG_CMDIOC) {
8674 /*
8675 * Need to make sure to tell everyone that might be
8676 * waiting on this command that it's going to fail. If
8677 * we get here, this command will never timeout because
8678 * the active command table is going to be re-allocated,
8679 * so there will be nothing to check against a time out.
8680 * Instead, mark the command as failed due to reset.
8681 */
8682 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
8683 STAT_BUS_RESET);
8684 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8685 (cmd->cmd_flags & CFLAG_CONFIG) ||
8686 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
8687 cmd->cmd_flags |= CFLAG_FINISHED;
8688 cv_broadcast(&mpt->m_passthru_cv);
8689 cv_broadcast(&mpt->m_config_cv);
8764 static void
8765 mptsas_start_watch_reset_delay()
8766 {
8767 NDBG22(("mptsas_start_watch_reset_delay"));
8768
8769 mutex_enter(&mptsas_global_mutex);
8770 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
8771 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
8772 drv_usectohz((clock_t)
8773 MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
8774 ASSERT(mptsas_reset_watch != NULL);
8775 }
8776 mutex_exit(&mptsas_global_mutex);
8777 }
8778
8779 static void
8780 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
8781 {
8782 mptsas_target_t *ptgt = NULL;
8783
8784 NDBG22(("mptsas_setup_bus_reset_delay"));
8785 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8786 MPTSAS_HASH_FIRST);
8787 while (ptgt != NULL) {
8788 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
8789 ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
8790
8791 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8792 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8793 }
8794
8795 mptsas_start_watch_reset_delay();
8796 }
8797
8798 /*
8799 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
8800 * mpt instance for active reset delays
8801 */
8802 static void
8803 mptsas_watch_reset_delay(void *arg)
8804 {
8805 #ifndef __lock_lint
8806 _NOTE(ARGUNUSED(arg))
8807 #endif
8808
8809 mptsas_t *mpt;
8810 int not_done = 0;
8811
8812 NDBG22(("mptsas_watch_reset_delay"));
8824 mutex_exit(&mpt->m_mutex);
8825 }
8826 rw_exit(&mptsas_global_rwlock);
8827
8828 if (not_done) {
8829 mptsas_start_watch_reset_delay();
8830 }
8831 }
8832
8833 static int
8834 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
8835 {
8836 int done = 0;
8837 int restart = 0;
8838 mptsas_target_t *ptgt = NULL;
8839
8840 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
8841
8842 ASSERT(mutex_owned(&mpt->m_mutex));
8843
8844 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8845 MPTSAS_HASH_FIRST);
8846 while (ptgt != NULL) {
8847 if (ptgt->m_reset_delay != 0) {
8848 ptgt->m_reset_delay -=
8849 MPTSAS_WATCH_RESET_DELAY_TICK;
8850 if (ptgt->m_reset_delay <= 0) {
8851 ptgt->m_reset_delay = 0;
8852 mptsas_set_throttle(mpt, ptgt,
8853 MAX_THROTTLE);
8854 restart++;
8855 } else {
8856 done = -1;
8857 }
8858 }
8859
8860 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8861 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8862 }
8863
8864 if (restart > 0) {
8865 mptsas_restart_hba(mpt);
8866 }
8867 return (done);
8868 }
8869
8870 #ifdef MPTSAS_TEST
8871 static void
8872 mptsas_test_reset(mptsas_t *mpt, int target)
8873 {
8874 mptsas_target_t *ptgt = NULL;
8875
8876 if (mptsas_rtest == target) {
8877 if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
8878 mptsas_rtest = -1;
8879 }
8880 if (mptsas_rtest == -1) {
8881 NDBG22(("mptsas_test_reset success"));
9145 */
9146 /*ARGSUSED*/
9147 static int
9148 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
9149 {
9150 NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
9151
9152 if (!cap)
9153 return (FALSE);
9154
9155 *cidxp = scsi_hba_lookup_capstr(cap);
9156 return (TRUE);
9157 }
9158
9159 static int
9160 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
9161 {
9162 mptsas_slots_t *old_active = mpt->m_active;
9163 mptsas_slots_t *new_active;
9164 size_t size;
9165 int rval = -1, i;
9166
9167 /*
9168 * if there are active commands, then we cannot
9169 * change size of active slots array.
9170 */
9171 ASSERT(mpt->m_ncmds == 0);
9172
9173 size = MPTSAS_SLOTS_SIZE(mpt);
9174 new_active = kmem_zalloc(size, flag);
9175 if (new_active == NULL) {
9176 NDBG1(("new active alloc failed"));
9177 return (rval);
9178 }
9179 /*
9180 * Since SMID 0 is reserved and the TM slot is reserved, the
9181 * number of slots that can be used at any one time is
9182 * m_max_requests - 2.
9183 */
9184 new_active->m_n_slots = (mpt->m_max_requests - 2);
9185 new_active->m_size = size;
9186 new_active->m_tags = 1;
9187 if (old_active) {
9188 new_active->m_tgttbl = old_active->m_tgttbl;
9189 new_active->m_smptbl = old_active->m_smptbl;
9190 new_active->m_num_raid_configs =
9191 old_active->m_num_raid_configs;
9192 for (i = 0; i < new_active->m_num_raid_configs; i++) {
9193 new_active->m_raidconfig[i] =
9194 old_active->m_raidconfig[i];
9195 }
9196 mptsas_free_active_slots(mpt);
9197 }
9198 mpt->m_active = new_active;
9199 rval = 0;
9200
9201 return (rval);
9202 }
9203
9204 static void
9205 mptsas_free_active_slots(mptsas_t *mpt)
9206 {
9207 mptsas_slots_t *active = mpt->m_active;
9208 size_t size;
9209
9210 if (active == NULL)
9211 return;
9212 size = active->m_size;
9213 kmem_free(active, size);
9214 mpt->m_active = NULL;
9215 }
9216
9217 /*
9218 * Error logging, printing, and debug print routines.
9219 */
9220 static char *mptsas_label = "mpt_sas";
9221
9326 (void) pm_idle_component(mpt->m_dip, 0);
9327 }
9328
9329 mutex_exit(&mpt->m_mutex);
9330 }
9331 rw_exit(&mptsas_global_rwlock);
9332
9333 mutex_enter(&mptsas_global_mutex);
9334 if (mptsas_timeouts_enabled)
9335 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
9336 mutex_exit(&mptsas_global_mutex);
9337 }
9338
9339 static void
9340 mptsas_watchsubr(mptsas_t *mpt)
9341 {
9342 int i;
9343 mptsas_cmd_t *cmd;
9344 mptsas_target_t *ptgt = NULL;
9345
9346 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
9347
9348 #ifdef MPTSAS_TEST
9349 if (mptsas_enable_untagged) {
9350 mptsas_test_untagged++;
9351 }
9352 #endif
9353
9354 /*
9355 * Check for commands stuck in active slot
9356 * Account for TM requests, which use the last SMID.
9357 */
9358 for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
9359 if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9360 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9361 cmd->cmd_active_timeout -=
9362 mptsas_scsi_watchdog_tick;
9363 if (cmd->cmd_active_timeout <= 0) {
9364 /*
9365 * There seems to be a command stuck
9366 * in the active slot. Drain throttle.
9367 */
9368 mptsas_set_throttle(mpt,
9369 cmd->cmd_tgt_addr,
9370 DRAIN_THROTTLE);
9371 }
9372 }
9373 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9374 (cmd->cmd_flags & CFLAG_CONFIG) ||
9375 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9376 cmd->cmd_active_timeout -=
9377 mptsas_scsi_watchdog_tick;
9378 if (cmd->cmd_active_timeout <= 0) {
9379 /*
9380 * passthrough command timeout
9381 */
9382 cmd->cmd_flags |= (CFLAG_FINISHED |
9383 CFLAG_TIMEOUT);
9384 cv_broadcast(&mpt->m_passthru_cv);
9385 cv_broadcast(&mpt->m_config_cv);
9386 cv_broadcast(&mpt->m_fw_diag_cv);
9387 }
9388 }
9389 }
9390 }
9391
9392 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9393 MPTSAS_HASH_FIRST);
9394 while (ptgt != NULL) {
9395 /*
9396 * If we were draining due to a qfull condition,
9397 * go back to full throttle.
9398 */
9399 if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
9400 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9401 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9402 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9403 mptsas_restart_hba(mpt);
9404 }
9405
9406 if ((ptgt->m_t_ncmds > 0) &&
9407 (ptgt->m_timebase)) {
9408
9409 if (ptgt->m_timebase <=
9410 mptsas_scsi_watchdog_tick) {
9411 ptgt->m_timebase +=
9412 mptsas_scsi_watchdog_tick;
9413 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9414 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9415 continue;
9416 }
9417
9418 ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9419
9420 if (ptgt->m_timeout < 0) {
9421 mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
9422 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9423 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9424 continue;
9425 }
9426
9427 if ((ptgt->m_timeout) <=
9428 mptsas_scsi_watchdog_tick) {
9429 NDBG23(("pending timeout"));
9430 mptsas_set_throttle(mpt, ptgt,
9431 DRAIN_THROTTLE);
9432 }
9433 }
9434
9435 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9436 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9437 }
9438 }
9439
9440 /*
9441 * timeout recovery
9442 */
9443 static void
9444 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9445 {
9446
9447 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9448 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9449 "Target %d", devhdl);
9450
9451 /*
9452 * If the current target is not the target passed in,
9453 * try to reset that target.
9454 */
9455 NDBG29(("mptsas_cmd_timeout: device reset"));
9456 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9480 {
9481 mptsas_t *mpt;
9482 scsi_hba_tran_t *tran;
9483
9484 tran = ddi_get_driver_private(dip);
9485 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9486 return (-1);
9487
9488 return (mptsas_unquiesce_bus(mpt));
9489 }
9490
9491 static int
9492 mptsas_quiesce_bus(mptsas_t *mpt)
9493 {
9494 mptsas_target_t *ptgt = NULL;
9495
9496 NDBG28(("mptsas_quiesce_bus"));
9497 mutex_enter(&mpt->m_mutex);
9498
9499 /* Set all the throttles to zero */
9500 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9501 MPTSAS_HASH_FIRST);
9502 while (ptgt != NULL) {
9503 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9504
9505 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9506 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9507 }
9508
9509 /* If there are any outstanding commands in the queue */
9510 if (mpt->m_ncmds) {
9511 mpt->m_softstate |= MPTSAS_SS_DRAINING;
9512 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9513 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9514 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9515 /*
9516 * Quiesce has been interrupted
9517 */
9518 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9519 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9520 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9521 while (ptgt != NULL) {
9522 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9523
9524 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9525 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9526 }
9527 mptsas_restart_hba(mpt);
9528 if (mpt->m_quiesce_timeid != 0) {
9529 timeout_id_t tid = mpt->m_quiesce_timeid;
9530 mpt->m_quiesce_timeid = 0;
9531 mutex_exit(&mpt->m_mutex);
9532 (void) untimeout(tid);
9533 return (-1);
9534 }
9535 mutex_exit(&mpt->m_mutex);
9536 return (-1);
9537 } else {
9538 /* Bus has been quiesced */
9539 ASSERT(mpt->m_quiesce_timeid == 0);
9540 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9541 mpt->m_softstate |= MPTSAS_SS_QUIESCED;
9542 mutex_exit(&mpt->m_mutex);
9543 return (0);
9544 }
9545 }
9546 /* Bus was not busy - QUIESCED */
9547 mutex_exit(&mpt->m_mutex);
9548
9549 return (0);
9550 }
9551
9552 static int
9553 mptsas_unquiesce_bus(mptsas_t *mpt)
9554 {
9555 mptsas_target_t *ptgt = NULL;
9556
9557 NDBG28(("mptsas_unquiesce_bus"));
9558 mutex_enter(&mpt->m_mutex);
9559 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
9560 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9561 MPTSAS_HASH_FIRST);
9562 while (ptgt != NULL) {
9563 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9564
9565 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9566 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9567 }
9568 mptsas_restart_hba(mpt);
9569 mutex_exit(&mpt->m_mutex);
9570 return (0);
9571 }
9572
9573 static void
9574 mptsas_ncmds_checkdrain(void *arg)
9575 {
9576 mptsas_t *mpt = arg;
9577 mptsas_target_t *ptgt = NULL;
9578
9579 mutex_enter(&mpt->m_mutex);
9580 if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
9581 mpt->m_quiesce_timeid = 0;
9582 if (mpt->m_ncmds == 0) {
9583 /* Command queue has been drained */
9584 cv_signal(&mpt->m_cv);
9585 } else {
9586 /*
9587 * The throttle may have been reset because
9588 * of a SCSI bus reset
9589 */
9590 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9591 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9592 while (ptgt != NULL) {
9593 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9594
9595 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9596 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9597 }
9598
9599 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9600 mpt, (MPTSAS_QUIESCE_TIMEOUT *
9601 drv_usectohz(1000000)));
9602 }
9603 }
9604 mutex_exit(&mpt->m_mutex);
9605 }
9606
9607 /*ARGSUSED*/
9608 static void
9609 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
9610 {
9611 int i;
9612 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9613 char buf[128];
9614
9615 buf[0] = '\0';
9616 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
11308
11309 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
11310 return (EFAULT);
11311 }
11312
11313 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
11314 lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
11315 lc.Led < MPTSAS_LEDCTL_LED_MIN ||
11316 lc.Led > MPTSAS_LEDCTL_LED_MAX ||
11317 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
11318 lc.LedStatus != 1)) {
11319 return (EINVAL);
11320 }
11321
11322 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
11323 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
11324 return (EACCES);
11325
11326 /* Locate the target we're interrogating... */
11327 mutex_enter(&mpt->m_mutex);
11328 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11329 MPTSAS_HASH_FIRST);
11330 while (ptgt != NULL) {
11331 if (ptgt->m_enclosure == lc.Enclosure &&
11332 ptgt->m_slot_num == lc.Slot) {
11333 break;
11334 }
11335 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11336 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11337 }
11338 if (ptgt == NULL) {
11339 /* We could not find a target for that enclosure/slot. */
11340 mutex_exit(&mpt->m_mutex);
11341 return (ENOENT);
11342 }
11343
11344 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
11345 /* Update our internal LED state. */
11346 ptgt->m_led_status &= ~(1 << (lc.Led - 1));
11347 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
11348
11349 /* Flush it to the controller. */
11350 ret = mptsas_flush_led_status(mpt, ptgt);
11351 mutex_exit(&mpt->m_mutex);
11352 return (ret);
11353 }
11354
11355 /* Return our internal LED state. */
11356 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
11357 mutex_exit(&mpt->m_mutex);
11368 {
11369 uint16_t i = 0;
11370 uint16_t count = 0;
11371 int ret = 0;
11372 mptsas_target_t *ptgt;
11373 mptsas_disk_info_t *di;
11374 STRUCT_DECL(mptsas_get_disk_info, gdi);
11375
11376 if ((mode & FREAD) == 0)
11377 return (EACCES);
11378
11379 STRUCT_INIT(gdi, get_udatamodel());
11380
11381 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
11382 mode) != 0) {
11383 return (EFAULT);
11384 }
11385
11386 /* Find out how many targets there are. */
11387 mutex_enter(&mpt->m_mutex);
11388 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11389 MPTSAS_HASH_FIRST);
11390 while (ptgt != NULL) {
11391 count++;
11392 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11393 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11394 }
11395 mutex_exit(&mpt->m_mutex);
11396
11397 /*
11398 * If we haven't been asked to copy out information on each target,
11399 * then just return the count.
11400 */
11401 STRUCT_FSET(gdi, DiskCount, count);
11402 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
11403 goto copy_out;
11404
11405 /*
11406 * If we haven't been given a large enough buffer to copy out into,
11407 * let the caller know.
11408 */
11409 if (STRUCT_FGET(gdi, DiskInfoArraySize) <
11410 count * sizeof (mptsas_disk_info_t)) {
11411 ret = ENOSPC;
11412 goto copy_out;
11413 }
11414
11415 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
11416
11417 mutex_enter(&mpt->m_mutex);
11418 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11419 MPTSAS_HASH_FIRST);
11420 while (ptgt != NULL) {
11421 if (i >= count) {
11422 /*
11423 * The number of targets changed while we weren't
11424 * looking, so give up.
11425 */
11426 mutex_exit(&mpt->m_mutex);
11427 kmem_free(di, count * sizeof (mptsas_disk_info_t));
11428 return (EAGAIN);
11429 }
11430 di[i].Instance = mpt->m_instance;
11431 di[i].Enclosure = ptgt->m_enclosure;
11432 di[i].Slot = ptgt->m_slot_num;
11433 di[i].SasAddress = ptgt->m_sas_wwn;
11434
11435 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11436 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11437 i++;
11438 }
11439 mutex_exit(&mpt->m_mutex);
11440 STRUCT_FSET(gdi, DiskCount, i);
11441
11442 /* Copy out the disk information to the caller. */
11443 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
11444 i * sizeof (mptsas_disk_info_t), mode) != 0) {
11445 ret = EFAULT;
11446 }
11447
11448 kmem_free(di, count * sizeof (mptsas_disk_info_t));
11449
11450 copy_out:
11451 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi),
11452 mode) != 0) {
11453 ret = EFAULT;
11454 }
11455
11456 return (ret);
11722 int
11723 mptsas_restart_ioc(mptsas_t *mpt)
11724 {
11725 int rval = DDI_SUCCESS;
11726 mptsas_target_t *ptgt = NULL;
11727
11728 ASSERT(mutex_owned(&mpt->m_mutex));
11729
11730 /*
11731 * Set a flag telling I/O path that we're processing a reset. This is
11732 * needed because after the reset is complete, the hash table still
11733 * needs to be rebuilt. If I/Os are started before the hash table is
11734 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked
11735 * so that they can be retried.
11736 */
11737 mpt->m_in_reset = TRUE;
11738
11739 /*
11740 * Set all throttles to HOLD
11741 */
11742 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11743 MPTSAS_HASH_FIRST);
11744 while (ptgt != NULL) {
11745 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
11746
11747 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11748 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11749 }
11750
11751 /*
11752 * Disable interrupts
11753 */
11754 MPTSAS_DISABLE_INTR(mpt);
11755
11756 /*
11757 * Abort all commands: outstanding commands, commands in waitq and
11758 * tx_waitq.
11759 */
11760 mptsas_flush_hba(mpt);
11761
11762 /*
11763 * Reinitialize the chip.
11764 */
11765 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
11766 rval = DDI_FAILURE;
11767 }
11768
11769 /*
11770 * Enable interrupts again
11771 */
11772 MPTSAS_ENABLE_INTR(mpt);
11773
11774 /*
11775 * If mptsas_init_chip was successful, update the driver data.
11776 */
11777 if (rval == DDI_SUCCESS) {
11778 mptsas_update_driver_data(mpt);
11779 }
11780
11781 /*
11782 * Reset the throttles
11783 */
11784 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11785 MPTSAS_HASH_FIRST);
11786 while (ptgt != NULL) {
11787 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
11788
11789 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11790 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11791 }
11792
11793 mptsas_doneq_empty(mpt);
11794 mptsas_restart_hba(mpt);
11795
11796 if (rval != DDI_SUCCESS) {
11797 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
11798 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
11799 }
11800
11801 /*
11802 * Clear the reset flag so that I/Os can continue.
11803 */
11804 mpt->m_in_reset = FALSE;
11805
11806 return (rval);
11807 }
11808
11809 static int
11810 mptsas_init_chip(mptsas_t *mpt, int first_time)
11836 }
11837 /*
11838 * Setup configuration space
11839 */
11840 if (mptsas_config_space_init(mpt) == FALSE) {
11841 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
11842 "failed!");
11843 goto fail;
11844 }
11845
11846 /*
11847 * IOC facts can change after a diag reset so all buffers that are
11848 * based on these numbers must be de-allocated and re-allocated. Get
11849 * new IOC facts each time chip is initialized.
11850 */
11851 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
11852 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
11853 goto fail;
11854 }
11855
11856 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
11857 goto fail;
11858 }
11859 /*
11860 * Allocate request message frames, reply free queue, reply descriptor
11861 * post queue, and reply message frames using latest IOC facts.
11862 */
11863 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
11864 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
11865 goto fail;
11866 }
11867 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
11868 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
11869 goto fail;
11870 }
11871 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
11872 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
11873 goto fail;
11874 }
11875 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
12474 uint64_t ena;
12475 char buf[FM_MAX_CLASS];
12476
12477 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
12478 ena = fm_ena_generate(0, FM_ENA_FMT1);
12479 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
12480 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
12481 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
12482 }
12483 }
12484
12485 static int
12486 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
12487 uint16_t *dev_handle, mptsas_target_t **pptgt)
12488 {
12489 int rval;
12490 uint32_t dev_info;
12491 uint64_t sas_wwn;
12492 mptsas_phymask_t phymask;
12493 uint8_t physport, phynum, config, disk;
12494 mptsas_slots_t *slots = mpt->m_active;
12495 uint64_t devicename;
12496 uint16_t pdev_hdl;
12497 mptsas_target_t *tmp_tgt = NULL;
12498 uint16_t bay_num, enclosure;
12499
12500 ASSERT(*pptgt == NULL);
12501
12502 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
12503 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl,
12504 &bay_num, &enclosure);
12505 if (rval != DDI_SUCCESS) {
12506 rval = DEV_INFO_FAIL_PAGE0;
12507 return (rval);
12508 }
12509
12510 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
12511 MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12512 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
12513 rval = DEV_INFO_WRONG_DEVICE_TYPE;
12514 return (rval);
12515 }
12516
12517 /*
12518 * Check if the dev handle is for a Phys Disk. If so, set return value
12519 * and exit. Don't add Phys Disks to hash.
12520 */
12521 for (config = 0; config < slots->m_num_raid_configs; config++) {
12522 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
12523 if (*dev_handle == slots->m_raidconfig[config].
12524 m_physdisk_devhdl[disk]) {
12525 rval = DEV_INFO_PHYS_DISK;
12526 return (rval);
12527 }
12528 }
12529 }
12530
12531 /*
12532 * Get SATA Device Name from SAS device page0 for
12533 * sata device, if device name doesn't exist, set m_sas_wwn to
12534 * 0 for direct attached SATA. For the device behind the expander
12535 * we still can use STP address assigned by expander.
12536 */
12537 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12538 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12539 mutex_exit(&mpt->m_mutex);
12540 /* alloc a tmp_tgt to send the cmd */
12541 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
12542 KM_SLEEP);
12543 tmp_tgt->m_devhdl = *dev_handle;
12544 tmp_tgt->m_deviceinfo = dev_info;
12545 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
12546 tmp_tgt->m_qfull_retry_interval =
12547 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
12548 tmp_tgt->m_t_throttle = MAX_THROTTLE;
12549 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
12550 kmem_free(tmp_tgt, sizeof (struct mptsas_target));
12551 mutex_enter(&mpt->m_mutex);
12552 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
12553 sas_wwn = devicename;
12554 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
12555 sas_wwn = 0;
12556 }
12557 }
12558
12559 phymask = mptsas_physport_to_phymask(mpt, physport);
12560 *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
12561 dev_info, phymask, phynum);
12562 if (*pptgt == NULL) {
12563 mptsas_log(mpt, CE_WARN, "Failed to allocated target"
12564 "structure!");
12565 rval = DEV_INFO_FAIL_ALLOC;
12566 return (rval);
12567 }
12568 (*pptgt)->m_enclosure = enclosure;
12569 (*pptgt)->m_slot_num = bay_num;
12570 return (DEV_INFO_SUCCESS);
12571 }
12572
12573 uint64_t
12574 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
12575 {
12576 uint64_t sata_guid = 0, *pwwn = NULL;
12577 int target = ptgt->m_devhdl;
12578 uchar_t *inq83 = NULL;
12579 int inq83_len = 0xFF;
12580 uchar_t *dblk = NULL;
12970 * didn't match any device by searching
12971 */
12972 return (DDI_FAILURE);
12973 }
12974 /*
12975 * If the LUN already exists and the status is online,
12976 * we just return the pointer to dev_info_t directly.
12977 * For the mdi_pathinfo node, we'll handle it in
12978 * mptsas_create_virt_lun()
12979 * TODO should be also in mptsas_handle_dr
12980 */
12981
12982 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
12983 if (*lundip != NULL) {
12984 /*
12985 * TODO Another senario is, we hotplug the same disk
12986 * on the same slot, the devhdl changed, is this
12987 * possible?
12988 * tgt_private->t_private != ptgt
12989 */
12990 if (sasaddr != ptgt->m_sas_wwn) {
12991 /*
12992 * The device has changed although the devhdl is the
12993 * same (Enclosure mapping mode, change drive on the
12994 * same slot)
12995 */
12996 return (DDI_FAILURE);
12997 }
12998 return (DDI_SUCCESS);
12999 }
13000
13001 if (phymask == 0) {
13002 /*
13003 * Configure IR volume
13004 */
13005 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
13006 return (rval);
13007 }
13008 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
13009
13010 return (rval);
13011 }
13012
13013 static int
13014 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
13015 dev_info_t **lundip)
13016 {
13017 int rval;
13018 mptsas_t *mpt = DIP2MPT(pdip);
13019 int phymask;
13020 mptsas_target_t *ptgt = NULL;
13021
13022 /*
13023 * Get the physical port associated to the iport
13024 */
13025 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13026 "phymask", 0);
13027
13028 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
13029 if (ptgt == NULL) {
13030 /*
13031 * didn't match any device by searching
13032 */
13033 return (DDI_FAILURE);
13034 }
13035
13036 /*
13037 * If the LUN already exists and the status is online,
13038 * we just return the pointer to dev_info_t directly.
13039 * For the mdi_pathinfo node, we'll handle it in
13040 * mptsas_create_virt_lun().
13041 */
13042
13043 *lundip = mptsas_find_child_phy(pdip, phy);
13044 if (*lundip != NULL) {
13045 return (DDI_SUCCESS);
13092 struct buf *repluns_bp = NULL;
13093 struct scsi_address ap;
13094 uchar_t cdb[CDB_GROUP5];
13095 int ret = DDI_FAILURE;
13096 int retry = 0;
13097 int lun_list_len = 0;
13098 uint16_t lun_num = 0;
13099 uint8_t lun_addr_type = 0;
13100 uint32_t lun_cnt = 0;
13101 uint32_t lun_total = 0;
13102 dev_info_t *cdip = NULL;
13103 uint16_t *saved_repluns = NULL;
13104 char *buffer = NULL;
13105 int buf_len = 128;
13106 mptsas_t *mpt = DIP2MPT(pdip);
13107 uint64_t sas_wwn = 0;
13108 uint8_t phy = 0xFF;
13109 uint32_t dev_info = 0;
13110
13111 mutex_enter(&mpt->m_mutex);
13112 sas_wwn = ptgt->m_sas_wwn;
13113 phy = ptgt->m_phynum;
13114 dev_info = ptgt->m_deviceinfo;
13115 mutex_exit(&mpt->m_mutex);
13116
13117 if (sas_wwn == 0) {
13118 /*
13119 * It's a SATA without Device Name
13120 * So don't try multi-LUNs
13121 */
13122 if (mptsas_find_child_phy(pdip, phy)) {
13123 return (DDI_SUCCESS);
13124 } else {
13125 /*
13126 * need configure and create node
13127 */
13128 return (DDI_FAILURE);
13129 }
13130 }
13131
13132 /*
13207 if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
13208 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
13209 MPTSAS_DEV_GONE);
13210 }
13211 }
13212 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
13213 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
13214 scsi_free_consistent_buf(repluns_bp);
13215 return (DDI_SUCCESS);
13216 }
13217
13218 static int
13219 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
13220 {
13221 int rval = DDI_FAILURE;
13222 struct scsi_inquiry *sd_inq = NULL;
13223 mptsas_t *mpt = DIP2MPT(pdip);
13224 mptsas_target_t *ptgt = NULL;
13225
13226 mutex_enter(&mpt->m_mutex);
13227 ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target);
13228 mutex_exit(&mpt->m_mutex);
13229 if (ptgt == NULL) {
13230 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
13231 "not found.", target);
13232 return (rval);
13233 }
13234
13235 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
13236 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
13237 SUN_INQSIZE, 0, (uchar_t)0);
13238
13239 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
13240 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
13241 0);
13242 } else {
13243 rval = DDI_FAILURE;
13244 }
13245
13246 kmem_free(sd_inq, SUN_INQSIZE);
13247 return (rval);
13248 }
13249
13250 /*
13251 * configure all RAID volumes for virtual iport
13252 */
13253 static void
13254 mptsas_config_all_viport(dev_info_t *pdip)
13255 {
13256 mptsas_t *mpt = DIP2MPT(pdip);
13257 int config, vol;
13258 int target;
13259 dev_info_t *lundip = NULL;
13260 mptsas_slots_t *slots = mpt->m_active;
13261
13262 /*
13263 * Get latest RAID info and search for any Volume DevHandles. If any
13264 * are found, configure the volume.
13265 */
13266 mutex_enter(&mpt->m_mutex);
13267 for (config = 0; config < slots->m_num_raid_configs; config++) {
13268 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
13269 if (slots->m_raidconfig[config].m_raidvol[vol].m_israid
13270 == 1) {
13271 target = slots->m_raidconfig[config].
13272 m_raidvol[vol].m_raidhandle;
13273 mutex_exit(&mpt->m_mutex);
13274 (void) mptsas_config_raid(pdip, target,
13275 &lundip);
13276 mutex_enter(&mpt->m_mutex);
13277 }
13278 }
13279 }
13280 mutex_exit(&mpt->m_mutex);
13281 }
13282
13283 static void
13284 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
13285 int lun_cnt, mptsas_target_t *ptgt)
13286 {
13287 dev_info_t *child = NULL, *savechild = NULL;
13288 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
13289 uint64_t sas_wwn, wwid;
13290 uint8_t phy;
13291 int lun;
13292 int i;
13293 int find;
13294 char *addr;
13295 char *nodename;
13296 mptsas_t *mpt = DIP2MPT(pdip);
13297
13298 mutex_enter(&mpt->m_mutex);
13299 wwid = ptgt->m_sas_wwn;
13300 mutex_exit(&mpt->m_mutex);
13301
13302 child = ddi_get_child(pdip);
13303 while (child) {
13304 find = 0;
13305 savechild = child;
13306 child = ddi_get_next_sibling(child);
13307
13308 nodename = ddi_node_name(savechild);
13309 if (strcmp(nodename, "smp") == 0) {
13310 continue;
13311 }
13312
13313 addr = ddi_get_name_addr(savechild);
13314 if (addr == NULL) {
13315 continue;
13316 }
13317
13318 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
13319 DDI_SUCCESS) {
13383 uint32_t page_address;
13384 int rval = 0;
13385 uint16_t dev_handle;
13386 mptsas_target_t *ptgt = NULL;
13387 mptsas_smp_t smp_node;
13388
13389 /*
13390 * Get latest RAID info.
13391 */
13392 (void) mptsas_get_raid_info(mpt);
13393
13394 dev_handle = mpt->m_smp_devhdl;
13395 for (; mpt->m_done_traverse_smp == 0; ) {
13396 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
13397 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
13398 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
13399 != DDI_SUCCESS) {
13400 break;
13401 }
13402 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
13403 (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
13404 }
13405
13406 /*
13407 * Config target devices
13408 */
13409 dev_handle = mpt->m_dev_handle;
13410
13411 /*
13412 * Do loop to get sas device page 0 by GetNextHandle till the
13413 * the last handle. If the sas device is a SATA/SSP target,
13414 * we try to config it.
13415 */
13416 for (; mpt->m_done_traverse_dev == 0; ) {
13417 ptgt = NULL;
13418 page_address =
13419 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
13420 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
13421 (uint32_t)dev_handle;
13422 rval = mptsas_get_target_device_info(mpt, page_address,
13423 &dev_handle, &ptgt);
13424 if ((rval == DEV_INFO_FAIL_PAGE0) ||
13425 (rval == DEV_INFO_FAIL_ALLOC)) {
13426 break;
13427 }
13428
13429 mpt->m_dev_handle = dev_handle;
13430 }
13431
13432 }
13433
13434 void
13435 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab)
13436 {
13437 mptsas_hash_data_t *data;
13438 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
13439 while (data != NULL) {
13440 data->devhdl = MPTSAS_INVALID_DEVHDL;
13441 data->device_info = 0;
13442 /*
13443 * For tgttbl, clear dr_flag.
13444 */
13445 data->dr_flag = MPTSAS_DR_INACTIVE;
13446 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
13447 }
13448 }
13449
13450 void
13451 mptsas_update_driver_data(struct mptsas *mpt)
13452 {
13453 /*
13454 * TODO after hard reset, update the driver data structures
13455 * 1. update port/phymask mapping table mpt->m_phy_info
13456 * 2. invalid all the entries in hash table
13457 * m_devhdl = 0xffff and m_deviceinfo = 0
13458 * 3. call sas_device_page/expander_page to update hash table
13459 */
13460 mptsas_update_phymask(mpt);
13461 /*
13462 * Invalid the existing entries
13463 */
13464 mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl);
13465 mptsas_invalid_hashtab(&mpt->m_active->m_smptbl);
13466 mpt->m_done_traverse_dev = 0;
13467 mpt->m_done_traverse_smp = 0;
13468 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
13469 mptsas_update_hashtab(mpt);
13470 }
13471
13472 static void
13473 mptsas_config_all(dev_info_t *pdip)
13474 {
13475 dev_info_t *smpdip = NULL;
13476 mptsas_t *mpt = DIP2MPT(pdip);
13477 int phymask = 0;
13478 mptsas_phymask_t phy_mask;
13479 mptsas_target_t *ptgt = NULL;
13480 mptsas_smp_t *psmp;
13481
13482 /*
13483 * Get the phymask associated to the iport
13484 */
13485 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13486 "phymask", 0);
13487
13488 /*
13489 * Enumerate RAID volumes here (phymask == 0).
13490 */
13491 if (phymask == 0) {
13492 mptsas_config_all_viport(pdip);
13493 return;
13494 }
13495
13496 mutex_enter(&mpt->m_mutex);
13497
13498 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
13499 mptsas_update_hashtab(mpt);
13500 }
13501
13502 psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl,
13503 MPTSAS_HASH_FIRST);
13504 while (psmp != NULL) {
13505 phy_mask = psmp->m_phymask;
13506 if (phy_mask == phymask) {
13507 smpdip = NULL;
13508 mutex_exit(&mpt->m_mutex);
13509 (void) mptsas_online_smp(pdip, psmp, &smpdip);
13510 mutex_enter(&mpt->m_mutex);
13511 }
13512 psmp = (mptsas_smp_t *)mptsas_hash_traverse(
13513 &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT);
13514 }
13515
13516 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
13517 MPTSAS_HASH_FIRST);
13518 while (ptgt != NULL) {
13519 phy_mask = ptgt->m_phymask;
13520 if (phy_mask == phymask) {
13521 mutex_exit(&mpt->m_mutex);
13522 (void) mptsas_config_target(pdip, ptgt);
13523 mutex_enter(&mpt->m_mutex);
13524 }
13525
13526 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
13527 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
13528 }
13529 mutex_exit(&mpt->m_mutex);
13530 }
13531
13532 static int
13533 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
13534 {
13535 int rval = DDI_FAILURE;
13536 dev_info_t *tdip;
13537
13538 rval = mptsas_config_luns(pdip, ptgt);
13539 if (rval != DDI_SUCCESS) {
13540 /*
13541 * The return value means the SCMD_REPORT_LUNS
13542 * did not execute successfully. The target maybe
13543 * doesn't support such command.
13544 */
13545 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
13546 }
13547 return (rval);
13689 }
13690
13691 if (strcmp(smp_wwn, str_wwn) == 0) {
13692 ddi_prop_free(smp_wwn);
13693 break;
13694 }
13695 child = ddi_get_next_sibling(child);
13696 ddi_prop_free(smp_wwn);
13697 }
13698 return (child);
13699 }
13700
13701 static int
13702 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
13703 {
13704 int rval = DDI_FAILURE;
13705 char *devname;
13706 char wwn_str[MPTSAS_WWN_STRLEN];
13707 dev_info_t *cdip;
13708
13709 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
13710
13711 cdip = mptsas_find_smp_child(pdip, wwn_str);
13712
13713 if (cdip == NULL)
13714 return (DDI_SUCCESS);
13715
13716 /*
13717 * Make sure node is attached otherwise
13718 * it won't have related cache nodes to
13719 * clean up. i_ddi_devi_attached is
13720 * similiar to i_ddi_node_state(cdip) >=
13721 * DS_ATTACHED.
13722 */
13723 if (i_ddi_devi_attached(cdip)) {
13724
13725 /* Get full devname */
13726 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
13727 (void) ddi_deviname(cdip, devname);
13728 /* Clean cache */
13729 (void) devfs_clean(pdip, devname + 1,
13969 char *attached_wwn_str = NULL;
13970 char *component = NULL;
13971 uint8_t phy = 0xFF;
13972 uint64_t sas_wwn;
13973 int64_t lun64 = 0;
13974 uint32_t devinfo;
13975 uint16_t dev_hdl;
13976 uint16_t pdev_hdl;
13977 uint64_t dev_sas_wwn;
13978 uint64_t pdev_sas_wwn;
13979 uint32_t pdev_info;
13980 uint8_t physport;
13981 uint8_t phy_id;
13982 uint32_t page_address;
13983 uint16_t bay_num, enclosure;
13984 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
13985 uint32_t dev_info;
13986
13987 mutex_enter(&mpt->m_mutex);
13988 target = ptgt->m_devhdl;
13989 sas_wwn = ptgt->m_sas_wwn;
13990 devinfo = ptgt->m_deviceinfo;
13991 phy = ptgt->m_phynum;
13992 mutex_exit(&mpt->m_mutex);
13993
13994 if (sas_wwn) {
13995 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13996 } else {
13997 *pip = mptsas_find_path_phy(pdip, phy);
13998 }
13999
14000 if (*pip != NULL) {
14001 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
14002 ASSERT(*lun_dip != NULL);
14003 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
14004 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
14005 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
14006 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14007 /*
14008 * Same path back online again.
14009 */
14318 char *component = NULL;
14319 char *attached_wwn_str = NULL;
14320 uint8_t phy = 0xFF;
14321 uint64_t sas_wwn;
14322 uint32_t devinfo;
14323 uint16_t dev_hdl;
14324 uint16_t pdev_hdl;
14325 uint64_t pdev_sas_wwn;
14326 uint64_t dev_sas_wwn;
14327 uint32_t pdev_info;
14328 uint8_t physport;
14329 uint8_t phy_id;
14330 uint32_t page_address;
14331 uint16_t bay_num, enclosure;
14332 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
14333 uint32_t dev_info;
14334 int64_t lun64 = 0;
14335
14336 mutex_enter(&mpt->m_mutex);
14337 target = ptgt->m_devhdl;
14338 sas_wwn = ptgt->m_sas_wwn;
14339 devinfo = ptgt->m_deviceinfo;
14340 phy = ptgt->m_phynum;
14341 mutex_exit(&mpt->m_mutex);
14342
14343 /*
14344 * generate compatible property with binding-set "mpt"
14345 */
14346 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
14347 &nodename, &compatible, &ncompatible);
14348
14349 /*
14350 * if nodename can't be determined then print a message and skip it
14351 */
14352 if (nodename == NULL) {
14353 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
14354 "for target %d lun %d", target, lun);
14355 return (DDI_FAILURE);
14356 }
14357
14358 ndi_rtn = ndi_devi_alloc(pdip, nodename,
14437 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
14438 mptsas_log(mpt, CE_WARN, "mptsas unable to"
14439 "create property for SAS target %d lun %d"
14440 " (SAS_PROP)", target, lun);
14441 ndi_rtn = NDI_FAILURE;
14442 goto phys_create_done;
14443 }
14444 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
14445 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
14446 mptsas_log(mpt, CE_WARN, "mptsas unable "
14447 "to create guid property for target %d "
14448 "lun %d", target, lun);
14449 ndi_rtn = NDI_FAILURE;
14450 goto phys_create_done;
14451 }
14452
14453 /*
14454 * The following code is to set properties for SM-HBA support,
14455 * it doesn't apply to RAID volumes
14456 */
14457 if (ptgt->m_phymask == 0)
14458 goto phys_raid_lun;
14459
14460 mutex_enter(&mpt->m_mutex);
14461
14462 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
14463 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
14464 (uint32_t)ptgt->m_devhdl;
14465 rval = mptsas_get_sas_device_page0(mpt, page_address,
14466 &dev_hdl, &dev_sas_wwn, &dev_info,
14467 &physport, &phy_id, &pdev_hdl,
14468 &bay_num, &enclosure);
14469 if (rval != DDI_SUCCESS) {
14470 mutex_exit(&mpt->m_mutex);
14471 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
14472 "parent device for handle %d.", page_address);
14473 ndi_rtn = NDI_FAILURE;
14474 goto phys_create_done;
14475 }
14476
14477 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
14591 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
14592 if (guid) {
14593 (void) snprintf(component, MAXPATHLEN,
14594 "disk@w%s,%x", wwn_str, lun);
14595 } else {
14596 (void) snprintf(component, MAXPATHLEN,
14597 "disk@p%x,%x", phy, lun);
14598 }
14599 if (ddi_pathname_obp_set(*lun_dip, component)
14600 != DDI_SUCCESS) {
14601 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
14602 "unable to set obp-path for SAS "
14603 "object %s", component);
14604 ndi_rtn = NDI_FAILURE;
14605 goto phys_create_done;
14606 }
14607 }
14608 /*
14609 * Create the phy-num property for non-raid disk
14610 */
14611 if (ptgt->m_phymask != 0) {
14612 if (ndi_prop_update_int(DDI_DEV_T_NONE,
14613 *lun_dip, "phy-num", ptgt->m_phynum) !=
14614 DDI_PROP_SUCCESS) {
14615 mptsas_log(mpt, CE_WARN, "mptsas driver "
14616 "failed to create phy-num property for "
14617 "target %d", target);
14618 ndi_rtn = NDI_FAILURE;
14619 goto phys_create_done;
14620 }
14621 }
14622 phys_create_done:
14623 /*
14624 * If props were setup ok, online the lun
14625 */
14626 if (ndi_rtn == NDI_SUCCESS) {
14627 /*
14628 * Try to online the new node
14629 */
14630 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
14631 }
14713 char attached_wwn_str[MPTSAS_WWN_STRLEN];
14714 int ndi_rtn = NDI_FAILURE;
14715 int rval = 0;
14716 mptsas_smp_t dev_info;
14717 uint32_t page_address;
14718 mptsas_t *mpt = DIP2MPT(pdip);
14719 uint16_t dev_hdl;
14720 uint64_t sas_wwn;
14721 uint64_t smp_sas_wwn;
14722 uint8_t physport;
14723 uint8_t phy_id;
14724 uint16_t pdev_hdl;
14725 uint8_t numphys = 0;
14726 uint16_t i = 0;
14727 char phymask[MPTSAS_MAX_PHYS];
14728 char *iport = NULL;
14729 mptsas_phymask_t phy_mask = 0;
14730 uint16_t attached_devhdl;
14731 uint16_t bay_num, enclosure;
14732
14733 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
14734
14735 /*
14736 * Probe smp device, prevent the node of removed device from being
14737 * configured succesfully
14738 */
14739 if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) {
14740 return (DDI_FAILURE);
14741 }
14742
14743 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
14744 return (DDI_SUCCESS);
14745 }
14746
14747 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
14748
14749 /*
14750 * if lun alloc success, set props
14751 */
14752 if (ndi_rtn == NDI_SUCCESS) {
14753 /*
14754 * Set the flavor of the child to be SMP flavored
14755 */
14756 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
14757
14758 if (ndi_prop_update_string(DDI_DEV_T_NONE,
14759 *smp_dip, SMP_WWN, wwn_str) !=
14760 DDI_PROP_SUCCESS) {
14761 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
14762 "property for smp device %s (sas_wwn)",
14763 wwn_str);
14764 ndi_rtn = NDI_FAILURE;
14765 goto smp_create_done;
14766 }
14767 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr);
14768 if (ndi_prop_update_string(DDI_DEV_T_NONE,
14769 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
14770 DDI_PROP_SUCCESS) {
14771 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
14772 "property for iport target-port %s (sas_wwn)",
14773 wwn_str);
14774 ndi_rtn = NDI_FAILURE;
14775 goto smp_create_done;
14776 }
14777
14778 mutex_enter(&mpt->m_mutex);
14779
14780 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
14781 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl;
14782 rval = mptsas_get_sas_expander_page0(mpt, page_address,
14783 &dev_info);
14784 if (rval != DDI_SUCCESS) {
14785 mutex_exit(&mpt->m_mutex);
14786 mptsas_log(mpt, CE_WARN,
14787 "mptsas unable to get expander "
15031 smp_pkt->smp_pkt_reason = EIO;
15032 break;
15033 }
15034 return (DDI_FAILURE);
15035 }
15036 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
15037 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
15038 rep.SASStatus);
15039 smp_pkt->smp_pkt_reason = EIO;
15040 return (DDI_FAILURE);
15041 }
15042
15043 return (DDI_SUCCESS);
15044 }
15045
15046 /*
15047 * If we didn't get a match, we need to get sas page0 for each device, and
15048 * untill we get a match. If failed, return NULL
15049 */
15050 static mptsas_target_t *
15051 mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy)
15052 {
15053 int i, j = 0;
15054 int rval = 0;
15055 uint16_t cur_handle;
15056 uint32_t page_address;
15057 mptsas_target_t *ptgt = NULL;
15058
15059 /*
15060 * PHY named device must be direct attached and attaches to
15061 * narrow port, if the iport is not parent of the device which
15062 * we are looking for.
15063 */
15064 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
15065 if ((1 << i) & phymask)
15066 j++;
15067 }
15068
15069 if (j > 1)
15070 return (NULL);
15071
15072 /*
15073 * Must be a narrow port and single device attached to the narrow port
15074 * So the physical port num of device which is equal to the iport's
15075 * port num is the device what we are looking for.
15076 */
15077
15078 if (mpt->m_phy_info[phy].phy_mask != phymask)
15079 return (NULL);
15080
15081 mutex_enter(&mpt->m_mutex);
15082
15083 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
15084 MPTSAS_HASH_FIRST);
15085 while (ptgt != NULL) {
15086 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
15087 mutex_exit(&mpt->m_mutex);
15088 return (ptgt);
15089 }
15090
15091 ptgt = (mptsas_target_t *)mptsas_hash_traverse(
15092 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
15093 }
15094
15095 if (mpt->m_done_traverse_dev) {
15096 mutex_exit(&mpt->m_mutex);
15097 return (NULL);
15098 }
15099
15100 /* If didn't get a match, come here */
15101 cur_handle = mpt->m_dev_handle;
15102 for (; ; ) {
15103 ptgt = NULL;
15104 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
15105 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
15106 rval = mptsas_get_target_device_info(mpt, page_address,
15107 &cur_handle, &ptgt);
15108 if ((rval == DEV_INFO_FAIL_PAGE0) ||
15109 (rval == DEV_INFO_FAIL_ALLOC)) {
15110 break;
15111 }
15112 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15113 (rval == DEV_INFO_PHYS_DISK)) {
15114 continue;
15115 }
15116 mpt->m_dev_handle = cur_handle;
15117
15118 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
15119 break;
15120 }
15121 }
15122
15123 mutex_exit(&mpt->m_mutex);
15124 return (ptgt);
15125 }
15126
15127 /*
15128 * The ptgt->m_sas_wwn contains the wwid for each disk.
15129 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
15130 * If we didn't get a match, we need to get sas page0 for each device, and
15131 * untill we get a match
15132 * If failed, return NULL
15133 */
15134 static mptsas_target_t *
15135 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid)
15136 {
15137 int rval = 0;
15138 uint16_t cur_handle;
15139 uint32_t page_address;
15140 mptsas_target_t *tmp_tgt = NULL;
15141
15142 mutex_enter(&mpt->m_mutex);
15143 tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
15144 &mpt->m_active->m_tgttbl, wwid, phymask);
15145 if (tmp_tgt != NULL) {
15146 mutex_exit(&mpt->m_mutex);
15147 return (tmp_tgt);
15148 }
15149
15150 if (phymask == 0) {
15151 /*
15152 * It's IR volume
15153 */
15154 rval = mptsas_get_raid_info(mpt);
15155 if (rval) {
15156 tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
15157 &mpt->m_active->m_tgttbl, wwid, phymask);
15158 }
15159 mutex_exit(&mpt->m_mutex);
15160 return (tmp_tgt);
15161 }
15162
15163 if (mpt->m_done_traverse_dev) {
15164 mutex_exit(&mpt->m_mutex);
15165 return (NULL);
15166 }
15167
15168 /* If didn't get a match, come here */
15169 cur_handle = mpt->m_dev_handle;
15170 for (; ; ) {
15171 tmp_tgt = NULL;
15172 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
15173 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
15174 rval = mptsas_get_target_device_info(mpt, page_address,
15175 &cur_handle, &tmp_tgt);
15176 if ((rval == DEV_INFO_FAIL_PAGE0) ||
15177 (rval == DEV_INFO_FAIL_ALLOC)) {
15178 tmp_tgt = NULL;
15179 break;
15180 }
15181 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15182 (rval == DEV_INFO_PHYS_DISK)) {
15183 continue;
15184 }
15185 mpt->m_dev_handle = cur_handle;
15186 if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) &&
15187 (tmp_tgt->m_phymask == phymask)) {
15188 break;
15189 }
15190 }
15191
15192 mutex_exit(&mpt->m_mutex);
15193 return (tmp_tgt);
15194 }
15195
15196 static mptsas_smp_t *
15197 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid)
15198 {
15199 int rval = 0;
15200 uint16_t cur_handle;
15201 uint32_t page_address;
15202 mptsas_smp_t smp_node, *psmp = NULL;
15203
15204 mutex_enter(&mpt->m_mutex);
15205 psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl,
15206 wwid, phymask);
15207 if (psmp != NULL) {
15208 mutex_exit(&mpt->m_mutex);
15209 return (psmp);
15210 }
15211
15212 if (mpt->m_done_traverse_smp) {
15213 mutex_exit(&mpt->m_mutex);
15214 return (NULL);
15215 }
15216
15217 /* If didn't get a match, come here */
15218 cur_handle = mpt->m_smp_devhdl;
15219 for (; ; ) {
15220 psmp = NULL;
15221 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
15222 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
15223 rval = mptsas_get_sas_expander_page0(mpt, page_address,
15224 &smp_node);
15225 if (rval != DDI_SUCCESS) {
15226 break;
15227 }
15228 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
15229 psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
15230 ASSERT(psmp);
15231 if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) &&
15232 (psmp->m_phymask == phymask)) {
15233 break;
15234 }
15235 }
15236
15237 mutex_exit(&mpt->m_mutex);
15238 return (psmp);
15239 }
15240
15241 /* helper functions using hash */
15242
15243 /*
15244 * Can't have duplicate entries for same devhdl,
15245 * if there are invalid entries, the devhdl should be set to 0xffff
15246 */
15247 static void *
15248 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl)
15249 {
15250 mptsas_hash_data_t *data;
15251
15252 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
15253 while (data != NULL) {
15254 if (data->devhdl == devhdl) {
15255 break;
15256 }
15257 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
15258 }
15259 return (data);
15260 }
15261
15262 mptsas_target_t *
15263 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
15264 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
15265 {
15266 mptsas_target_t *tmp_tgt = NULL;
15267
15268 tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
15269 if (tmp_tgt != NULL) {
15270 NDBG20(("Hash item already exist"));
15271 tmp_tgt->m_deviceinfo = devinfo;
15272 tmp_tgt->m_devhdl = devhdl;
15273 return (tmp_tgt);
15274 }
15275 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
15276 if (tmp_tgt == NULL) {
15277 cmn_err(CE_WARN, "Fatal, allocated tgt failed");
15278 return (NULL);
15279 }
15280 tmp_tgt->m_devhdl = devhdl;
15281 tmp_tgt->m_sas_wwn = wwid;
15282 tmp_tgt->m_deviceinfo = devinfo;
15283 tmp_tgt->m_phymask = phymask;
15284 tmp_tgt->m_phynum = phynum;
15285 /* Initialized the tgt structure */
15286 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
15287 tmp_tgt->m_qfull_retry_interval =
15288 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
15289 tmp_tgt->m_t_throttle = MAX_THROTTLE;
15290
15291 mptsas_hash_add(hashtab, tmp_tgt);
15292
15293 return (tmp_tgt);
15294 }
15295
15296 static void
15297 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
15298 mptsas_phymask_t phymask)
15299 {
15300 mptsas_target_t *tmp_tgt;
15301 tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
15302 if (tmp_tgt == NULL) {
15303 cmn_err(CE_WARN, "Tgt not found, nothing to free");
15304 } else {
15305 kmem_free(tmp_tgt, sizeof (struct mptsas_target));
15306 }
15307 }
15308
15309 /*
15310 * Return the entry in the hash table
15311 */
15312 static mptsas_smp_t *
15313 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
15314 {
15315 uint64_t key1 = data->m_sasaddr;
15316 mptsas_phymask_t key2 = data->m_phymask;
15317 mptsas_smp_t *ret_data;
15318
15319 ret_data = mptsas_hash_search(hashtab, key1, key2);
15320 if (ret_data != NULL) {
15321 bcopy(data, ret_data, sizeof (mptsas_smp_t));
15322 return (ret_data);
15323 }
15324
15325 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
15326 bcopy(data, ret_data, sizeof (mptsas_smp_t));
15327 mptsas_hash_add(hashtab, ret_data);
15328 return (ret_data);
15329 }
15330
15331 static void
15332 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
15333 mptsas_phymask_t phymask)
15334 {
15335 mptsas_smp_t *tmp_smp;
15336 tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask);
15337 if (tmp_smp == NULL) {
15338 cmn_err(CE_WARN, "Smp element not found, nothing to free");
15339 } else {
15340 kmem_free(tmp_smp, sizeof (struct mptsas_smp));
15341 }
15342 }
15343
15344 /*
15345 * Hash operation functions
15346 * key1 is the sas_wwn, key2 is the phymask
15347 */
15348 static void
15349 mptsas_hash_init(mptsas_hash_table_t *hashtab)
15350 {
15351 if (hashtab == NULL) {
15352 return;
15353 }
15354 bzero(hashtab->head, sizeof (mptsas_hash_node_t) *
15355 MPTSAS_HASH_ARRAY_SIZE);
15356 hashtab->cur = NULL;
15357 hashtab->line = 0;
15358 }
15359
15360 static void
15361 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen)
15362 {
15363 uint16_t line = 0;
15364 mptsas_hash_node_t *cur = NULL, *last = NULL;
15365
15366 if (hashtab == NULL) {
15367 return;
15368 }
15369 for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) {
15370 cur = hashtab->head[line];
15371 while (cur != NULL) {
15372 last = cur;
15373 cur = cur->next;
15374 kmem_free(last->data, datalen);
15375 kmem_free(last, sizeof (mptsas_hash_node_t));
15376 }
15377 }
15378 }
15379
15380 /*
15381 * You must guarantee the element doesn't exist in the hash table
15382 * before you call mptsas_hash_add()
15383 */
15384 static void
15385 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data)
15386 {
15387 uint64_t key1 = ((mptsas_hash_data_t *)data)->key1;
15388 mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2;
15389 mptsas_hash_node_t **head = NULL;
15390 mptsas_hash_node_t *node = NULL;
15391
15392 if (hashtab == NULL) {
15393 return;
15394 }
15395 ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL);
15396 node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP);
15397 node->data = data;
15398
15399 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
15400 if (*head == NULL) {
15401 *head = node;
15402 } else {
15403 node->next = *head;
15404 *head = node;
15405 }
15406 }
15407
15408 static void *
15409 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
15410 mptsas_phymask_t key2)
15411 {
15412 mptsas_hash_node_t **head = NULL;
15413 mptsas_hash_node_t *last = NULL, *cur = NULL;
15414 mptsas_hash_data_t *data;
15415 if (hashtab == NULL) {
15416 return (NULL);
15417 }
15418 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
15419 cur = *head;
15420 while (cur != NULL) {
15421 data = cur->data;
15422 if ((data->key1 == key1) && (data->key2 == key2)) {
15423 if (last == NULL) {
15424 (*head) = cur->next;
15425 } else {
15426 last->next = cur->next;
15427 }
15428 kmem_free(cur, sizeof (mptsas_hash_node_t));
15429 return (data);
15430 } else {
15431 last = cur;
15432 cur = cur->next;
15433 }
15434 }
15435 return (NULL);
15436 }
15437
15438 static void *
15439 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
15440 mptsas_phymask_t key2)
15441 {
15442 mptsas_hash_node_t *cur = NULL;
15443 mptsas_hash_data_t *data;
15444 if (hashtab == NULL) {
15445 return (NULL);
15446 }
15447 cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE];
15448 while (cur != NULL) {
15449 data = cur->data;
15450 if ((data->key1 == key1) && (data->key2 == key2)) {
15451 return (data);
15452 } else {
15453 cur = cur->next;
15454 }
15455 }
15456 return (NULL);
15457 }
15458
15459 static void *
15460 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos)
15461 {
15462 mptsas_hash_node_t *this = NULL;
15463
15464 if (hashtab == NULL) {
15465 return (NULL);
15466 }
15467
15468 if (pos == MPTSAS_HASH_FIRST) {
15469 hashtab->line = 0;
15470 hashtab->cur = NULL;
15471 this = hashtab->head[0];
15472 } else {
15473 if (hashtab->cur == NULL) {
15474 return (NULL);
15475 } else {
15476 this = hashtab->cur->next;
15477 }
15478 }
15479
15480 while (this == NULL) {
15481 hashtab->line++;
15482 if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
15483 /* the traverse reaches the end */
15484 hashtab->cur = NULL;
15485 return (NULL);
15486 } else {
15487 this = hashtab->head[hashtab->line];
15488 }
15489 }
15490 hashtab->cur = this;
15491 return (this->data);
15492 }
15493
15494 /*
15495 * Functions for SGPIO LED support
15496 */
15497 static dev_info_t *
15498 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
15499 {
15500 dev_info_t *dip;
15501 int prop;
15502 dip = e_ddi_hold_devi_by_dev(dev, 0);
15503 if (dip == NULL)
15504 return (dip);
15505 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
15506 "phymask", 0);
15507 *phymask = (mptsas_phymask_t)prop;
15508 ddi_release_devi(dip);
15509 return (dip);
15510 }
15511 static mptsas_target_t *
15512 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
15513 {
15514 uint8_t phynum;
15557 Mpi2SepRequest_t req;
15558 Mpi2SepReply_t rep;
15559 int ret;
15560
15561 ASSERT(mutex_owned(&mpt->m_mutex));
15562
15563 /*
15564 * We only support SEP control of directly-attached targets, in which
15565 * case the "SEP" we're talking to is a virtual one contained within
15566 * the HBA itself. This is necessary because DA targets typically have
15567 * no other mechanism for LED control. Targets for which a separate
15568 * enclosure service processor exists should be controlled via ses(7d)
15569 * or sgen(7d). Furthermore, since such requests can time out, they
15570 * should be made in user context rather than in response to
15571 * asynchronous fabric changes.
15572 *
15573 * In addition, we do not support this operation for RAID volumes,
15574 * since there is no slot associated with them.
15575 */
15576 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
15577 ptgt->m_phymask == 0) {
15578 return (ENOTTY);
15579 }
15580
15581 bzero(&req, sizeof (req));
15582 bzero(&rep, sizeof (rep));
15583
15584 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
15585 req.Action = act;
15586 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
15587 req.EnclosureHandle = LE_16(ptgt->m_enclosure);
15588 req.Slot = LE_16(ptgt->m_slot_num);
15589 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
15590 req.SlotStatus = LE_32(*status);
15591 }
15592 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
15593 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
15594 if (ret != 0) {
15595 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
15596 "Processor Request message error %d", ret);
15597 return (ret);
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2014, Joyent, Inc. All rights reserved.
26 * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved.
27 */
28
29 /*
30 * Copyright (c) 2000 to 2010, LSI Corporation.
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms of all code within
34 * this file that is exclusively owned by LSI, with or without
35 * modification, is permitted provided that, in addition to the CDDL 1.0
36 * License requirements, the following conditions are met:
37 *
38 * Neither the name of the author nor the names of its contributors may be
39 * used to endorse or promote products derived from this software without
40 * specific prior written permission.
41 *
42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
45 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
80
81 #pragma pack(1)
82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
90 #pragma pack()
91
92 /*
93 * private header files.
94 *
95 */
96 #include <sys/scsi/impl/scsi_reset_notify.h>
97 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
98 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
99 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h>
100 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h>
101 #include <sys/raidioctl.h>
102
103 #include <sys/fs/dv_node.h> /* devfs_clean */
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 /*
320 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
321
322 /*
323 * helper functions
324 */
325 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
326
327 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
328 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
329 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
330 int lun);
331 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
332 int lun);
333 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
334 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
335
336 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
337 int *lun);
338 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
339
340 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt,
341 mptsas_phymask_t phymask, uint8_t phy);
342 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt,
343 mptsas_phymask_t phymask, uint64_t wwid);
344 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt,
345 mptsas_phymask_t phymask, uint64_t wwid);
346
347 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
348 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
349
350 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
351 uint16_t *handle, mptsas_target_t **pptgt);
352 static void mptsas_update_phymask(mptsas_t *mpt);
353
354 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt,
355 uint32_t *status, uint8_t cmd);
356 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev,
357 mptsas_phymask_t *phymask);
358 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr,
359 mptsas_phymask_t phymask);
360 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt);
361
362
363 /*
364 * Enumeration / DR functions
365 */
391 static void mptsas_offline_missed_luns(dev_info_t *pdip,
392 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
393 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
394 mdi_pathinfo_t *rpip, uint_t flags);
395
396 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
397 dev_info_t **smp_dip);
398 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
399 uint_t flags);
400
401 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
402 int mode, int *rval);
403 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
404 int mode, int *rval);
405 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
406 int mode, int *rval);
407 static void mptsas_record_event(void *args);
408 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
409 int mode);
410
411 mptsas_target_t *mptsas_tgt_alloc(mptsas_t *, uint16_t, uint64_t,
412 uint32_t, mptsas_phymask_t, uint8_t);
413 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *);
414 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
415 dev_info_t **smp_dip);
416
417 /*
418 * Power management functions
419 */
420 static int mptsas_get_pci_cap(mptsas_t *mpt);
421 static int mptsas_init_pm(mptsas_t *mpt);
422
423 /*
424 * MPT MSI tunable:
425 *
426 * By default MSI is enabled on all supported platforms.
427 */
428 boolean_t mptsas_enable_msi = B_TRUE;
429 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE;
430
431 static int mptsas_register_intrs(mptsas_t *);
432 static void mptsas_unregister_intrs(mptsas_t *);
433 static int mptsas_add_intrs(mptsas_t *, int);
665 mutex_destroy(&mptsas_global_mutex);
666 rw_destroy(&mptsas_global_rwlock);
667 mutex_destroy(&mptsas_log_mutex);
668 }
669 return (status);
670 }
671
672 /*
673 * The loadable-module _info(9E) entry point
674 */
675 int
676 _info(struct modinfo *modinfop)
677 {
678 /* CONSTCOND */
679 ASSERT(NO_COMPETING_THREADS);
680 NDBG0(("mptsas _info"));
681
682 return (mod_info(&modlinkage, modinfop));
683 }
684
685 static int
686 mptsas_target_eval_devhdl(const void *op, void *arg)
687 {
688 uint16_t dh = *(uint16_t *)arg;
689 const mptsas_target_t *tp = op;
690
691 return ((int)tp->m_devhdl - (int)dh);
692 }
693
694 static int
695 mptsas_target_eval_slot(const void *op, void *arg)
696 {
697 mptsas_led_control_t *lcp = arg;
698 const mptsas_target_t *tp = op;
699
700 if (tp->m_enclosure != lcp->Enclosure)
701 return ((int)tp->m_enclosure - (int)lcp->Enclosure);
702
703 return ((int)tp->m_slot_num - (int)lcp->Slot);
704 }
705
706 static int
707 mptsas_target_eval_nowwn(const void *op, void *arg)
708 {
709 uint8_t phy = *(uint8_t *)arg;
710 const mptsas_target_t *tp = op;
711
712 if (tp->m_addr.mta_wwn != 0)
713 return (-1);
714
715 return ((int)tp->m_phynum - (int)phy);
716 }
717
718 static int
719 mptsas_smp_eval_devhdl(const void *op, void *arg)
720 {
721 uint16_t dh = *(uint16_t *)arg;
722 const mptsas_smp_t *sp = op;
723
724 return ((int)sp->m_devhdl - (int)dh);
725 }
726
727 static uint64_t
728 mptsas_target_addr_hash(const void *tp)
729 {
730 const mptsas_target_addr_t *tap = tp;
731
732 return ((tap->mta_wwn & 0xffffffffffffULL) |
733 ((uint64_t)tap->mta_phymask << 48));
734 }
735
736 static int
737 mptsas_target_addr_cmp(const void *a, const void *b)
738 {
739 const mptsas_target_addr_t *aap = a;
740 const mptsas_target_addr_t *bap = b;
741
742 if (aap->mta_wwn < bap->mta_wwn)
743 return (-1);
744 if (aap->mta_wwn > bap->mta_wwn)
745 return (1);
746 return ((int)bap->mta_phymask - (int)aap->mta_phymask);
747 }
748
749 static void
750 mptsas_target_free(void *op)
751 {
752 kmem_free(op, sizeof (mptsas_target_t));
753 }
754
755 static void
756 mptsas_smp_free(void *op)
757 {
758 kmem_free(op, sizeof (mptsas_smp_t));
759 }
760
761 static void
762 mptsas_destroy_hashes(mptsas_t *mpt)
763 {
764 mptsas_target_t *tp;
765 mptsas_smp_t *sp;
766
767 for (tp = refhash_first(mpt->m_targets); tp != NULL;
768 tp = refhash_next(mpt->m_targets, tp)) {
769 refhash_remove(mpt->m_targets, tp);
770 }
771 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
772 sp = refhash_next(mpt->m_smp_targets, sp)) {
773 refhash_remove(mpt->m_smp_targets, sp);
774 }
775 refhash_destroy(mpt->m_targets);
776 refhash_destroy(mpt->m_smp_targets);
777 mpt->m_targets = NULL;
778 mpt->m_smp_targets = NULL;
779 }
780
781 static int
782 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
783 {
784 dev_info_t *pdip;
785 mptsas_t *mpt;
786 scsi_hba_tran_t *hba_tran;
787 char *iport = NULL;
788 char phymask[MPTSAS_MAX_PHYS];
789 mptsas_phymask_t phy_mask = 0;
790 int dynamic_port = 0;
791 uint32_t page_address;
792 char initiator_wwnstr[MPTSAS_WWN_STRLEN];
793 int rval = DDI_FAILURE;
794 int i = 0;
795 uint8_t numphys = 0;
796 uint8_t phy_id;
797 uint8_t phy_port = 0;
798 uint16_t attached_devhdl = 0;
799 uint32_t dev_info;
800 uint64_t attached_sas_wwn;
801 uint16_t dev_hdl;
1469
1470 if (mptsas_timeout_id && (mptsas_head == NULL)) {
1471 timeout_id_t tid = mptsas_timeout_id;
1472 mptsas_timeouts_enabled = 0;
1473 mptsas_timeout_id = 0;
1474 mutex_exit(&mptsas_global_mutex);
1475 (void) untimeout(tid);
1476 mutex_enter(&mptsas_global_mutex);
1477 }
1478 mutex_exit(&mptsas_global_mutex);
1479 /* deallocate in reverse order */
1480 mptsas_cache_destroy(mpt);
1481
1482 if (smp_attach_setup) {
1483 mptsas_smp_teardown(mpt);
1484 }
1485 if (hba_attach_setup) {
1486 mptsas_hba_teardown(mpt);
1487 }
1488
1489 if (mpt->m_targets)
1490 refhash_destroy(mpt->m_targets);
1491 if (mpt->m_smp_targets)
1492 refhash_destroy(mpt->m_smp_targets);
1493
1494 if (mpt->m_active) {
1495 mptsas_free_active_slots(mpt);
1496 }
1497 if (intr_added) {
1498 mptsas_unregister_intrs(mpt);
1499 }
1500
1501 if (doneq_thread_create) {
1502 mutex_enter(&mpt->m_doneq_mutex);
1503 doneq_thread_num = mpt->m_doneq_thread_n;
1504 for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1505 mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1506 mpt->m_doneq_thread_id[j].flag &=
1507 (~MPTSAS_DONEQ_THREAD_ACTIVE);
1508 cv_signal(&mpt->m_doneq_thread_id[j].cv);
1509 mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1510 }
1511 while (mpt->m_doneq_thread_n) {
1512 cv_wait(&mpt->m_doneq_thread_cv,
1513 &mpt->m_doneq_mutex);
1514 }
1907 mptsas_timeout_id = 0;
1908 mutex_exit(&mptsas_global_mutex);
1909 (void) untimeout(tid);
1910 mutex_enter(&mptsas_global_mutex);
1911 }
1912 if (mptsas_reset_watch) {
1913 tid = mptsas_reset_watch;
1914 mptsas_reset_watch = 0;
1915 mutex_exit(&mptsas_global_mutex);
1916 (void) untimeout(tid);
1917 mutex_enter(&mptsas_global_mutex);
1918 }
1919 }
1920 mutex_exit(&mptsas_global_mutex);
1921
1922 /*
1923 * Delete Phy stats
1924 */
1925 mptsas_destroy_phy_stats(mpt);
1926
1927 mptsas_destroy_hashes(mpt);
1928
1929 /*
1930 * Delete nt_active.
1931 */
1932 mutex_enter(&mpt->m_mutex);
1933 mptsas_free_active_slots(mpt);
1934 mutex_exit(&mpt->m_mutex);
1935
1936 /* deallocate everything that was allocated in mptsas_attach */
1937 mptsas_cache_destroy(mpt);
1938
1939 mptsas_hba_fini(mpt);
1940 mptsas_cfg_fini(mpt);
1941
1942 /* Lower the power informing PM Framework */
1943 if (mpt->m_options & MPTSAS_OPT_PM) {
1944 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
1945 mptsas_log(mpt, CE_WARN,
1946 "!mptsas%d: Lower power request failed "
1947 "during detach, ignoring.",
1948 mpt->m_instance);
1949 }
1950
1951 mutex_destroy(&mpt->m_tx_waitq_mutex);
1952 mutex_destroy(&mpt->m_passthru_mutex);
2173 (void) scsi_hba_iport_register(mpt->m_dip, "v0");
2174
2175 }
2176
2177 static int
2178 mptsas_smp_setup(mptsas_t *mpt)
2179 {
2180 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip);
2181 ASSERT(mpt->m_smptran != NULL);
2182 mpt->m_smptran->smp_tran_hba_private = mpt;
2183 mpt->m_smptran->smp_tran_start = mptsas_smp_start;
2184 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) {
2185 mptsas_log(mpt, CE_WARN, "smp attach setup failed");
2186 smp_hba_tran_free(mpt->m_smptran);
2187 mpt->m_smptran = NULL;
2188 return (FALSE);
2189 }
2190 /*
2191 * Initialize smp hash table
2192 */
2193 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT,
2194 mptsas_target_addr_hash, mptsas_target_addr_cmp,
2195 mptsas_smp_free, sizeof (mptsas_smp_t),
2196 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr),
2197 KM_SLEEP);
2198 mpt->m_smp_devhdl = 0xFFFF;
2199
2200 return (TRUE);
2201 }
2202
2203 static void
2204 mptsas_smp_teardown(mptsas_t *mpt)
2205 {
2206 (void) smp_hba_detach(mpt->m_dip);
2207 if (mpt->m_smptran != NULL) {
2208 smp_hba_tran_free(mpt->m_smptran);
2209 mpt->m_smptran = NULL;
2210 }
2211 mpt->m_smp_devhdl = 0;
2212 }
2213
2214 static int
2215 mptsas_cache_create(mptsas_t *mpt)
2216 {
2217 int instance = mpt->m_instance;
2820 {
2821 #ifndef __lock_lint
2822 _NOTE(ARGUNUSED(hba_tran))
2823 #endif
2824
2825 /*
2826 * At this point, the scsi_device structure already exists
2827 * and has been initialized.
2828 *
2829 * Use this function to allocate target-private data structures,
2830 * if needed by this HBA. Add revised flow-control and queue
2831 * properties for child here, if desired and if you can tell they
2832 * support tagged queueing by now.
2833 */
2834 mptsas_t *mpt;
2835 int lun = sd->sd_address.a_lun;
2836 mdi_pathinfo_t *pip = NULL;
2837 mptsas_tgt_private_t *tgt_private = NULL;
2838 mptsas_target_t *ptgt = NULL;
2839 char *psas_wwn = NULL;
2840 mptsas_phymask_t phymask = 0;
2841 uint64_t sas_wwn = 0;
2842 mptsas_target_addr_t addr;
2843 mpt = SDEV2MPT(sd);
2844
2845 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
2846
2847 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
2848 (void *)hba_dip, (void *)tgt_dip, lun));
2849
2850 if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
2851 (void) ndi_merge_node(tgt_dip, mptsas_name_child);
2852 ddi_set_name_addr(tgt_dip, NULL);
2853 return (DDI_FAILURE);
2854 }
2855 /*
2856 * phymask is 0 means the virtual port for RAID
2857 */
2858 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
2859 "phymask", 0);
2860 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2861 if ((pip = (void *)(sd->sd_private)) == NULL) {
2862 /*
2863 * Very bad news if this occurs. Somehow scsi_vhci has
2864 * lost the pathinfo node for this target.
2865 */
2866 return (DDI_NOT_WELL_FORMED);
2867 }
2868
2869 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
2870 DDI_PROP_SUCCESS) {
2871 mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
2872 return (DDI_FAILURE);
2873 }
2874
2875 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
2876 &psas_wwn) == MDI_SUCCESS) {
2877 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2878 sas_wwn = 0;
2879 }
2880 (void) mdi_prop_free(psas_wwn);
2881 }
2882 } else {
2883 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
2884 DDI_PROP_DONTPASS, LUN_PROP, 0);
2885 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
2886 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
2887 DDI_PROP_SUCCESS) {
2888 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2889 sas_wwn = 0;
2890 }
2891 ddi_prop_free(psas_wwn);
2892 } else {
2893 sas_wwn = 0;
2894 }
2895 }
2896
2897 ASSERT((sas_wwn != 0) || (phymask != 0));
2898 addr.mta_wwn = sas_wwn;
2899 addr.mta_phymask = phymask;
2900 mutex_enter(&mpt->m_mutex);
2901 ptgt = refhash_lookup(mpt->m_targets, &addr);
2902 mutex_exit(&mpt->m_mutex);
2903 if (ptgt == NULL) {
2904 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
2905 "gone already! phymask:%x, saswwn %"PRIx64, phymask,
2906 sas_wwn);
2907 return (DDI_FAILURE);
2908 }
2909 if (hba_tran->tran_tgt_private == NULL) {
2910 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
2911 KM_SLEEP);
2912 tgt_private->t_lun = lun;
2913 tgt_private->t_private = ptgt;
2914 hba_tran->tran_tgt_private = tgt_private;
2915 }
2916
2917 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2918 return (DDI_SUCCESS);
2919 }
2920 mutex_enter(&mpt->m_mutex);
2921
3312
3313 if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3314 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3315
3316 /*
3317 * Only flush the doneq if this is not a TM
3318 * cmd. For TM cmds the flushing of the
3319 * doneq will be done in those routines.
3320 */
3321 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3322 mptsas_doneq_empty(mpt);
3323 }
3324 }
3325 }
3326 return (rval);
3327 }
3328
3329 int
3330 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3331 {
3332 mptsas_slots_t *slots = mpt->m_active;
3333 uint_t slot, start_rotor;
3334 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
3335
3336 ASSERT(MUTEX_HELD(&mpt->m_mutex));
3337
3338 /*
3339 * Account for reserved TM request slot and reserved SMID of 0.
3340 */
3341 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2));
3342
3343 /*
3344 * Find the next available slot, beginning at m_rotor. If no slot is
3345 * available, we'll return FALSE to indicate that. This mechanism
3346 * considers only the normal slots, not the reserved slot 0 nor the
3347 * task management slot m_n_normal + 1. The rotor is left to point to
3348 * the normal slot after the one we select, unless we select the last
3349 * normal slot in which case it returns to slot 1.
3350 */
3351 start_rotor = slots->m_rotor;
3352 do {
3353 slot = slots->m_rotor++;
3354 if (slots->m_rotor > slots->m_n_normal)
3355 slots->m_rotor = 1;
3356
3357 if (slots->m_rotor == start_rotor)
3358 break;
3359 } while (slots->m_slot[slot] != NULL);
3360
3361 if (slots->m_slot[slot] != NULL)
3362 return (FALSE);
3363
3364 ASSERT(slot != 0 && slot <= slots->m_n_normal);
3365
3366 cmd->cmd_slot = slot;
3367 slots->m_slot[slot] = cmd;
3368 mpt->m_ncmds++;
3369
3370 /*
3371 * only increment per target ncmds if this is not a
3372 * command that has no target associated with it (i.e. a
3373 * event acknoledgment)
3374 */
3375 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3376 ptgt->m_t_ncmds++;
3377 }
3378 cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
3379
3380 /*
3381 * If initial timout is less than or equal to one tick, bump
3382 * the timeout by a tick so that command doesn't timeout before
3383 * its allotted time.
3384 */
3385 if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
3386 cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
3387 }
3388 return (TRUE);
3389 }
3390
3391 /*
3392 * prepare the pkt:
3393 * the pkt may have been resubmitted or just reused so
3394 * initialize some fields and do some checks.
3395 */
3396 static int
3397 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3398 {
3399 struct scsi_pkt *pkt = CMD2PKT(cmd);
3400
3401 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3402
3403 /*
3404 * Reinitialize some fields that need it; the packet may
3405 * have been resubmitted
3406 */
3407 pkt->pkt_reason = CMD_CMPLT;
3408 pkt->pkt_state = 0;
4709 static void
4710 mptsas_handle_scsi_io_success(mptsas_t *mpt,
4711 pMpi2ReplyDescriptorsUnion_t reply_desc)
4712 {
4713 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success;
4714 uint16_t SMID;
4715 mptsas_slots_t *slots = mpt->m_active;
4716 mptsas_cmd_t *cmd = NULL;
4717 struct scsi_pkt *pkt;
4718
4719 ASSERT(mutex_owned(&mpt->m_mutex));
4720
4721 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4722 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4723
4724 /*
4725 * This is a success reply so just complete the IO. First, do a sanity
4726 * check on the SMID. The final slot is used for TM requests, which
4727 * would not come into this reply handler.
4728 */
4729 if ((SMID == 0) || (SMID > slots->m_n_normal)) {
4730 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4731 SMID);
4732 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4733 return;
4734 }
4735
4736 cmd = slots->m_slot[SMID];
4737
4738 /*
4739 * print warning and return if the slot is empty
4740 */
4741 if (cmd == NULL) {
4742 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
4743 "in slot %d", SMID);
4744 return;
4745 }
4746
4747 pkt = CMD2PKT(cmd);
4748 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
4749 STATE_GOT_STATUS);
4812 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4813 return;
4814 }
4815
4816 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
4817 DDI_DMA_SYNC_FORCPU);
4818 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
4819 mpt->m_reply_frame_dma_addr));
4820 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
4821
4822 /*
4823 * don't get slot information and command for events since these values
4824 * don't exist
4825 */
4826 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
4827 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
4828 /*
4829 * This could be a TM reply, which use the last allocated SMID,
4830 * so allow for that.
4831 */
4832 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) {
4833 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
4834 "%d\n", SMID);
4835 ddi_fm_service_impact(mpt->m_dip,
4836 DDI_SERVICE_UNAFFECTED);
4837 return;
4838 }
4839
4840 cmd = slots->m_slot[SMID];
4841
4842 /*
4843 * print warning and return if the slot is empty
4844 */
4845 if (cmd == NULL) {
4846 mptsas_log(mpt, CE_WARN, "?NULL command for address "
4847 "reply in slot %d", SMID);
4848 return;
4849 }
4850 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
4851 (cmd->cmd_flags & CFLAG_CONFIG) ||
4852 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
5129 */
5130 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5131 (scsi_sense_asc(sensedata) == 0x3F) &&
5132 (scsi_sense_ascq(sensedata) == 0x0E)) ||
5133 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5134 (scsi_sense_asc(sensedata) == 0x25) &&
5135 (scsi_sense_ascq(sensedata) == 0x00))) {
5136 mptsas_topo_change_list_t *topo_node = NULL;
5137
5138 topo_node = kmem_zalloc(
5139 sizeof (mptsas_topo_change_list_t),
5140 KM_NOSLEEP);
5141 if (topo_node == NULL) {
5142 mptsas_log(mpt, CE_NOTE, "No memory"
5143 "resource for handle SAS dynamic"
5144 "reconfigure.\n");
5145 break;
5146 }
5147 topo_node->mpt = mpt;
5148 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5149 topo_node->un.phymask = ptgt->m_addr.mta_phymask;
5150 topo_node->devhdl = ptgt->m_devhdl;
5151 topo_node->object = (void *)ptgt;
5152 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5153
5154 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5155 mptsas_handle_dr,
5156 (void *)topo_node,
5157 DDI_NOSLEEP)) != DDI_SUCCESS) {
5158 mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5159 "for handle SAS dynamic reconfigure"
5160 "failed. \n");
5161 }
5162 }
5163 break;
5164 case MPI2_SCSI_STATUS_GOOD:
5165 switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5166 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5167 pkt->pkt_reason = CMD_DEV_GONE;
5168 pkt->pkt_state |= STATE_GOT_BUS;
5169 if (ptgt->m_reset_delay == 0) {
5195 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5196 mptsas_set_pkt_reason(mpt,
5197 cmd, CMD_RESET, STAT_BUS_RESET);
5198 break;
5199 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5200 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5201 mptsas_set_pkt_reason(mpt,
5202 cmd, CMD_RESET, STAT_DEV_RESET);
5203 break;
5204 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5205 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5206 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5207 mptsas_set_pkt_reason(mpt,
5208 cmd, CMD_TERMINATED, STAT_TERMINATED);
5209 break;
5210 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5211 case MPI2_IOCSTATUS_BUSY:
5212 /*
5213 * set throttles to drain
5214 */
5215 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
5216 ptgt = refhash_next(mpt->m_targets, ptgt)) {
5217 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5218 }
5219
5220 /*
5221 * retry command
5222 */
5223 cmd->cmd_flags |= CFLAG_RETRY;
5224 cmd->cmd_pkt_flags |= FLAG_HEAD;
5225
5226 (void) mptsas_accept_pkt(mpt, cmd);
5227 break;
5228 default:
5229 mptsas_log(mpt, CE_WARN,
5230 "unknown ioc_status = %x\n", ioc_status);
5231 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5232 "count = %x, scsi_status = %x", scsi_state,
5233 xferred, scsi_status);
5234 break;
5235 }
5236 break;
5237 case MPI2_SCSI_STATUS_TASK_SET_FULL:
5888 char *addr = NULL;
5889 dev_info_t *lundip;
5890 int circ = 0, circ1 = 0;
5891 char attached_wwnstr[MPTSAS_WWN_STRLEN];
5892
5893 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance));
5894
5895 ASSERT(mutex_owned(&mpt->m_mutex));
5896
5897 switch (topo_node->event) {
5898 case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5899 {
5900 char *phy_mask_name;
5901 mptsas_phymask_t phymask = 0;
5902
5903 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5904 /*
5905 * Get latest RAID info.
5906 */
5907 (void) mptsas_get_raid_info(mpt);
5908 ptgt = refhash_linear_search(mpt->m_targets,
5909 mptsas_target_eval_devhdl, &topo_node->devhdl);
5910 if (ptgt == NULL)
5911 break;
5912 } else {
5913 ptgt = (void *)topo_node->object;
5914 }
5915
5916 if (ptgt == NULL) {
5917 /*
5918 * If a Phys Disk was deleted, RAID info needs to be
5919 * updated to reflect the new topology.
5920 */
5921 (void) mptsas_get_raid_info(mpt);
5922
5923 /*
5924 * Get sas device page 0 by DevHandle to make sure if
5925 * SSP/SATA end device exist.
5926 */
5927 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
5928 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
5929 topo_node->devhdl;
5938 } else if (rval == DEV_INFO_FAIL_ALLOC) {
5939 mptsas_log(mpt, CE_NOTE,
5940 "mptsas_handle_topo_change: could not "
5941 "allocate memory. \n");
5942 }
5943 /*
5944 * If rval is DEV_INFO_PHYS_DISK than there is nothing
5945 * else to do, just leave.
5946 */
5947 if (rval != DEV_INFO_SUCCESS) {
5948 return;
5949 }
5950 }
5951
5952 ASSERT(ptgt->m_devhdl == topo_node->devhdl);
5953
5954 mutex_exit(&mpt->m_mutex);
5955 flags = topo_node->flags;
5956
5957 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
5958 phymask = ptgt->m_addr.mta_phymask;
5959 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP);
5960 (void) sprintf(phy_mask_name, "%x", phymask);
5961 parent = scsi_hba_iport_find(mpt->m_dip,
5962 phy_mask_name);
5963 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS);
5964 if (parent == NULL) {
5965 mptsas_log(mpt, CE_WARN, "Failed to find a "
5966 "iport for PD, should not happen!");
5967 mutex_enter(&mpt->m_mutex);
5968 break;
5969 }
5970 }
5971
5972 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5973 ndi_devi_enter(parent, &circ1);
5974 (void) mptsas_config_raid(parent, topo_node->devhdl,
5975 &lundip);
5976 ndi_devi_exit(parent, circ1);
5977 } else {
5978 /*
5979 * hold nexus for bus configure
5980 */
5981 ndi_devi_enter(scsi_vhci_dip, &circ);
5982 ndi_devi_enter(parent, &circ1);
5983 rval = mptsas_config_target(parent, ptgt);
5984 /*
5985 * release nexus for bus configure
5986 */
5987 ndi_devi_exit(parent, circ1);
5988 ndi_devi_exit(scsi_vhci_dip, circ);
5989
5990 /*
5991 * Add parent's props for SMHBA support
5992 */
5993 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
5994 bzero(attached_wwnstr,
5995 sizeof (attached_wwnstr));
5996 (void) sprintf(attached_wwnstr, "w%016"PRIx64,
5997 ptgt->m_addr.mta_wwn);
5998 if (ddi_prop_update_string(DDI_DEV_T_NONE,
5999 parent,
6000 SCSI_ADDR_PROP_ATTACHED_PORT,
6001 attached_wwnstr)
6002 != DDI_PROP_SUCCESS) {
6003 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6004 parent,
6005 SCSI_ADDR_PROP_ATTACHED_PORT);
6006 mptsas_log(mpt, CE_WARN, "Failed to"
6007 "attached-port props");
6008 return;
6009 }
6010 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6011 MPTSAS_NUM_PHYS, 1) !=
6012 DDI_PROP_SUCCESS) {
6013 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6014 parent, MPTSAS_NUM_PHYS);
6015 mptsas_log(mpt, CE_WARN, "Failed to"
6016 " create num-phys props");
6017 return;
6035 */
6036 mptsas_smhba_set_one_phy_props(mpt, parent,
6037 topo_node->un.physport, &attached_devhdl);
6038
6039 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6040 MPTSAS_VIRTUAL_PORT, 0) !=
6041 DDI_PROP_SUCCESS) {
6042 (void) ddi_prop_remove(DDI_DEV_T_NONE,
6043 parent, MPTSAS_VIRTUAL_PORT);
6044 mptsas_log(mpt, CE_WARN,
6045 "mptsas virtual-port"
6046 "port prop update failed");
6047 return;
6048 }
6049 }
6050 }
6051 mutex_enter(&mpt->m_mutex);
6052
6053 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
6054 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
6055 ptgt->m_addr.mta_phymask));
6056 break;
6057 }
6058 case MPTSAS_DR_EVENT_OFFLINE_TARGET:
6059 {
6060 devhdl = topo_node->devhdl;
6061 ptgt = refhash_linear_search(mpt->m_targets,
6062 mptsas_target_eval_devhdl, &devhdl);
6063 if (ptgt == NULL)
6064 break;
6065
6066 sas_wwn = ptgt->m_addr.mta_wwn;
6067 phy = ptgt->m_phynum;
6068
6069 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
6070
6071 if (sas_wwn) {
6072 (void) sprintf(addr, "w%016"PRIx64, sas_wwn);
6073 } else {
6074 (void) sprintf(addr, "p%x", phy);
6075 }
6076 ASSERT(ptgt->m_devhdl == devhdl);
6077
6078 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) ||
6079 (topo_node->flags ==
6080 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
6081 /*
6082 * Get latest RAID info if RAID volume status changes
6083 * or Phys Disk status changes
6084 */
6085 (void) mptsas_get_raid_info(mpt);
6086 }
6087 /*
6088 * Abort all outstanding command on the device
6089 */
6090 rval = mptsas_do_scsi_reset(mpt, devhdl);
6091 if (rval) {
6092 NDBG20(("mptsas%d handle_topo_change to reset target "
6093 "before offline devhdl:%x, phymask:%x, rval:%x",
6094 mpt->m_instance, ptgt->m_devhdl,
6095 ptgt->m_addr.mta_phymask, rval));
6096 }
6097
6098 mutex_exit(&mpt->m_mutex);
6099
6100 ndi_devi_enter(scsi_vhci_dip, &circ);
6101 ndi_devi_enter(parent, &circ1);
6102 rval = mptsas_offline_target(parent, addr);
6103 ndi_devi_exit(parent, circ1);
6104 ndi_devi_exit(scsi_vhci_dip, circ);
6105 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
6106 "phymask:%x, rval:%x", mpt->m_instance,
6107 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval));
6108
6109 kmem_free(addr, SCSI_MAXNAMELEN);
6110
6111 /*
6112 * Clear parent's props for SMHBA support
6113 */
6114 flags = topo_node->flags;
6115 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
6116 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6117 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6118 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6119 DDI_PROP_SUCCESS) {
6120 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6121 SCSI_ADDR_PROP_ATTACHED_PORT);
6122 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6123 "prop update failed");
6124 break;
6125 }
6126 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6127 MPTSAS_NUM_PHYS, 0) !=
6130 MPTSAS_NUM_PHYS);
6131 mptsas_log(mpt, CE_WARN, "mptsas num phys "
6132 "prop update failed");
6133 break;
6134 }
6135 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6136 MPTSAS_VIRTUAL_PORT, 1) !=
6137 DDI_PROP_SUCCESS) {
6138 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6139 MPTSAS_VIRTUAL_PORT);
6140 mptsas_log(mpt, CE_WARN, "mptsas virtual port "
6141 "prop update failed");
6142 break;
6143 }
6144 }
6145
6146 mutex_enter(&mpt->m_mutex);
6147 ptgt->m_led_status = 0;
6148 (void) mptsas_flush_led_status(mpt, ptgt);
6149 if (rval == DDI_SUCCESS) {
6150 refhash_remove(mpt->m_targets, ptgt);
6151 ptgt = NULL;
6152 } else {
6153 /*
6154 * clean DR_INTRANSITION flag to allow I/O down to
6155 * PHCI driver since failover finished.
6156 * Invalidate the devhdl
6157 */
6158 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
6159 ptgt->m_tgt_unconfigured = 0;
6160 mutex_enter(&mpt->m_tx_waitq_mutex);
6161 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
6162 mutex_exit(&mpt->m_tx_waitq_mutex);
6163 }
6164
6165 /*
6166 * Send SAS IO Unit Control to free the dev handle
6167 */
6168 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
6169 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
6170 rval = mptsas_free_devhdl(mpt, devhdl);
6187 if (rval) {
6188 NDBG20(("mpt%d reset target before remove "
6189 "devhdl:%x, rval:%x", mpt->m_instance,
6190 devhdl, rval));
6191 }
6192 }
6193
6194 /*
6195 * Send SAS IO Unit Control to free the dev handle
6196 */
6197 rval = mptsas_free_devhdl(mpt, devhdl);
6198 NDBG20(("mptsas%d handle_topo_change to remove "
6199 "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6200 rval));
6201 break;
6202 }
6203 case MPTSAS_DR_EVENT_RECONFIG_SMP:
6204 {
6205 mptsas_smp_t smp;
6206 dev_info_t *smpdip;
6207
6208 devhdl = topo_node->devhdl;
6209
6210 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6211 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6212 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6213 if (rval != DDI_SUCCESS) {
6214 mptsas_log(mpt, CE_WARN, "failed to online smp, "
6215 "handle %x", devhdl);
6216 return;
6217 }
6218
6219 psmp = mptsas_smp_alloc(mpt, &smp);
6220 if (psmp == NULL) {
6221 return;
6222 }
6223
6224 mutex_exit(&mpt->m_mutex);
6225 ndi_devi_enter(parent, &circ1);
6226 (void) mptsas_online_smp(parent, psmp, &smpdip);
6227 ndi_devi_exit(parent, circ1);
6228
6229 mutex_enter(&mpt->m_mutex);
6230 break;
6231 }
6232 case MPTSAS_DR_EVENT_OFFLINE_SMP:
6233 {
6234 devhdl = topo_node->devhdl;
6235 uint32_t dev_info;
6236
6237 psmp = refhash_linear_search(mpt->m_smp_targets,
6238 mptsas_smp_eval_devhdl, &devhdl);
6239 if (psmp == NULL)
6240 break;
6241 /*
6242 * The mptsas_smp_t data is released only if the dip is offlined
6243 * successfully.
6244 */
6245 mutex_exit(&mpt->m_mutex);
6246
6247 ndi_devi_enter(parent, &circ1);
6248 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6249 ndi_devi_exit(parent, circ1);
6250
6251 dev_info = psmp->m_deviceinfo;
6252 if ((dev_info & DEVINFO_DIRECT_ATTACHED) ==
6253 DEVINFO_DIRECT_ATTACHED) {
6254 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent,
6255 MPTSAS_VIRTUAL_PORT, 1) !=
6256 DDI_PROP_SUCCESS) {
6257 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6258 MPTSAS_VIRTUAL_PORT);
6274 }
6275 /*
6276 * Clear parent's attached-port props
6277 */
6278 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6279 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent,
6280 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) !=
6281 DDI_PROP_SUCCESS) {
6282 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent,
6283 SCSI_ADDR_PROP_ATTACHED_PORT);
6284 mptsas_log(mpt, CE_WARN, "mptsas attached port "
6285 "prop update failed");
6286 return;
6287 }
6288 }
6289
6290 mutex_enter(&mpt->m_mutex);
6291 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6292 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6293 if (rval == DDI_SUCCESS) {
6294 refhash_remove(mpt->m_smp_targets, psmp);
6295 } else {
6296 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6297 }
6298
6299 bzero(attached_wwnstr, sizeof (attached_wwnstr));
6300
6301 break;
6302 }
6303 default:
6304 return;
6305 }
6306 }
6307
6308 /*
6309 * Record the event if its type is enabled in mpt instance by ioctl.
6310 */
6311 static void
6312 mptsas_record_event(void *args)
6313 {
6314 m_replyh_arg_t *replyh_arg;
6433 }
6434
6435 /*
6436 * figure out what kind of event we got and handle accordingly
6437 */
6438 switch (event) {
6439 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6440 {
6441 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list;
6442 uint8_t num_entries, expstatus, phy;
6443 uint8_t phystatus, physport, state, i;
6444 uint8_t start_phy_num, link_rate;
6445 uint16_t dev_handle, reason_code;
6446 uint16_t enc_handle, expd_handle;
6447 char string[80], curr[80], prev[80];
6448 mptsas_topo_change_list_t *topo_head = NULL;
6449 mptsas_topo_change_list_t *topo_tail = NULL;
6450 mptsas_topo_change_list_t *topo_node = NULL;
6451 mptsas_target_t *ptgt;
6452 mptsas_smp_t *psmp;
6453 uint8_t flags = 0, exp_flag;
6454 smhba_info_t *pSmhba = NULL;
6455
6456 NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6457
6458 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6459 eventreply->EventData;
6460
6461 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6462 &sas_topo_change_list->EnclosureHandle);
6463 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6464 &sas_topo_change_list->ExpanderDevHandle);
6465 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6466 &sas_topo_change_list->NumEntries);
6467 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
6468 &sas_topo_change_list->StartPhyNum);
6469 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6470 &sas_topo_change_list->ExpStatus);
6471 physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
6472 &sas_topo_change_list->PhysicalPort);
6473
6474 string[0] = 0;
6475 if (expd_handle) {
6476 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
6477 switch (expstatus) {
6483 mpt->m_port_chng = 1;
6484 topo_node = kmem_zalloc(
6485 sizeof (mptsas_topo_change_list_t),
6486 KM_SLEEP);
6487 topo_node->mpt = mpt;
6488 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
6489 topo_node->un.physport = physport;
6490 topo_node->devhdl = expd_handle;
6491 topo_node->flags = flags;
6492 topo_node->object = NULL;
6493 if (topo_head == NULL) {
6494 topo_head = topo_tail = topo_node;
6495 } else {
6496 topo_tail->next = topo_node;
6497 topo_tail = topo_node;
6498 }
6499 break;
6500 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6501 (void) sprintf(string, " not responding, "
6502 "removed");
6503 psmp = refhash_linear_search(mpt->m_smp_targets,
6504 mptsas_smp_eval_devhdl, &expd_handle);
6505 if (psmp == NULL)
6506 break;
6507
6508 topo_node = kmem_zalloc(
6509 sizeof (mptsas_topo_change_list_t),
6510 KM_SLEEP);
6511 topo_node->mpt = mpt;
6512 topo_node->un.phymask =
6513 psmp->m_addr.mta_phymask;
6514 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6515 topo_node->devhdl = expd_handle;
6516 topo_node->flags = flags;
6517 topo_node->object = NULL;
6518 if (topo_head == NULL) {
6519 topo_head = topo_tail = topo_node;
6520 } else {
6521 topo_tail->next = topo_node;
6522 topo_tail = topo_node;
6523 }
6524 break;
6525 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
6526 break;
6527 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
6528 (void) sprintf(string, " not responding, "
6529 "delaying removal");
6530 break;
6531 default:
6532 break;
6533 }
6644 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
6645 {
6646 NDBG20(("mptsas%d phy %d physical_port %d "
6647 "dev_handle %d removed", mpt->m_instance,
6648 phy, physport, dev_handle));
6649 /*
6650 * Set association flag according to if an
6651 * expander is used or not.
6652 */
6653 exp_flag =
6654 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6655 if (flags ==
6656 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6657 flags = exp_flag;
6658 }
6659 /*
6660 * Target device is removed from the system
6661 * Before the device is really offline from
6662 * from system.
6663 */
6664 ptgt = refhash_linear_search(mpt->m_targets,
6665 mptsas_target_eval_devhdl, &dev_handle);
6666 /*
6667 * If ptgt is NULL here, it means that the
6668 * DevHandle is not in the hash table. This is
6669 * reasonable sometimes. For example, if a
6670 * disk was pulled, then added, then pulled
6671 * again, the disk will not have been put into
6672 * the hash table because the add event will
6673 * have an invalid phymask. BUT, this does not
6674 * mean that the DevHandle is invalid. The
6675 * controller will still have a valid DevHandle
6676 * that must be removed. To do this, use the
6677 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
6678 */
6679 if (ptgt == NULL) {
6680 topo_node = kmem_zalloc(
6681 sizeof (mptsas_topo_change_list_t),
6682 KM_SLEEP);
6683 topo_node->mpt = mpt;
6684 topo_node->un.phymask = 0;
6685 topo_node->event =
6697 break;
6698 }
6699
6700 /*
6701 * Update DR flag immediately avoid I/O failure
6702 * before failover finish. Pay attention to the
6703 * mutex protect, we need grab m_tx_waitq_mutex
6704 * during set m_dr_flag because we won't add
6705 * the following command into waitq, instead,
6706 * we need return TRAN_BUSY in the tran_start
6707 * context.
6708 */
6709 mutex_enter(&mpt->m_tx_waitq_mutex);
6710 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6711 mutex_exit(&mpt->m_tx_waitq_mutex);
6712
6713 topo_node = kmem_zalloc(
6714 sizeof (mptsas_topo_change_list_t),
6715 KM_SLEEP);
6716 topo_node->mpt = mpt;
6717 topo_node->un.phymask =
6718 ptgt->m_addr.mta_phymask;
6719 topo_node->event =
6720 MPTSAS_DR_EVENT_OFFLINE_TARGET;
6721 topo_node->devhdl = dev_handle;
6722 topo_node->flags = flags;
6723 topo_node->object = NULL;
6724 if (topo_head == NULL) {
6725 topo_head = topo_tail = topo_node;
6726 } else {
6727 topo_tail->next = topo_node;
6728 topo_tail = topo_node;
6729 }
6730 break;
6731 }
6732 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
6733 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6734 &sas_topo_change_list->PHY[i].LinkRate);
6735 state = (link_rate &
6736 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6737 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6738 pSmhba = &mpt->m_phy_info[i].smhba_info;
6858 if (topo_head != NULL) {
6859 /*
6860 * Launch DR taskq to handle topology change
6861 */
6862 if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6863 mptsas_handle_dr, (void *)topo_head,
6864 DDI_NOSLEEP)) != DDI_SUCCESS) {
6865 mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6866 "for handle SAS DR event failed. \n");
6867 }
6868 }
6869 break;
6870 }
6871 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6872 {
6873 Mpi2EventDataIrConfigChangeList_t *irChangeList;
6874 mptsas_topo_change_list_t *topo_head = NULL;
6875 mptsas_topo_change_list_t *topo_tail = NULL;
6876 mptsas_topo_change_list_t *topo_node = NULL;
6877 mptsas_target_t *ptgt;
6878 uint8_t num_entries, i, reason;
6879 uint16_t volhandle, diskhandle;
6880
6881 irChangeList = (pMpi2EventDataIrConfigChangeList_t)
6882 eventreply->EventData;
6883 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6884 &irChangeList->NumElements);
6885
6886 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
6887 mpt->m_instance));
6888
6889 for (i = 0; i < num_entries; i++) {
6890 reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
6891 &irChangeList->ConfigElement[i].ReasonCode);
6892 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6893 &irChangeList->ConfigElement[i].VolDevHandle);
6894 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6895 &irChangeList->ConfigElement[i].PhysDiskDevHandle);
6896
6897 switch (reason) {
6898 case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6899 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6900 {
6901 NDBG20(("mptsas %d volume added\n",
6902 mpt->m_instance));
6903
6904 topo_node = kmem_zalloc(
6905 sizeof (mptsas_topo_change_list_t),
6909 topo_node->event =
6910 MPTSAS_DR_EVENT_RECONFIG_TARGET;
6911 topo_node->un.physport = 0xff;
6912 topo_node->devhdl = volhandle;
6913 topo_node->flags =
6914 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6915 topo_node->object = NULL;
6916 if (topo_head == NULL) {
6917 topo_head = topo_tail = topo_node;
6918 } else {
6919 topo_tail->next = topo_node;
6920 topo_tail = topo_node;
6921 }
6922 break;
6923 }
6924 case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6925 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6926 {
6927 NDBG20(("mptsas %d volume deleted\n",
6928 mpt->m_instance));
6929 ptgt = refhash_linear_search(mpt->m_targets,
6930 mptsas_target_eval_devhdl, &volhandle);
6931 if (ptgt == NULL)
6932 break;
6933
6934 /*
6935 * Clear any flags related to volume
6936 */
6937 (void) mptsas_delete_volume(mpt, volhandle);
6938
6939 /*
6940 * Update DR flag immediately avoid I/O failure
6941 */
6942 mutex_enter(&mpt->m_tx_waitq_mutex);
6943 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6944 mutex_exit(&mpt->m_tx_waitq_mutex);
6945
6946 topo_node = kmem_zalloc(
6947 sizeof (mptsas_topo_change_list_t),
6948 KM_SLEEP);
6949 topo_node->mpt = mpt;
6950 topo_node->un.phymask =
6951 ptgt->m_addr.mta_phymask;
6952 topo_node->event =
6953 MPTSAS_DR_EVENT_OFFLINE_TARGET;
6954 topo_node->devhdl = volhandle;
6955 topo_node->flags =
6956 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6957 topo_node->object = (void *)ptgt;
6958 if (topo_head == NULL) {
6959 topo_head = topo_tail = topo_node;
6960 } else {
6961 topo_tail->next = topo_node;
6962 topo_tail = topo_node;
6963 }
6964 break;
6965 }
6966 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6967 case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6968 {
6969 ptgt = refhash_linear_search(mpt->m_targets,
6970 mptsas_target_eval_devhdl, &diskhandle);
6971 if (ptgt == NULL)
6972 break;
6973
6974 /*
6975 * Update DR flag immediately avoid I/O failure
6976 */
6977 mutex_enter(&mpt->m_tx_waitq_mutex);
6978 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6979 mutex_exit(&mpt->m_tx_waitq_mutex);
6980
6981 topo_node = kmem_zalloc(
6982 sizeof (mptsas_topo_change_list_t),
6983 KM_SLEEP);
6984 topo_node->mpt = mpt;
6985 topo_node->un.phymask =
6986 ptgt->m_addr.mta_phymask;
6987 topo_node->event =
6988 MPTSAS_DR_EVENT_OFFLINE_TARGET;
6989 topo_node->devhdl = diskhandle;
6990 topo_node->flags =
6991 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6992 topo_node->object = (void *)ptgt;
6993 if (topo_head == NULL) {
6994 topo_head = topo_tail = topo_node;
6995 } else {
6996 topo_tail->next = topo_node;
6997 topo_tail = topo_node;
6998 }
6999 break;
7000 }
7001 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
7002 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
7003 {
7004 /*
7005 * The physical drive is released by a IR
7006 * volume. But we cannot get the the physport
7391 SAS_PORT_BROADCAST_D27_4,
7392 &mpt->m_phy_info[phy_num].smhba_info);
7393 break;
7394 default:
7395 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE"
7396 " %x received",
7397 mpt->m_instance, primitive));
7398 break;
7399 }
7400 NDBG20(("mptsas%d sas broadcast primitive: "
7401 "\tprimitive(0x%04x), phy(%d) complete\n",
7402 mpt->m_instance, primitive, phy_num));
7403 break;
7404 }
7405 case MPI2_EVENT_IR_VOLUME:
7406 {
7407 Mpi2EventDataIrVolume_t *irVolume;
7408 uint16_t devhandle;
7409 uint32_t state;
7410 int config, vol;
7411 uint8_t found = FALSE;
7412
7413 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
7414 state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7415 &irVolume->NewValue);
7416 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7417 &irVolume->VolDevHandle);
7418
7419 NDBG20(("EVENT_IR_VOLUME event is received"));
7420
7421 /*
7422 * Get latest RAID info and then find the DevHandle for this
7423 * event in the configuration. If the DevHandle is not found
7424 * just exit the event.
7425 */
7426 (void) mptsas_get_raid_info(mpt);
7427 for (config = 0; (config < mpt->m_num_raid_configs) &&
7428 (!found); config++) {
7429 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
7430 if (mpt->m_raidconfig[config].m_raidvol[vol].
7431 m_raidhandle == devhandle) {
7432 found = TRUE;
7433 break;
7434 }
7435 }
7436 }
7437 if (!found) {
7438 break;
7439 }
7440
7441 switch (irVolume->ReasonCode) {
7442 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
7443 {
7444 uint32_t i;
7445 mpt->m_raidconfig[config].m_raidvol[vol].m_settings =
7446 state;
7447
7448 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
7449 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
7450 ", auto-config of hot-swap drives is %s"
7451 ", write caching is %s"
7452 ", hot-spare pool mask is %02x\n",
7453 vol, state &
7454 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
7455 ? "disabled" : "enabled",
7456 i == MPI2_RAIDVOL0_SETTING_UNCHANGED
7457 ? "controlled by member disks" :
7458 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7459 ? "disabled" :
7460 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7461 ? "enabled" :
7462 "incorrectly set",
7463 (state >> 16) & 0xff);
7464 break;
7465 }
7466 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7467 {
7468 mpt->m_raidconfig[config].m_raidvol[vol].m_state =
7469 (uint8_t)state;
7470
7471 mptsas_log(mpt, CE_NOTE,
7472 "Volume %d is now %s\n", vol,
7473 state == MPI2_RAID_VOL_STATE_OPTIMAL
7474 ? "optimal" :
7475 state == MPI2_RAID_VOL_STATE_DEGRADED
7476 ? "degraded" :
7477 state == MPI2_RAID_VOL_STATE_ONLINE
7478 ? "online" :
7479 state == MPI2_RAID_VOL_STATE_INITIALIZING
7480 ? "initializing" :
7481 state == MPI2_RAID_VOL_STATE_FAILED
7482 ? "failed" :
7483 state == MPI2_RAID_VOL_STATE_MISSING
7484 ? "missing" :
7485 "state unknown");
7486 break;
7487 }
7488 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7489 {
7490 mpt->m_raidconfig[config].m_raidvol[vol].
7491 m_statusflags = state;
7492
7493 mptsas_log(mpt, CE_NOTE,
7494 " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7495 vol,
7496 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7497 ? ", enabled" : ", disabled",
7498 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7499 ? ", quiesced" : "",
7500 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
7501 ? ", inactive" : ", active",
7502 state &
7503 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
7504 ? ", bad block table is full" : "",
7505 state &
7506 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
7507 ? ", resync in progress" : "",
7508 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
7509 ? ", background initialization in progress" : "",
7510 state &
7619 mpt->m_free_index = 0;
7620 }
7621 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
7622 mpt->m_free_index);
7623 mutex_exit(&mpt->m_mutex);
7624 }
7625
7626 /*
7627 * invoked from timeout() to restart qfull cmds with throttle == 0
7628 */
7629 static void
7630 mptsas_restart_cmd(void *arg)
7631 {
7632 mptsas_t *mpt = arg;
7633 mptsas_target_t *ptgt = NULL;
7634
7635 mutex_enter(&mpt->m_mutex);
7636
7637 mpt->m_restart_cmd_timeid = 0;
7638
7639 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
7640 ptgt = refhash_next(mpt->m_targets, ptgt)) {
7641 if (ptgt->m_reset_delay == 0) {
7642 if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7643 mptsas_set_throttle(mpt, ptgt,
7644 MAX_THROTTLE);
7645 }
7646 }
7647 }
7648 mptsas_restart_hba(mpt);
7649 mutex_exit(&mpt->m_mutex);
7650 }
7651
7652 void
7653 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7654 {
7655 int slot;
7656 mptsas_slots_t *slots = mpt->m_active;
7657 int t;
7658 mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7659
7660 ASSERT(cmd != NULL);
7661 ASSERT(cmd->cmd_queued == FALSE);
7662
7663 /*
7664 * Task Management cmds are removed in their own routines. Also,
7665 * we don't want to modify timeout based on TM cmds.
7666 */
7698 }
7699
7700 /*
7701 * This is all we need to do for ioc commands.
7702 */
7703 if (cmd->cmd_flags & CFLAG_CMDIOC) {
7704 mptsas_return_to_pool(mpt, cmd);
7705 return;
7706 }
7707
7708 /*
7709 * Figure out what to set tag Q timeout for...
7710 *
7711 * Optimize: If we have duplicate's of same timeout
7712 * we're using, then we'll use it again until we run
7713 * out of duplicates. This should be the normal case
7714 * for block and raw I/O.
7715 * If no duplicates, we have to scan through tag que and
7716 * find the longest timeout value and use it. This is
7717 * going to take a while...
7718 * Add 1 to m_n_normal to account for TM request.
7719 */
7720 if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
7721 if (--(ptgt->m_dups) == 0) {
7722 if (ptgt->m_t_ncmds) {
7723 mptsas_cmd_t *ssp;
7724 uint_t n = 0;
7725 ushort_t nslots = (slots->m_n_normal + 1);
7726 ushort_t i;
7727 /*
7728 * This crude check assumes we don't do
7729 * this too often which seems reasonable
7730 * for block and raw I/O.
7731 */
7732 for (i = 0; i < nslots; i++) {
7733 ssp = slots->m_slot[i];
7734 if (ssp && (Tgt(ssp) == t) &&
7735 (ssp->cmd_pkt->pkt_time > n)) {
7736 n = ssp->cmd_pkt->pkt_time;
7737 ptgt->m_dups = 1;
7738 } else if (ssp && (Tgt(ssp) == t) &&
7739 (ssp->cmd_pkt->pkt_time == n)) {
7740 ptgt->m_dups++;
7741 }
7742 }
7743 ptgt->m_timebase = n;
7744 } else {
7745 ptgt->m_dups = 0;
8464 drv_usecwait(mpt->m_scsi_reset_delay * 1000);
8465 }
8466 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
8467 mutex_exit(&mpt->m_mutex);
8468
8469 /*
8470 * The transport layer expect to only see TRUE and
8471 * FALSE. Therefore, we will adjust the return value
8472 * if mptsas_do_scsi_reset returns FAILED.
8473 */
8474 if (rval == FAILED)
8475 rval = FALSE;
8476 return (rval);
8477 }
8478
8479 static int
8480 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8481 {
8482 int rval = FALSE;
8483 uint8_t config, disk;
8484
8485 ASSERT(mutex_owned(&mpt->m_mutex));
8486
8487 if (mptsas_debug_resets) {
8488 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8489 devhdl);
8490 }
8491
8492 /*
8493 * Issue a Target Reset message to the target specified but not to a
8494 * disk making up a raid volume. Just look through the RAID config
8495 * Phys Disk list of DevHandles. If the target's DevHandle is in this
8496 * list, then don't reset this target.
8497 */
8498 for (config = 0; config < mpt->m_num_raid_configs; config++) {
8499 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8500 if (devhdl == mpt->m_raidconfig[config].
8501 m_physdisk_devhdl[disk]) {
8502 return (TRUE);
8503 }
8504 }
8505 }
8506
8507 rval = mptsas_ioc_task_management(mpt,
8508 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0);
8509
8510 mptsas_doneq_empty(mpt);
8511 return (rval);
8512 }
8513
8514 static int
8515 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
8516 void (*callback)(caddr_t), caddr_t arg)
8517 {
8518 mptsas_t *mpt = ADDR2MPT(ap);
8519
8520 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
8576 * commands for a particular target. For the case of abort task set, this
8577 * function clears the waitq of all commonds for a particular target/lun.
8578 */
8579 static void
8580 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
8581 {
8582 mptsas_slots_t *slots = mpt->m_active;
8583 mptsas_cmd_t *cmd, *next_cmd;
8584 int slot;
8585 uchar_t reason;
8586 uint_t stat;
8587
8588 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8589
8590 /*
8591 * Make sure the I/O Controller has flushed all cmds
8592 * that are associated with this target for a target reset
8593 * and target/lun for abort task set.
8594 * Account for TM requests, which use the last SMID.
8595 */
8596 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
8597 if ((cmd = slots->m_slot[slot]) == NULL)
8598 continue;
8599 reason = CMD_RESET;
8600 stat = STAT_DEV_RESET;
8601 switch (tasktype) {
8602 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8603 if (Tgt(cmd) == target) {
8604 NDBG25(("mptsas_flush_target discovered non-"
8605 "NULL cmd in slot %d, tasktype 0x%x", slot,
8606 tasktype));
8607 mptsas_dump_cmd(mpt, cmd);
8608 mptsas_remove_cmd(mpt, cmd);
8609 mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8610 mptsas_doneq_add(mpt, cmd);
8611 }
8612 break;
8613 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8614 reason = CMD_ABORTED;
8615 stat = STAT_ABORTED;
8616 /*FALLTHROUGH*/
8708
8709 /*
8710 * Clean up hba state, abort all outstanding command and commands in waitq
8711 * reset timeout of all targets.
8712 */
8713 static void
8714 mptsas_flush_hba(mptsas_t *mpt)
8715 {
8716 mptsas_slots_t *slots = mpt->m_active;
8717 mptsas_cmd_t *cmd;
8718 int slot;
8719
8720 NDBG25(("mptsas_flush_hba"));
8721
8722 /*
8723 * The I/O Controller should have already sent back
8724 * all commands via the scsi I/O reply frame. Make
8725 * sure all commands have been flushed.
8726 * Account for TM request, which use the last SMID.
8727 */
8728 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) {
8729 if ((cmd = slots->m_slot[slot]) == NULL)
8730 continue;
8731
8732 if (cmd->cmd_flags & CFLAG_CMDIOC) {
8733 /*
8734 * Need to make sure to tell everyone that might be
8735 * waiting on this command that it's going to fail. If
8736 * we get here, this command will never timeout because
8737 * the active command table is going to be re-allocated,
8738 * so there will be nothing to check against a time out.
8739 * Instead, mark the command as failed due to reset.
8740 */
8741 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
8742 STAT_BUS_RESET);
8743 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8744 (cmd->cmd_flags & CFLAG_CONFIG) ||
8745 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
8746 cmd->cmd_flags |= CFLAG_FINISHED;
8747 cv_broadcast(&mpt->m_passthru_cv);
8748 cv_broadcast(&mpt->m_config_cv);
8823 static void
8824 mptsas_start_watch_reset_delay()
8825 {
8826 NDBG22(("mptsas_start_watch_reset_delay"));
8827
8828 mutex_enter(&mptsas_global_mutex);
8829 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
8830 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
8831 drv_usectohz((clock_t)
8832 MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
8833 ASSERT(mptsas_reset_watch != NULL);
8834 }
8835 mutex_exit(&mptsas_global_mutex);
8836 }
8837
8838 static void
8839 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
8840 {
8841 mptsas_target_t *ptgt = NULL;
8842
8843 ASSERT(MUTEX_HELD(&mpt->m_mutex));
8844
8845 NDBG22(("mptsas_setup_bus_reset_delay"));
8846 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
8847 ptgt = refhash_next(mpt->m_targets, ptgt)) {
8848 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
8849 ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
8850 }
8851
8852 mptsas_start_watch_reset_delay();
8853 }
8854
8855 /*
8856 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
8857 * mpt instance for active reset delays
8858 */
8859 static void
8860 mptsas_watch_reset_delay(void *arg)
8861 {
8862 #ifndef __lock_lint
8863 _NOTE(ARGUNUSED(arg))
8864 #endif
8865
8866 mptsas_t *mpt;
8867 int not_done = 0;
8868
8869 NDBG22(("mptsas_watch_reset_delay"));
8881 mutex_exit(&mpt->m_mutex);
8882 }
8883 rw_exit(&mptsas_global_rwlock);
8884
8885 if (not_done) {
8886 mptsas_start_watch_reset_delay();
8887 }
8888 }
8889
8890 static int
8891 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
8892 {
8893 int done = 0;
8894 int restart = 0;
8895 mptsas_target_t *ptgt = NULL;
8896
8897 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
8898
8899 ASSERT(mutex_owned(&mpt->m_mutex));
8900
8901 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
8902 ptgt = refhash_next(mpt->m_targets, ptgt)) {
8903 if (ptgt->m_reset_delay != 0) {
8904 ptgt->m_reset_delay -=
8905 MPTSAS_WATCH_RESET_DELAY_TICK;
8906 if (ptgt->m_reset_delay <= 0) {
8907 ptgt->m_reset_delay = 0;
8908 mptsas_set_throttle(mpt, ptgt,
8909 MAX_THROTTLE);
8910 restart++;
8911 } else {
8912 done = -1;
8913 }
8914 }
8915 }
8916
8917 if (restart > 0) {
8918 mptsas_restart_hba(mpt);
8919 }
8920 return (done);
8921 }
8922
8923 #ifdef MPTSAS_TEST
8924 static void
8925 mptsas_test_reset(mptsas_t *mpt, int target)
8926 {
8927 mptsas_target_t *ptgt = NULL;
8928
8929 if (mptsas_rtest == target) {
8930 if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
8931 mptsas_rtest = -1;
8932 }
8933 if (mptsas_rtest == -1) {
8934 NDBG22(("mptsas_test_reset success"));
9198 */
9199 /*ARGSUSED*/
9200 static int
9201 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
9202 {
9203 NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
9204
9205 if (!cap)
9206 return (FALSE);
9207
9208 *cidxp = scsi_hba_lookup_capstr(cap);
9209 return (TRUE);
9210 }
9211
9212 static int
9213 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
9214 {
9215 mptsas_slots_t *old_active = mpt->m_active;
9216 mptsas_slots_t *new_active;
9217 size_t size;
9218
9219 /*
9220 * if there are active commands, then we cannot
9221 * change size of active slots array.
9222 */
9223 ASSERT(mpt->m_ncmds == 0);
9224
9225 size = MPTSAS_SLOTS_SIZE(mpt);
9226 new_active = kmem_zalloc(size, flag);
9227 if (new_active == NULL) {
9228 NDBG1(("new active alloc failed"));
9229 return (-1);
9230 }
9231 /*
9232 * Since SMID 0 is reserved and the TM slot is reserved, the
9233 * number of slots that can be used at any one time is
9234 * m_max_requests - 2.
9235 */
9236 new_active->m_n_normal = (mpt->m_max_requests - 2);
9237 new_active->m_size = size;
9238 new_active->m_rotor = 1;
9239 if (old_active)
9240 mptsas_free_active_slots(mpt);
9241 mpt->m_active = new_active;
9242
9243 return (0);
9244 }
9245
9246 static void
9247 mptsas_free_active_slots(mptsas_t *mpt)
9248 {
9249 mptsas_slots_t *active = mpt->m_active;
9250 size_t size;
9251
9252 if (active == NULL)
9253 return;
9254 size = active->m_size;
9255 kmem_free(active, size);
9256 mpt->m_active = NULL;
9257 }
9258
9259 /*
9260 * Error logging, printing, and debug print routines.
9261 */
9262 static char *mptsas_label = "mpt_sas";
9263
9368 (void) pm_idle_component(mpt->m_dip, 0);
9369 }
9370
9371 mutex_exit(&mpt->m_mutex);
9372 }
9373 rw_exit(&mptsas_global_rwlock);
9374
9375 mutex_enter(&mptsas_global_mutex);
9376 if (mptsas_timeouts_enabled)
9377 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
9378 mutex_exit(&mptsas_global_mutex);
9379 }
9380
9381 static void
9382 mptsas_watchsubr(mptsas_t *mpt)
9383 {
9384 int i;
9385 mptsas_cmd_t *cmd;
9386 mptsas_target_t *ptgt = NULL;
9387
9388 ASSERT(MUTEX_HELD(&mpt->m_mutex));
9389
9390 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
9391
9392 #ifdef MPTSAS_TEST
9393 if (mptsas_enable_untagged) {
9394 mptsas_test_untagged++;
9395 }
9396 #endif
9397
9398 /*
9399 * Check for commands stuck in active slot
9400 * Account for TM requests, which use the last SMID.
9401 */
9402 for (i = 0; i <= mpt->m_active->m_n_normal; i++) {
9403 if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9404 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9405 cmd->cmd_active_timeout -=
9406 mptsas_scsi_watchdog_tick;
9407 if (cmd->cmd_active_timeout <= 0) {
9408 /*
9409 * There seems to be a command stuck
9410 * in the active slot. Drain throttle.
9411 */
9412 mptsas_set_throttle(mpt,
9413 cmd->cmd_tgt_addr,
9414 DRAIN_THROTTLE);
9415 }
9416 }
9417 if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9418 (cmd->cmd_flags & CFLAG_CONFIG) ||
9419 (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9420 cmd->cmd_active_timeout -=
9421 mptsas_scsi_watchdog_tick;
9422 if (cmd->cmd_active_timeout <= 0) {
9423 /*
9424 * passthrough command timeout
9425 */
9426 cmd->cmd_flags |= (CFLAG_FINISHED |
9427 CFLAG_TIMEOUT);
9428 cv_broadcast(&mpt->m_passthru_cv);
9429 cv_broadcast(&mpt->m_config_cv);
9430 cv_broadcast(&mpt->m_fw_diag_cv);
9431 }
9432 }
9433 }
9434 }
9435
9436 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9437 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9438 /*
9439 * If we were draining due to a qfull condition,
9440 * go back to full throttle.
9441 */
9442 if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
9443 (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9444 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9445 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9446 mptsas_restart_hba(mpt);
9447 }
9448
9449 if ((ptgt->m_t_ncmds > 0) &&
9450 (ptgt->m_timebase)) {
9451
9452 if (ptgt->m_timebase <=
9453 mptsas_scsi_watchdog_tick) {
9454 ptgt->m_timebase +=
9455 mptsas_scsi_watchdog_tick;
9456 continue;
9457 }
9458
9459 ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9460
9461 if (ptgt->m_timeout < 0) {
9462 mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
9463 continue;
9464 }
9465
9466 if ((ptgt->m_timeout) <=
9467 mptsas_scsi_watchdog_tick) {
9468 NDBG23(("pending timeout"));
9469 mptsas_set_throttle(mpt, ptgt,
9470 DRAIN_THROTTLE);
9471 }
9472 }
9473 }
9474 }
9475
9476 /*
9477 * timeout recovery
9478 */
9479 static void
9480 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9481 {
9482
9483 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9484 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9485 "Target %d", devhdl);
9486
9487 /*
9488 * If the current target is not the target passed in,
9489 * try to reset that target.
9490 */
9491 NDBG29(("mptsas_cmd_timeout: device reset"));
9492 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9516 {
9517 mptsas_t *mpt;
9518 scsi_hba_tran_t *tran;
9519
9520 tran = ddi_get_driver_private(dip);
9521 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9522 return (-1);
9523
9524 return (mptsas_unquiesce_bus(mpt));
9525 }
9526
9527 static int
9528 mptsas_quiesce_bus(mptsas_t *mpt)
9529 {
9530 mptsas_target_t *ptgt = NULL;
9531
9532 NDBG28(("mptsas_quiesce_bus"));
9533 mutex_enter(&mpt->m_mutex);
9534
9535 /* Set all the throttles to zero */
9536 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9537 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9538 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9539 }
9540
9541 /* If there are any outstanding commands in the queue */
9542 if (mpt->m_ncmds) {
9543 mpt->m_softstate |= MPTSAS_SS_DRAINING;
9544 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9545 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9546 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9547 /*
9548 * Quiesce has been interrupted
9549 */
9550 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9551 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9552 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9553 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9554 }
9555 mptsas_restart_hba(mpt);
9556 if (mpt->m_quiesce_timeid != 0) {
9557 timeout_id_t tid = mpt->m_quiesce_timeid;
9558 mpt->m_quiesce_timeid = 0;
9559 mutex_exit(&mpt->m_mutex);
9560 (void) untimeout(tid);
9561 return (-1);
9562 }
9563 mutex_exit(&mpt->m_mutex);
9564 return (-1);
9565 } else {
9566 /* Bus has been quiesced */
9567 ASSERT(mpt->m_quiesce_timeid == 0);
9568 mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9569 mpt->m_softstate |= MPTSAS_SS_QUIESCED;
9570 mutex_exit(&mpt->m_mutex);
9571 return (0);
9572 }
9573 }
9574 /* Bus was not busy - QUIESCED */
9575 mutex_exit(&mpt->m_mutex);
9576
9577 return (0);
9578 }
9579
9580 static int
9581 mptsas_unquiesce_bus(mptsas_t *mpt)
9582 {
9583 mptsas_target_t *ptgt = NULL;
9584
9585 NDBG28(("mptsas_unquiesce_bus"));
9586 mutex_enter(&mpt->m_mutex);
9587 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
9588 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9589 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9590 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9591 }
9592 mptsas_restart_hba(mpt);
9593 mutex_exit(&mpt->m_mutex);
9594 return (0);
9595 }
9596
9597 static void
9598 mptsas_ncmds_checkdrain(void *arg)
9599 {
9600 mptsas_t *mpt = arg;
9601 mptsas_target_t *ptgt = NULL;
9602
9603 mutex_enter(&mpt->m_mutex);
9604 if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
9605 mpt->m_quiesce_timeid = 0;
9606 if (mpt->m_ncmds == 0) {
9607 /* Command queue has been drained */
9608 cv_signal(&mpt->m_cv);
9609 } else {
9610 /*
9611 * The throttle may have been reset because
9612 * of a SCSI bus reset
9613 */
9614 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
9615 ptgt = refhash_next(mpt->m_targets, ptgt)) {
9616 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9617 }
9618
9619 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9620 mpt, (MPTSAS_QUIESCE_TIMEOUT *
9621 drv_usectohz(1000000)));
9622 }
9623 }
9624 mutex_exit(&mpt->m_mutex);
9625 }
9626
9627 /*ARGSUSED*/
9628 static void
9629 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
9630 {
9631 int i;
9632 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9633 char buf[128];
9634
9635 buf[0] = '\0';
9636 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd,
11328
11329 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) {
11330 return (EFAULT);
11331 }
11332
11333 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET &&
11334 lc.Command != MPTSAS_LEDCTL_FLAG_GET) ||
11335 lc.Led < MPTSAS_LEDCTL_LED_MIN ||
11336 lc.Led > MPTSAS_LEDCTL_LED_MAX ||
11337 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 &&
11338 lc.LedStatus != 1)) {
11339 return (EINVAL);
11340 }
11341
11342 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) ||
11343 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0))
11344 return (EACCES);
11345
11346 /* Locate the target we're interrogating... */
11347 mutex_enter(&mpt->m_mutex);
11348 ptgt = refhash_linear_search(mpt->m_targets,
11349 mptsas_target_eval_slot, &lc);
11350 if (ptgt == NULL) {
11351 /* We could not find a target for that enclosure/slot. */
11352 mutex_exit(&mpt->m_mutex);
11353 return (ENOENT);
11354 }
11355
11356 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) {
11357 /* Update our internal LED state. */
11358 ptgt->m_led_status &= ~(1 << (lc.Led - 1));
11359 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1);
11360
11361 /* Flush it to the controller. */
11362 ret = mptsas_flush_led_status(mpt, ptgt);
11363 mutex_exit(&mpt->m_mutex);
11364 return (ret);
11365 }
11366
11367 /* Return our internal LED state. */
11368 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1;
11369 mutex_exit(&mpt->m_mutex);
11380 {
11381 uint16_t i = 0;
11382 uint16_t count = 0;
11383 int ret = 0;
11384 mptsas_target_t *ptgt;
11385 mptsas_disk_info_t *di;
11386 STRUCT_DECL(mptsas_get_disk_info, gdi);
11387
11388 if ((mode & FREAD) == 0)
11389 return (EACCES);
11390
11391 STRUCT_INIT(gdi, get_udatamodel());
11392
11393 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi),
11394 mode) != 0) {
11395 return (EFAULT);
11396 }
11397
11398 /* Find out how many targets there are. */
11399 mutex_enter(&mpt->m_mutex);
11400 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
11401 ptgt = refhash_next(mpt->m_targets, ptgt)) {
11402 count++;
11403 }
11404 mutex_exit(&mpt->m_mutex);
11405
11406 /*
11407 * If we haven't been asked to copy out information on each target,
11408 * then just return the count.
11409 */
11410 STRUCT_FSET(gdi, DiskCount, count);
11411 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL)
11412 goto copy_out;
11413
11414 /*
11415 * If we haven't been given a large enough buffer to copy out into,
11416 * let the caller know.
11417 */
11418 if (STRUCT_FGET(gdi, DiskInfoArraySize) <
11419 count * sizeof (mptsas_disk_info_t)) {
11420 ret = ENOSPC;
11421 goto copy_out;
11422 }
11423
11424 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP);
11425
11426 mutex_enter(&mpt->m_mutex);
11427 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
11428 ptgt = refhash_next(mpt->m_targets, ptgt)) {
11429 if (i >= count) {
11430 /*
11431 * The number of targets changed while we weren't
11432 * looking, so give up.
11433 */
11434 refhash_rele(mpt->m_targets, ptgt);
11435 mutex_exit(&mpt->m_mutex);
11436 kmem_free(di, count * sizeof (mptsas_disk_info_t));
11437 return (EAGAIN);
11438 }
11439 di[i].Instance = mpt->m_instance;
11440 di[i].Enclosure = ptgt->m_enclosure;
11441 di[i].Slot = ptgt->m_slot_num;
11442 di[i].SasAddress = ptgt->m_addr.mta_wwn;
11443 i++;
11444 }
11445 mutex_exit(&mpt->m_mutex);
11446 STRUCT_FSET(gdi, DiskCount, i);
11447
11448 /* Copy out the disk information to the caller. */
11449 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray),
11450 i * sizeof (mptsas_disk_info_t), mode) != 0) {
11451 ret = EFAULT;
11452 }
11453
11454 kmem_free(di, count * sizeof (mptsas_disk_info_t));
11455
11456 copy_out:
11457 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi),
11458 mode) != 0) {
11459 ret = EFAULT;
11460 }
11461
11462 return (ret);
11728 int
11729 mptsas_restart_ioc(mptsas_t *mpt)
11730 {
11731 int rval = DDI_SUCCESS;
11732 mptsas_target_t *ptgt = NULL;
11733
11734 ASSERT(mutex_owned(&mpt->m_mutex));
11735
11736 /*
11737 * Set a flag telling I/O path that we're processing a reset. This is
11738 * needed because after the reset is complete, the hash table still
11739 * needs to be rebuilt. If I/Os are started before the hash table is
11740 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked
11741 * so that they can be retried.
11742 */
11743 mpt->m_in_reset = TRUE;
11744
11745 /*
11746 * Set all throttles to HOLD
11747 */
11748 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
11749 ptgt = refhash_next(mpt->m_targets, ptgt)) {
11750 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
11751 }
11752
11753 /*
11754 * Disable interrupts
11755 */
11756 MPTSAS_DISABLE_INTR(mpt);
11757
11758 /*
11759 * Abort all commands: outstanding commands, commands in waitq and
11760 * tx_waitq.
11761 */
11762 mptsas_flush_hba(mpt);
11763
11764 /*
11765 * Reinitialize the chip.
11766 */
11767 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
11768 rval = DDI_FAILURE;
11769 }
11770
11771 /*
11772 * Enable interrupts again
11773 */
11774 MPTSAS_ENABLE_INTR(mpt);
11775
11776 /*
11777 * If mptsas_init_chip was successful, update the driver data.
11778 */
11779 if (rval == DDI_SUCCESS) {
11780 mptsas_update_driver_data(mpt);
11781 }
11782
11783 /*
11784 * Reset the throttles
11785 */
11786 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
11787 ptgt = refhash_next(mpt->m_targets, ptgt)) {
11788 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
11789 }
11790
11791 mptsas_doneq_empty(mpt);
11792 mptsas_restart_hba(mpt);
11793
11794 if (rval != DDI_SUCCESS) {
11795 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
11796 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
11797 }
11798
11799 /*
11800 * Clear the reset flag so that I/Os can continue.
11801 */
11802 mpt->m_in_reset = FALSE;
11803
11804 return (rval);
11805 }
11806
11807 static int
11808 mptsas_init_chip(mptsas_t *mpt, int first_time)
11834 }
11835 /*
11836 * Setup configuration space
11837 */
11838 if (mptsas_config_space_init(mpt) == FALSE) {
11839 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
11840 "failed!");
11841 goto fail;
11842 }
11843
11844 /*
11845 * IOC facts can change after a diag reset so all buffers that are
11846 * based on these numbers must be de-allocated and re-allocated. Get
11847 * new IOC facts each time chip is initialized.
11848 */
11849 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
11850 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
11851 goto fail;
11852 }
11853
11854 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT,
11855 mptsas_target_addr_hash, mptsas_target_addr_cmp,
11856 mptsas_target_free, sizeof (mptsas_target_t),
11857 offsetof(mptsas_target_t, m_link),
11858 offsetof(mptsas_target_t, m_addr), KM_SLEEP);
11859
11860 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
11861 goto fail;
11862 }
11863 /*
11864 * Allocate request message frames, reply free queue, reply descriptor
11865 * post queue, and reply message frames using latest IOC facts.
11866 */
11867 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
11868 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
11869 goto fail;
11870 }
11871 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
11872 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
11873 goto fail;
11874 }
11875 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
11876 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
11877 goto fail;
11878 }
11879 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
12478 uint64_t ena;
12479 char buf[FM_MAX_CLASS];
12480
12481 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
12482 ena = fm_ena_generate(0, FM_ENA_FMT1);
12483 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
12484 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
12485 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
12486 }
12487 }
12488
12489 static int
12490 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
12491 uint16_t *dev_handle, mptsas_target_t **pptgt)
12492 {
12493 int rval;
12494 uint32_t dev_info;
12495 uint64_t sas_wwn;
12496 mptsas_phymask_t phymask;
12497 uint8_t physport, phynum, config, disk;
12498 uint64_t devicename;
12499 uint16_t pdev_hdl;
12500 mptsas_target_t *tmp_tgt = NULL;
12501 uint16_t bay_num, enclosure;
12502
12503 ASSERT(*pptgt == NULL);
12504
12505 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
12506 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl,
12507 &bay_num, &enclosure);
12508 if (rval != DDI_SUCCESS) {
12509 rval = DEV_INFO_FAIL_PAGE0;
12510 return (rval);
12511 }
12512
12513 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
12514 MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12515 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
12516 rval = DEV_INFO_WRONG_DEVICE_TYPE;
12517 return (rval);
12518 }
12519
12520 /*
12521 * Check if the dev handle is for a Phys Disk. If so, set return value
12522 * and exit. Don't add Phys Disks to hash.
12523 */
12524 for (config = 0; config < mpt->m_num_raid_configs; config++) {
12525 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
12526 if (*dev_handle == mpt->m_raidconfig[config].
12527 m_physdisk_devhdl[disk]) {
12528 rval = DEV_INFO_PHYS_DISK;
12529 return (rval);
12530 }
12531 }
12532 }
12533
12534 /*
12535 * Get SATA Device Name from SAS device page0 for
12536 * sata device, if device name doesn't exist, set mta_wwn to
12537 * 0 for direct attached SATA. For the device behind the expander
12538 * we still can use STP address assigned by expander.
12539 */
12540 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12541 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12542 mutex_exit(&mpt->m_mutex);
12543 /* alloc a tmp_tgt to send the cmd */
12544 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
12545 KM_SLEEP);
12546 tmp_tgt->m_devhdl = *dev_handle;
12547 tmp_tgt->m_deviceinfo = dev_info;
12548 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
12549 tmp_tgt->m_qfull_retry_interval =
12550 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
12551 tmp_tgt->m_t_throttle = MAX_THROTTLE;
12552 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
12553 kmem_free(tmp_tgt, sizeof (struct mptsas_target));
12554 mutex_enter(&mpt->m_mutex);
12555 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
12556 sas_wwn = devicename;
12557 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
12558 sas_wwn = 0;
12559 }
12560 }
12561
12562 phymask = mptsas_physport_to_phymask(mpt, physport);
12563 *pptgt = mptsas_tgt_alloc(mpt, *dev_handle, sas_wwn,
12564 dev_info, phymask, phynum);
12565 if (*pptgt == NULL) {
12566 mptsas_log(mpt, CE_WARN, "Failed to allocated target"
12567 "structure!");
12568 rval = DEV_INFO_FAIL_ALLOC;
12569 return (rval);
12570 }
12571 (*pptgt)->m_enclosure = enclosure;
12572 (*pptgt)->m_slot_num = bay_num;
12573 return (DEV_INFO_SUCCESS);
12574 }
12575
12576 uint64_t
12577 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
12578 {
12579 uint64_t sata_guid = 0, *pwwn = NULL;
12580 int target = ptgt->m_devhdl;
12581 uchar_t *inq83 = NULL;
12582 int inq83_len = 0xFF;
12583 uchar_t *dblk = NULL;
12973 * didn't match any device by searching
12974 */
12975 return (DDI_FAILURE);
12976 }
12977 /*
12978 * If the LUN already exists and the status is online,
12979 * we just return the pointer to dev_info_t directly.
12980 * For the mdi_pathinfo node, we'll handle it in
12981 * mptsas_create_virt_lun()
12982 * TODO should be also in mptsas_handle_dr
12983 */
12984
12985 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
12986 if (*lundip != NULL) {
12987 /*
12988 * TODO Another senario is, we hotplug the same disk
12989 * on the same slot, the devhdl changed, is this
12990 * possible?
12991 * tgt_private->t_private != ptgt
12992 */
12993 if (sasaddr != ptgt->m_addr.mta_wwn) {
12994 /*
12995 * The device has changed although the devhdl is the
12996 * same (Enclosure mapping mode, change drive on the
12997 * same slot)
12998 */
12999 return (DDI_FAILURE);
13000 }
13001 return (DDI_SUCCESS);
13002 }
13003
13004 if (phymask == 0) {
13005 /*
13006 * Configure IR volume
13007 */
13008 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
13009 return (rval);
13010 }
13011 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
13012
13013 return (rval);
13014 }
13015
13016 static int
13017 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
13018 dev_info_t **lundip)
13019 {
13020 int rval;
13021 mptsas_t *mpt = DIP2MPT(pdip);
13022 mptsas_phymask_t phymask;
13023 mptsas_target_t *ptgt = NULL;
13024
13025 /*
13026 * Get the physical port associated to the iport
13027 */
13028 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13029 "phymask", 0);
13030
13031 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy);
13032 if (ptgt == NULL) {
13033 /*
13034 * didn't match any device by searching
13035 */
13036 return (DDI_FAILURE);
13037 }
13038
13039 /*
13040 * If the LUN already exists and the status is online,
13041 * we just return the pointer to dev_info_t directly.
13042 * For the mdi_pathinfo node, we'll handle it in
13043 * mptsas_create_virt_lun().
13044 */
13045
13046 *lundip = mptsas_find_child_phy(pdip, phy);
13047 if (*lundip != NULL) {
13048 return (DDI_SUCCESS);
13095 struct buf *repluns_bp = NULL;
13096 struct scsi_address ap;
13097 uchar_t cdb[CDB_GROUP5];
13098 int ret = DDI_FAILURE;
13099 int retry = 0;
13100 int lun_list_len = 0;
13101 uint16_t lun_num = 0;
13102 uint8_t lun_addr_type = 0;
13103 uint32_t lun_cnt = 0;
13104 uint32_t lun_total = 0;
13105 dev_info_t *cdip = NULL;
13106 uint16_t *saved_repluns = NULL;
13107 char *buffer = NULL;
13108 int buf_len = 128;
13109 mptsas_t *mpt = DIP2MPT(pdip);
13110 uint64_t sas_wwn = 0;
13111 uint8_t phy = 0xFF;
13112 uint32_t dev_info = 0;
13113
13114 mutex_enter(&mpt->m_mutex);
13115 sas_wwn = ptgt->m_addr.mta_wwn;
13116 phy = ptgt->m_phynum;
13117 dev_info = ptgt->m_deviceinfo;
13118 mutex_exit(&mpt->m_mutex);
13119
13120 if (sas_wwn == 0) {
13121 /*
13122 * It's a SATA without Device Name
13123 * So don't try multi-LUNs
13124 */
13125 if (mptsas_find_child_phy(pdip, phy)) {
13126 return (DDI_SUCCESS);
13127 } else {
13128 /*
13129 * need configure and create node
13130 */
13131 return (DDI_FAILURE);
13132 }
13133 }
13134
13135 /*
13210 if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
13211 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
13212 MPTSAS_DEV_GONE);
13213 }
13214 }
13215 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
13216 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
13217 scsi_free_consistent_buf(repluns_bp);
13218 return (DDI_SUCCESS);
13219 }
13220
13221 static int
13222 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
13223 {
13224 int rval = DDI_FAILURE;
13225 struct scsi_inquiry *sd_inq = NULL;
13226 mptsas_t *mpt = DIP2MPT(pdip);
13227 mptsas_target_t *ptgt = NULL;
13228
13229 mutex_enter(&mpt->m_mutex);
13230 ptgt = refhash_linear_search(mpt->m_targets,
13231 mptsas_target_eval_devhdl, &target);
13232 mutex_exit(&mpt->m_mutex);
13233 if (ptgt == NULL) {
13234 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
13235 "not found.", target);
13236 return (rval);
13237 }
13238
13239 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
13240 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
13241 SUN_INQSIZE, 0, (uchar_t)0);
13242
13243 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
13244 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
13245 0);
13246 } else {
13247 rval = DDI_FAILURE;
13248 }
13249
13250 kmem_free(sd_inq, SUN_INQSIZE);
13251 return (rval);
13252 }
13253
13254 /*
13255 * configure all RAID volumes for virtual iport
13256 */
13257 static void
13258 mptsas_config_all_viport(dev_info_t *pdip)
13259 {
13260 mptsas_t *mpt = DIP2MPT(pdip);
13261 int config, vol;
13262 int target;
13263 dev_info_t *lundip = NULL;
13264
13265 /*
13266 * Get latest RAID info and search for any Volume DevHandles. If any
13267 * are found, configure the volume.
13268 */
13269 mutex_enter(&mpt->m_mutex);
13270 for (config = 0; config < mpt->m_num_raid_configs; config++) {
13271 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
13272 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid
13273 == 1) {
13274 target = mpt->m_raidconfig[config].
13275 m_raidvol[vol].m_raidhandle;
13276 mutex_exit(&mpt->m_mutex);
13277 (void) mptsas_config_raid(pdip, target,
13278 &lundip);
13279 mutex_enter(&mpt->m_mutex);
13280 }
13281 }
13282 }
13283 mutex_exit(&mpt->m_mutex);
13284 }
13285
13286 static void
13287 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
13288 int lun_cnt, mptsas_target_t *ptgt)
13289 {
13290 dev_info_t *child = NULL, *savechild = NULL;
13291 mdi_pathinfo_t *pip = NULL, *savepip = NULL;
13292 uint64_t sas_wwn, wwid;
13293 uint8_t phy;
13294 int lun;
13295 int i;
13296 int find;
13297 char *addr;
13298 char *nodename;
13299 mptsas_t *mpt = DIP2MPT(pdip);
13300
13301 mutex_enter(&mpt->m_mutex);
13302 wwid = ptgt->m_addr.mta_wwn;
13303 mutex_exit(&mpt->m_mutex);
13304
13305 child = ddi_get_child(pdip);
13306 while (child) {
13307 find = 0;
13308 savechild = child;
13309 child = ddi_get_next_sibling(child);
13310
13311 nodename = ddi_node_name(savechild);
13312 if (strcmp(nodename, "smp") == 0) {
13313 continue;
13314 }
13315
13316 addr = ddi_get_name_addr(savechild);
13317 if (addr == NULL) {
13318 continue;
13319 }
13320
13321 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
13322 DDI_SUCCESS) {
13386 uint32_t page_address;
13387 int rval = 0;
13388 uint16_t dev_handle;
13389 mptsas_target_t *ptgt = NULL;
13390 mptsas_smp_t smp_node;
13391
13392 /*
13393 * Get latest RAID info.
13394 */
13395 (void) mptsas_get_raid_info(mpt);
13396
13397 dev_handle = mpt->m_smp_devhdl;
13398 for (; mpt->m_done_traverse_smp == 0; ) {
13399 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
13400 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
13401 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
13402 != DDI_SUCCESS) {
13403 break;
13404 }
13405 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
13406 (void) mptsas_smp_alloc(mpt, &smp_node);
13407 }
13408
13409 /*
13410 * Config target devices
13411 */
13412 dev_handle = mpt->m_dev_handle;
13413
13414 /*
13415 * Do loop to get sas device page 0 by GetNextHandle till the
13416 * the last handle. If the sas device is a SATA/SSP target,
13417 * we try to config it.
13418 */
13419 for (; mpt->m_done_traverse_dev == 0; ) {
13420 ptgt = NULL;
13421 page_address =
13422 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
13423 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
13424 (uint32_t)dev_handle;
13425 rval = mptsas_get_target_device_info(mpt, page_address,
13426 &dev_handle, &ptgt);
13427 if ((rval == DEV_INFO_FAIL_PAGE0) ||
13428 (rval == DEV_INFO_FAIL_ALLOC)) {
13429 break;
13430 }
13431
13432 mpt->m_dev_handle = dev_handle;
13433 }
13434
13435 }
13436
13437 void
13438 mptsas_update_driver_data(struct mptsas *mpt)
13439 {
13440 mptsas_target_t *tp;
13441 mptsas_smp_t *sp;
13442
13443 ASSERT(MUTEX_HELD(&mpt->m_mutex));
13444
13445 /*
13446 * TODO after hard reset, update the driver data structures
13447 * 1. update port/phymask mapping table mpt->m_phy_info
13448 * 2. invalid all the entries in hash table
13449 * m_devhdl = 0xffff and m_deviceinfo = 0
13450 * 3. call sas_device_page/expander_page to update hash table
13451 */
13452 mptsas_update_phymask(mpt);
13453 /*
13454 * Invalid the existing entries
13455 *
13456 * XXX - It seems like we should just delete everything here. We are
13457 * holding the lock and are about to refresh all the targets in both
13458 * hashes anyway. Given the path we're in, what outstanding async
13459 * event could possibly be trying to reference one of these things
13460 * without taking the lock, and how would that be useful anyway?
13461 */
13462 for (tp = refhash_first(mpt->m_targets); tp != NULL;
13463 tp = refhash_next(mpt->m_targets, tp)) {
13464 tp->m_devhdl = MPTSAS_INVALID_DEVHDL;
13465 tp->m_deviceinfo = 0;
13466 tp->m_dr_flag = MPTSAS_DR_INACTIVE;
13467 }
13468 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL;
13469 sp = refhash_next(mpt->m_smp_targets, sp)) {
13470 sp->m_devhdl = MPTSAS_INVALID_DEVHDL;
13471 sp->m_deviceinfo = 0;
13472 }
13473 mpt->m_done_traverse_dev = 0;
13474 mpt->m_done_traverse_smp = 0;
13475 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
13476 mptsas_update_hashtab(mpt);
13477 }
13478
13479 static void
13480 mptsas_config_all(dev_info_t *pdip)
13481 {
13482 dev_info_t *smpdip = NULL;
13483 mptsas_t *mpt = DIP2MPT(pdip);
13484 int phymask = 0;
13485 mptsas_phymask_t phy_mask;
13486 mptsas_target_t *ptgt = NULL;
13487 mptsas_smp_t *psmp;
13488
13489 /*
13490 * Get the phymask associated to the iport
13491 */
13492 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13493 "phymask", 0);
13494
13495 /*
13496 * Enumerate RAID volumes here (phymask == 0).
13497 */
13498 if (phymask == 0) {
13499 mptsas_config_all_viport(pdip);
13500 return;
13501 }
13502
13503 mutex_enter(&mpt->m_mutex);
13504
13505 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
13506 mptsas_update_hashtab(mpt);
13507 }
13508
13509 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL;
13510 psmp = refhash_next(mpt->m_smp_targets, psmp)) {
13511 phy_mask = psmp->m_addr.mta_phymask;
13512 if (phy_mask == phymask) {
13513 smpdip = NULL;
13514 mutex_exit(&mpt->m_mutex);
13515 (void) mptsas_online_smp(pdip, psmp, &smpdip);
13516 mutex_enter(&mpt->m_mutex);
13517 }
13518 }
13519
13520 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL;
13521 ptgt = refhash_next(mpt->m_targets, ptgt)) {
13522 phy_mask = ptgt->m_addr.mta_phymask;
13523 if (phy_mask == phymask) {
13524 mutex_exit(&mpt->m_mutex);
13525 (void) mptsas_config_target(pdip, ptgt);
13526 mutex_enter(&mpt->m_mutex);
13527 }
13528 }
13529 mutex_exit(&mpt->m_mutex);
13530 }
13531
13532 static int
13533 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
13534 {
13535 int rval = DDI_FAILURE;
13536 dev_info_t *tdip;
13537
13538 rval = mptsas_config_luns(pdip, ptgt);
13539 if (rval != DDI_SUCCESS) {
13540 /*
13541 * The return value means the SCMD_REPORT_LUNS
13542 * did not execute successfully. The target maybe
13543 * doesn't support such command.
13544 */
13545 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
13546 }
13547 return (rval);
13689 }
13690
13691 if (strcmp(smp_wwn, str_wwn) == 0) {
13692 ddi_prop_free(smp_wwn);
13693 break;
13694 }
13695 child = ddi_get_next_sibling(child);
13696 ddi_prop_free(smp_wwn);
13697 }
13698 return (child);
13699 }
13700
13701 static int
13702 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
13703 {
13704 int rval = DDI_FAILURE;
13705 char *devname;
13706 char wwn_str[MPTSAS_WWN_STRLEN];
13707 dev_info_t *cdip;
13708
13709 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
13710
13711 cdip = mptsas_find_smp_child(pdip, wwn_str);
13712
13713 if (cdip == NULL)
13714 return (DDI_SUCCESS);
13715
13716 /*
13717 * Make sure node is attached otherwise
13718 * it won't have related cache nodes to
13719 * clean up. i_ddi_devi_attached is
13720 * similiar to i_ddi_node_state(cdip) >=
13721 * DS_ATTACHED.
13722 */
13723 if (i_ddi_devi_attached(cdip)) {
13724
13725 /* Get full devname */
13726 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
13727 (void) ddi_deviname(cdip, devname);
13728 /* Clean cache */
13729 (void) devfs_clean(pdip, devname + 1,
13969 char *attached_wwn_str = NULL;
13970 char *component = NULL;
13971 uint8_t phy = 0xFF;
13972 uint64_t sas_wwn;
13973 int64_t lun64 = 0;
13974 uint32_t devinfo;
13975 uint16_t dev_hdl;
13976 uint16_t pdev_hdl;
13977 uint64_t dev_sas_wwn;
13978 uint64_t pdev_sas_wwn;
13979 uint32_t pdev_info;
13980 uint8_t physport;
13981 uint8_t phy_id;
13982 uint32_t page_address;
13983 uint16_t bay_num, enclosure;
13984 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
13985 uint32_t dev_info;
13986
13987 mutex_enter(&mpt->m_mutex);
13988 target = ptgt->m_devhdl;
13989 sas_wwn = ptgt->m_addr.mta_wwn;
13990 devinfo = ptgt->m_deviceinfo;
13991 phy = ptgt->m_phynum;
13992 mutex_exit(&mpt->m_mutex);
13993
13994 if (sas_wwn) {
13995 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13996 } else {
13997 *pip = mptsas_find_path_phy(pdip, phy);
13998 }
13999
14000 if (*pip != NULL) {
14001 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
14002 ASSERT(*lun_dip != NULL);
14003 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
14004 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
14005 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
14006 if (strncmp(guid, old_guid, strlen(guid)) == 0) {
14007 /*
14008 * Same path back online again.
14009 */
14318 char *component = NULL;
14319 char *attached_wwn_str = NULL;
14320 uint8_t phy = 0xFF;
14321 uint64_t sas_wwn;
14322 uint32_t devinfo;
14323 uint16_t dev_hdl;
14324 uint16_t pdev_hdl;
14325 uint64_t pdev_sas_wwn;
14326 uint64_t dev_sas_wwn;
14327 uint32_t pdev_info;
14328 uint8_t physport;
14329 uint8_t phy_id;
14330 uint32_t page_address;
14331 uint16_t bay_num, enclosure;
14332 char pdev_wwn_str[MPTSAS_WWN_STRLEN];
14333 uint32_t dev_info;
14334 int64_t lun64 = 0;
14335
14336 mutex_enter(&mpt->m_mutex);
14337 target = ptgt->m_devhdl;
14338 sas_wwn = ptgt->m_addr.mta_wwn;
14339 devinfo = ptgt->m_deviceinfo;
14340 phy = ptgt->m_phynum;
14341 mutex_exit(&mpt->m_mutex);
14342
14343 /*
14344 * generate compatible property with binding-set "mpt"
14345 */
14346 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
14347 &nodename, &compatible, &ncompatible);
14348
14349 /*
14350 * if nodename can't be determined then print a message and skip it
14351 */
14352 if (nodename == NULL) {
14353 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
14354 "for target %d lun %d", target, lun);
14355 return (DDI_FAILURE);
14356 }
14357
14358 ndi_rtn = ndi_devi_alloc(pdip, nodename,
14437 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
14438 mptsas_log(mpt, CE_WARN, "mptsas unable to"
14439 "create property for SAS target %d lun %d"
14440 " (SAS_PROP)", target, lun);
14441 ndi_rtn = NDI_FAILURE;
14442 goto phys_create_done;
14443 }
14444 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
14445 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
14446 mptsas_log(mpt, CE_WARN, "mptsas unable "
14447 "to create guid property for target %d "
14448 "lun %d", target, lun);
14449 ndi_rtn = NDI_FAILURE;
14450 goto phys_create_done;
14451 }
14452
14453 /*
14454 * The following code is to set properties for SM-HBA support,
14455 * it doesn't apply to RAID volumes
14456 */
14457 if (ptgt->m_addr.mta_phymask == 0)
14458 goto phys_raid_lun;
14459
14460 mutex_enter(&mpt->m_mutex);
14461
14462 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
14463 MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
14464 (uint32_t)ptgt->m_devhdl;
14465 rval = mptsas_get_sas_device_page0(mpt, page_address,
14466 &dev_hdl, &dev_sas_wwn, &dev_info,
14467 &physport, &phy_id, &pdev_hdl,
14468 &bay_num, &enclosure);
14469 if (rval != DDI_SUCCESS) {
14470 mutex_exit(&mpt->m_mutex);
14471 mptsas_log(mpt, CE_WARN, "mptsas unable to get"
14472 "parent device for handle %d.", page_address);
14473 ndi_rtn = NDI_FAILURE;
14474 goto phys_create_done;
14475 }
14476
14477 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
14591 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
14592 if (guid) {
14593 (void) snprintf(component, MAXPATHLEN,
14594 "disk@w%s,%x", wwn_str, lun);
14595 } else {
14596 (void) snprintf(component, MAXPATHLEN,
14597 "disk@p%x,%x", phy, lun);
14598 }
14599 if (ddi_pathname_obp_set(*lun_dip, component)
14600 != DDI_SUCCESS) {
14601 mptsas_log(mpt, CE_WARN, "mpt_sas driver "
14602 "unable to set obp-path for SAS "
14603 "object %s", component);
14604 ndi_rtn = NDI_FAILURE;
14605 goto phys_create_done;
14606 }
14607 }
14608 /*
14609 * Create the phy-num property for non-raid disk
14610 */
14611 if (ptgt->m_addr.mta_phymask != 0) {
14612 if (ndi_prop_update_int(DDI_DEV_T_NONE,
14613 *lun_dip, "phy-num", ptgt->m_phynum) !=
14614 DDI_PROP_SUCCESS) {
14615 mptsas_log(mpt, CE_WARN, "mptsas driver "
14616 "failed to create phy-num property for "
14617 "target %d", target);
14618 ndi_rtn = NDI_FAILURE;
14619 goto phys_create_done;
14620 }
14621 }
14622 phys_create_done:
14623 /*
14624 * If props were setup ok, online the lun
14625 */
14626 if (ndi_rtn == NDI_SUCCESS) {
14627 /*
14628 * Try to online the new node
14629 */
14630 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
14631 }
14713 char attached_wwn_str[MPTSAS_WWN_STRLEN];
14714 int ndi_rtn = NDI_FAILURE;
14715 int rval = 0;
14716 mptsas_smp_t dev_info;
14717 uint32_t page_address;
14718 mptsas_t *mpt = DIP2MPT(pdip);
14719 uint16_t dev_hdl;
14720 uint64_t sas_wwn;
14721 uint64_t smp_sas_wwn;
14722 uint8_t physport;
14723 uint8_t phy_id;
14724 uint16_t pdev_hdl;
14725 uint8_t numphys = 0;
14726 uint16_t i = 0;
14727 char phymask[MPTSAS_MAX_PHYS];
14728 char *iport = NULL;
14729 mptsas_phymask_t phy_mask = 0;
14730 uint16_t attached_devhdl;
14731 uint16_t bay_num, enclosure;
14732
14733 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn);
14734
14735 /*
14736 * Probe smp device, prevent the node of removed device from being
14737 * configured succesfully
14738 */
14739 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) {
14740 return (DDI_FAILURE);
14741 }
14742
14743 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
14744 return (DDI_SUCCESS);
14745 }
14746
14747 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
14748
14749 /*
14750 * if lun alloc success, set props
14751 */
14752 if (ndi_rtn == NDI_SUCCESS) {
14753 /*
14754 * Set the flavor of the child to be SMP flavored
14755 */
14756 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
14757
14758 if (ndi_prop_update_string(DDI_DEV_T_NONE,
14759 *smp_dip, SMP_WWN, wwn_str) !=
14760 DDI_PROP_SUCCESS) {
14761 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
14762 "property for smp device %s (sas_wwn)",
14763 wwn_str);
14764 ndi_rtn = NDI_FAILURE;
14765 goto smp_create_done;
14766 }
14767 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn);
14768 if (ndi_prop_update_string(DDI_DEV_T_NONE,
14769 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) !=
14770 DDI_PROP_SUCCESS) {
14771 mptsas_log(mpt, CE_WARN, "mptsas unable to create "
14772 "property for iport target-port %s (sas_wwn)",
14773 wwn_str);
14774 ndi_rtn = NDI_FAILURE;
14775 goto smp_create_done;
14776 }
14777
14778 mutex_enter(&mpt->m_mutex);
14779
14780 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
14781 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl;
14782 rval = mptsas_get_sas_expander_page0(mpt, page_address,
14783 &dev_info);
14784 if (rval != DDI_SUCCESS) {
14785 mutex_exit(&mpt->m_mutex);
14786 mptsas_log(mpt, CE_WARN,
14787 "mptsas unable to get expander "
15031 smp_pkt->smp_pkt_reason = EIO;
15032 break;
15033 }
15034 return (DDI_FAILURE);
15035 }
15036 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
15037 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
15038 rep.SASStatus);
15039 smp_pkt->smp_pkt_reason = EIO;
15040 return (DDI_FAILURE);
15041 }
15042
15043 return (DDI_SUCCESS);
15044 }
15045
15046 /*
15047 * If we didn't get a match, we need to get sas page0 for each device, and
15048 * untill we get a match. If failed, return NULL
15049 */
15050 static mptsas_target_t *
15051 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy)
15052 {
15053 int i, j = 0;
15054 int rval = 0;
15055 uint16_t cur_handle;
15056 uint32_t page_address;
15057 mptsas_target_t *ptgt = NULL;
15058
15059 /*
15060 * PHY named device must be direct attached and attaches to
15061 * narrow port, if the iport is not parent of the device which
15062 * we are looking for.
15063 */
15064 for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
15065 if ((1 << i) & phymask)
15066 j++;
15067 }
15068
15069 if (j > 1)
15070 return (NULL);
15071
15072 /*
15073 * Must be a narrow port and single device attached to the narrow port
15074 * So the physical port num of device which is equal to the iport's
15075 * port num is the device what we are looking for.
15076 */
15077
15078 if (mpt->m_phy_info[phy].phy_mask != phymask)
15079 return (NULL);
15080
15081 mutex_enter(&mpt->m_mutex);
15082
15083 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn,
15084 &phy);
15085 if (ptgt != NULL) {
15086 mutex_exit(&mpt->m_mutex);
15087 return (ptgt);
15088 }
15089
15090 if (mpt->m_done_traverse_dev) {
15091 mutex_exit(&mpt->m_mutex);
15092 return (NULL);
15093 }
15094
15095 /* If didn't get a match, come here */
15096 cur_handle = mpt->m_dev_handle;
15097 for (; ; ) {
15098 ptgt = NULL;
15099 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
15100 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
15101 rval = mptsas_get_target_device_info(mpt, page_address,
15102 &cur_handle, &ptgt);
15103 if ((rval == DEV_INFO_FAIL_PAGE0) ||
15104 (rval == DEV_INFO_FAIL_ALLOC)) {
15105 break;
15106 }
15107 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15108 (rval == DEV_INFO_PHYS_DISK)) {
15109 continue;
15110 }
15111 mpt->m_dev_handle = cur_handle;
15112
15113 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) {
15114 break;
15115 }
15116 }
15117
15118 mutex_exit(&mpt->m_mutex);
15119 return (ptgt);
15120 }
15121
15122 /*
15123 * The ptgt->m_addr.mta_wwn contains the wwid for each disk.
15124 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
15125 * If we didn't get a match, we need to get sas page0 for each device, and
15126 * untill we get a match
15127 * If failed, return NULL
15128 */
15129 static mptsas_target_t *
15130 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
15131 {
15132 int rval = 0;
15133 uint16_t cur_handle;
15134 uint32_t page_address;
15135 mptsas_target_t *tmp_tgt = NULL;
15136 mptsas_target_addr_t addr;
15137
15138 addr.mta_wwn = wwid;
15139 addr.mta_phymask = phymask;
15140 mutex_enter(&mpt->m_mutex);
15141 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
15142 if (tmp_tgt != NULL) {
15143 mutex_exit(&mpt->m_mutex);
15144 return (tmp_tgt);
15145 }
15146
15147 if (phymask == 0) {
15148 /*
15149 * It's IR volume
15150 */
15151 rval = mptsas_get_raid_info(mpt);
15152 if (rval) {
15153 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
15154 }
15155 mutex_exit(&mpt->m_mutex);
15156 return (tmp_tgt);
15157 }
15158
15159 if (mpt->m_done_traverse_dev) {
15160 mutex_exit(&mpt->m_mutex);
15161 return (NULL);
15162 }
15163
15164 /* If didn't get a match, come here */
15165 cur_handle = mpt->m_dev_handle;
15166 for (;;) {
15167 tmp_tgt = NULL;
15168 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
15169 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
15170 rval = mptsas_get_target_device_info(mpt, page_address,
15171 &cur_handle, &tmp_tgt);
15172 if ((rval == DEV_INFO_FAIL_PAGE0) ||
15173 (rval == DEV_INFO_FAIL_ALLOC)) {
15174 tmp_tgt = NULL;
15175 break;
15176 }
15177 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
15178 (rval == DEV_INFO_PHYS_DISK)) {
15179 continue;
15180 }
15181 mpt->m_dev_handle = cur_handle;
15182 if ((tmp_tgt->m_addr.mta_wwn) &&
15183 (tmp_tgt->m_addr.mta_wwn == wwid) &&
15184 (tmp_tgt->m_addr.mta_phymask == phymask)) {
15185 break;
15186 }
15187 }
15188
15189 mutex_exit(&mpt->m_mutex);
15190 return (tmp_tgt);
15191 }
15192
15193 static mptsas_smp_t *
15194 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid)
15195 {
15196 int rval = 0;
15197 uint16_t cur_handle;
15198 uint32_t page_address;
15199 mptsas_smp_t smp_node, *psmp = NULL;
15200 mptsas_target_addr_t addr;
15201
15202 addr.mta_wwn = wwid;
15203 addr.mta_phymask = phymask;
15204 mutex_enter(&mpt->m_mutex);
15205 psmp = refhash_lookup(mpt->m_smp_targets, &addr);
15206 if (psmp != NULL) {
15207 mutex_exit(&mpt->m_mutex);
15208 return (psmp);
15209 }
15210
15211 if (mpt->m_done_traverse_smp) {
15212 mutex_exit(&mpt->m_mutex);
15213 return (NULL);
15214 }
15215
15216 /* If didn't get a match, come here */
15217 cur_handle = mpt->m_smp_devhdl;
15218 for (;;) {
15219 psmp = NULL;
15220 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
15221 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
15222 rval = mptsas_get_sas_expander_page0(mpt, page_address,
15223 &smp_node);
15224 if (rval != DDI_SUCCESS) {
15225 break;
15226 }
15227 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
15228 psmp = mptsas_smp_alloc(mpt, &smp_node);
15229 ASSERT(psmp);
15230 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) &&
15231 (psmp->m_addr.mta_phymask == phymask)) {
15232 break;
15233 }
15234 }
15235
15236 mutex_exit(&mpt->m_mutex);
15237 return (psmp);
15238 }
15239
15240 mptsas_target_t *
15241 mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid,
15242 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum)
15243 {
15244 mptsas_target_t *tmp_tgt = NULL;
15245 mptsas_target_addr_t addr;
15246
15247 addr.mta_wwn = wwid;
15248 addr.mta_phymask = phymask;
15249 tmp_tgt = refhash_lookup(mpt->m_targets, &addr);
15250 if (tmp_tgt != NULL) {
15251 NDBG20(("Hash item already exist"));
15252 tmp_tgt->m_deviceinfo = devinfo;
15253 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */
15254 return (tmp_tgt);
15255 }
15256 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
15257 if (tmp_tgt == NULL) {
15258 cmn_err(CE_WARN, "Fatal, allocated tgt failed");
15259 return (NULL);
15260 }
15261 tmp_tgt->m_devhdl = devhdl;
15262 tmp_tgt->m_addr.mta_wwn = wwid;
15263 tmp_tgt->m_deviceinfo = devinfo;
15264 tmp_tgt->m_addr.mta_phymask = phymask;
15265 tmp_tgt->m_phynum = phynum;
15266 /* Initialized the tgt structure */
15267 tmp_tgt->m_qfull_retries = QFULL_RETRIES;
15268 tmp_tgt->m_qfull_retry_interval =
15269 drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
15270 tmp_tgt->m_t_throttle = MAX_THROTTLE;
15271
15272 refhash_insert(mpt->m_targets, tmp_tgt);
15273
15274 return (tmp_tgt);
15275 }
15276
15277 static void
15278 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst)
15279 {
15280 dst->m_devhdl = src->m_devhdl;
15281 dst->m_deviceinfo = src->m_deviceinfo;
15282 dst->m_pdevhdl = src->m_pdevhdl;
15283 dst->m_pdevinfo = src->m_pdevinfo;
15284 }
15285
15286 static mptsas_smp_t *
15287 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data)
15288 {
15289 mptsas_target_addr_t addr;
15290 mptsas_smp_t *ret_data;
15291
15292 addr.mta_wwn = data->m_addr.mta_wwn;
15293 addr.mta_phymask = data->m_addr.mta_phymask;
15294 ret_data = refhash_lookup(mpt->m_smp_targets, &addr);
15295 /*
15296 * If there's already a matching SMP target, update its fields
15297 * in place. Since the address is not changing, it's safe to do
15298 * this. We cannot just bcopy() here because the structure we've
15299 * been given has invalid hash links.
15300 */
15301 if (ret_data != NULL) {
15302 mptsas_smp_target_copy(data, ret_data);
15303 return (ret_data);
15304 }
15305
15306 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
15307 bcopy(data, ret_data, sizeof (mptsas_smp_t));
15308 refhash_insert(mpt->m_smp_targets, ret_data);
15309 return (ret_data);
15310 }
15311
15312 /*
15313 * Functions for SGPIO LED support
15314 */
15315 static dev_info_t *
15316 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask)
15317 {
15318 dev_info_t *dip;
15319 int prop;
15320 dip = e_ddi_hold_devi_by_dev(dev, 0);
15321 if (dip == NULL)
15322 return (dip);
15323 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
15324 "phymask", 0);
15325 *phymask = (mptsas_phymask_t)prop;
15326 ddi_release_devi(dip);
15327 return (dip);
15328 }
15329 static mptsas_target_t *
15330 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask)
15331 {
15332 uint8_t phynum;
15375 Mpi2SepRequest_t req;
15376 Mpi2SepReply_t rep;
15377 int ret;
15378
15379 ASSERT(mutex_owned(&mpt->m_mutex));
15380
15381 /*
15382 * We only support SEP control of directly-attached targets, in which
15383 * case the "SEP" we're talking to is a virtual one contained within
15384 * the HBA itself. This is necessary because DA targets typically have
15385 * no other mechanism for LED control. Targets for which a separate
15386 * enclosure service processor exists should be controlled via ses(7d)
15387 * or sgen(7d). Furthermore, since such requests can time out, they
15388 * should be made in user context rather than in response to
15389 * asynchronous fabric changes.
15390 *
15391 * In addition, we do not support this operation for RAID volumes,
15392 * since there is no slot associated with them.
15393 */
15394 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) ||
15395 ptgt->m_addr.mta_phymask == 0) {
15396 return (ENOTTY);
15397 }
15398
15399 bzero(&req, sizeof (req));
15400 bzero(&rep, sizeof (rep));
15401
15402 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
15403 req.Action = act;
15404 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS;
15405 req.EnclosureHandle = LE_16(ptgt->m_enclosure);
15406 req.Slot = LE_16(ptgt->m_slot_num);
15407 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) {
15408 req.SlotStatus = LE_32(*status);
15409 }
15410 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
15411 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
15412 if (ret != 0) {
15413 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP "
15414 "Processor Request message error %d", ret);
15415 return (ret);
|