xref: /illumos-gate/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_attach.c (revision 60aabb4ce92352f01733c518d6b6bb69e60b9113)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
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  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 #include <sys/scsi/adapters/pmcs/pmcs.h>
25 
26 #define	PMCS_DRIVER_VERSION	"pmcs HBA device driver"
27 
28 static	char	*pmcs_driver_rev = PMCS_DRIVER_VERSION;
29 
30 /*
31  * Non-DDI Compliant stuff
32  */
33 extern char hw_serial[];
34 
35 /*
36  * Global driver data
37  */
38 void *pmcs_softc_state = NULL;
39 void *pmcs_iport_softstate = NULL;
40 
41 /*
42  * Tracing and Logging info
43  */
44 pmcs_tbuf_t *pmcs_tbuf = NULL;
45 uint32_t pmcs_tbuf_num_elems = 0;
46 pmcs_tbuf_t *pmcs_tbuf_ptr;
47 uint32_t pmcs_tbuf_idx = 0;
48 boolean_t pmcs_tbuf_wrap = B_FALSE;
49 kmutex_t pmcs_trace_lock;
50 
51 /*
52  * If pmcs_force_syslog value is non-zero, all messages put in the trace log
53  * will also be sent to system log.
54  */
55 int pmcs_force_syslog = 0;
56 int pmcs_console = 0;
57 
58 /*
59  * External References
60  */
61 extern int ncpus_online;
62 
63 /*
64  * Local static data
65  */
66 static int fwlog_level = 3;
67 static int physpeed = PHY_LINK_ALL;
68 static int phymode = PHY_LM_AUTO;
69 static int block_mask = 0;
70 static int phymap_stable_usec = 3 * MICROSEC;
71 static int iportmap_stable_usec = 2 * MICROSEC;
72 static int iportmap_csync_usec = 20 * MICROSEC;
73 
74 #ifdef DEBUG
75 static int debug_mask = 1;
76 #else
77 static int debug_mask = 0;
78 #endif
79 
80 #ifdef DISABLE_MSIX
81 static int disable_msix = 1;
82 #else
83 static int disable_msix = 0;
84 #endif
85 
86 #ifdef DISABLE_MSI
87 static int disable_msi = 1;
88 #else
89 static int disable_msi = 0;
90 #endif
91 
92 static uint16_t maxqdepth = 0xfffe;
93 
94 /*
95  * Local prototypes
96  */
97 static int pmcs_attach(dev_info_t *, ddi_attach_cmd_t);
98 static int pmcs_detach(dev_info_t *, ddi_detach_cmd_t);
99 static int pmcs_unattach(pmcs_hw_t *);
100 static int pmcs_iport_unattach(pmcs_iport_t *);
101 static int pmcs_add_more_chunks(pmcs_hw_t *, unsigned long);
102 static void pmcs_watchdog(void *);
103 static int pmcs_setup_intr(pmcs_hw_t *);
104 static int pmcs_teardown_intr(pmcs_hw_t *);
105 
106 static uint_t pmcs_nonio_ix(caddr_t, caddr_t);
107 static uint_t pmcs_general_ix(caddr_t, caddr_t);
108 static uint_t pmcs_event_ix(caddr_t, caddr_t);
109 static uint_t pmcs_iodone_ix(caddr_t, caddr_t);
110 static uint_t pmcs_fatal_ix(caddr_t, caddr_t);
111 static uint_t pmcs_all_intr(caddr_t, caddr_t);
112 static int pmcs_quiesce(dev_info_t *dip);
113 static boolean_t pmcs_fabricate_wwid(pmcs_hw_t *);
114 
115 static void pmcs_create_all_phy_stats(pmcs_iport_t *);
116 int pmcs_update_phy_stats(kstat_t *, int);
117 static void pmcs_destroy_phy_stats(pmcs_iport_t *);
118 
119 static void pmcs_fm_fini(pmcs_hw_t *pwp);
120 static void pmcs_fm_init(pmcs_hw_t *pwp);
121 static int pmcs_fm_error_cb(dev_info_t *dip,
122     ddi_fm_error_t *err, const void *impl_data);
123 
124 /*
125  * Local configuration data
126  */
127 static struct dev_ops pmcs_ops = {
128 	DEVO_REV,		/* devo_rev, */
129 	0,			/* refcnt */
130 	ddi_no_info,		/* info */
131 	nulldev,		/* identify */
132 	nulldev,		/* probe */
133 	pmcs_attach,		/* attach */
134 	pmcs_detach,		/* detach */
135 	nodev,			/* reset */
136 	NULL,			/* driver operations */
137 	NULL,			/* bus operations */
138 	ddi_power,		/* power management */
139 	pmcs_quiesce		/* quiesce */
140 };
141 
142 static struct modldrv modldrv = {
143 	&mod_driverops,
144 	PMCS_DRIVER_VERSION,
145 	&pmcs_ops,	/* driver ops */
146 };
147 static struct modlinkage modlinkage = {
148 	MODREV_1, &modldrv, NULL
149 };
150 
151 const ddi_dma_attr_t pmcs_dattr = {
152 	DMA_ATTR_V0,			/* dma_attr version	*/
153 	0x0000000000000000ull,		/* dma_attr_addr_lo	*/
154 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_addr_hi	*/
155 	0x00000000FFFFFFFFull,		/* dma_attr_count_max	*/
156 	0x0000000000000001ull,		/* dma_attr_align	*/
157 	0x00000078,			/* dma_attr_burstsizes	*/
158 	0x00000001,			/* dma_attr_minxfer	*/
159 	0x00000000FFFFFFFFull,		/* dma_attr_maxxfer	*/
160 	0x00000000FFFFFFFFull,		/* dma_attr_seg		*/
161 	1,				/* dma_attr_sgllen 	*/
162 	512,				/* dma_attr_granular 	*/
163 	0				/* dma_attr_flags 	*/
164 };
165 
166 static ddi_device_acc_attr_t rattr = {
167 	DDI_DEVICE_ATTR_V1,
168 	DDI_STRUCTURE_LE_ACC,
169 	DDI_STRICTORDER_ACC,
170 	DDI_DEFAULT_ACC
171 };
172 
173 
174 /*
175  * Attach/Detach functions
176  */
177 
178 int
179 _init(void)
180 {
181 	int ret;
182 
183 	ret = ddi_soft_state_init(&pmcs_softc_state, sizeof (pmcs_hw_t), 1);
184 	if (ret != 0) {
185 		cmn_err(CE_WARN, "?soft state init failed for pmcs");
186 		return (ret);
187 	}
188 
189 	if ((ret = scsi_hba_init(&modlinkage)) != 0) {
190 		cmn_err(CE_WARN, "?scsi_hba_init failed for pmcs");
191 		ddi_soft_state_fini(&pmcs_softc_state);
192 		return (ret);
193 	}
194 
195 	/*
196 	 * Allocate soft state for iports
197 	 */
198 	ret = ddi_soft_state_init(&pmcs_iport_softstate,
199 	    sizeof (pmcs_iport_t), 2);
200 	if (ret != 0) {
201 		cmn_err(CE_WARN, "?iport soft state init failed for pmcs");
202 		ddi_soft_state_fini(&pmcs_softc_state);
203 		return (ret);
204 	}
205 
206 	ret = mod_install(&modlinkage);
207 	if (ret != 0) {
208 		cmn_err(CE_WARN, "?mod_install failed for pmcs (%d)", ret);
209 		scsi_hba_fini(&modlinkage);
210 		ddi_soft_state_fini(&pmcs_iport_softstate);
211 		ddi_soft_state_fini(&pmcs_softc_state);
212 		return (ret);
213 	}
214 
215 	/* Initialize the global trace lock */
216 	mutex_init(&pmcs_trace_lock, NULL, MUTEX_DRIVER, NULL);
217 
218 	return (0);
219 }
220 
221 int
222 _fini(void)
223 {
224 	int ret;
225 	if ((ret = mod_remove(&modlinkage)) != 0) {
226 		return (ret);
227 	}
228 	scsi_hba_fini(&modlinkage);
229 
230 	/* Free pmcs log buffer and destroy the global lock */
231 	if (pmcs_tbuf) {
232 		kmem_free(pmcs_tbuf,
233 		    pmcs_tbuf_num_elems * sizeof (pmcs_tbuf_t));
234 		pmcs_tbuf = NULL;
235 	}
236 	mutex_destroy(&pmcs_trace_lock);
237 
238 	ddi_soft_state_fini(&pmcs_iport_softstate);
239 	ddi_soft_state_fini(&pmcs_softc_state);
240 	return (0);
241 }
242 
243 int
244 _info(struct modinfo *modinfop)
245 {
246 	return (mod_info(&modlinkage, modinfop));
247 }
248 
249 static int
250 pmcs_iport_attach(dev_info_t *dip)
251 {
252 	pmcs_iport_t		*iport;
253 	pmcs_hw_t		*pwp;
254 	scsi_hba_tran_t		*tran;
255 	void			*ua_priv = NULL;
256 	char			*iport_ua;
257 	char			*init_port;
258 	int			hba_inst;
259 	int			inst;
260 
261 	hba_inst = ddi_get_instance(ddi_get_parent(dip));
262 	inst = ddi_get_instance(dip);
263 
264 	pwp = ddi_get_soft_state(pmcs_softc_state, hba_inst);
265 	if (pwp == NULL) {
266 		cmn_err(CE_WARN, "%s: No HBA softstate for instance %d",
267 		    __func__, inst);
268 		return (DDI_FAILURE);
269 	}
270 
271 	if ((pwp->state == STATE_UNPROBING) || (pwp->state == STATE_DEAD)) {
272 		return (DDI_FAILURE);
273 	}
274 
275 	if ((iport_ua = scsi_hba_iport_unit_address(dip)) == NULL) {
276 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
277 		    "%s: invoked with NULL unit address, inst (%d)",
278 		    __func__, inst);
279 		return (DDI_FAILURE);
280 	}
281 
282 	if (ddi_soft_state_zalloc(pmcs_iport_softstate, inst) != DDI_SUCCESS) {
283 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
284 		    "Failed to alloc soft state for iport %d", inst);
285 		return (DDI_FAILURE);
286 	}
287 
288 	iport = ddi_get_soft_state(pmcs_iport_softstate, inst);
289 	if (iport == NULL) {
290 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
291 		    "cannot get iport soft state");
292 		goto iport_attach_fail1;
293 	}
294 
295 	mutex_init(&iport->lock, NULL, MUTEX_DRIVER,
296 	    DDI_INTR_PRI(pwp->intr_pri));
297 	cv_init(&iport->refcnt_cv, NULL, CV_DEFAULT, NULL);
298 	cv_init(&iport->smp_cv, NULL, CV_DEFAULT, NULL);
299 	mutex_init(&iport->refcnt_lock, NULL, MUTEX_DRIVER,
300 	    DDI_INTR_PRI(pwp->intr_pri));
301 	mutex_init(&iport->smp_lock, NULL, MUTEX_DRIVER,
302 	    DDI_INTR_PRI(pwp->intr_pri));
303 
304 	/* Set some data on the iport handle */
305 	iport->dip = dip;
306 	iport->pwp = pwp;
307 
308 	/* Dup the UA into the iport handle */
309 	iport->ua = strdup(iport_ua);
310 
311 	tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip);
312 	tran->tran_hba_private = iport;
313 
314 	list_create(&iport->phys, sizeof (pmcs_phy_t),
315 	    offsetof(pmcs_phy_t, list_node));
316 
317 	/*
318 	 * If our unit address is active in the phymap, configure our
319 	 * iport's phylist.
320 	 */
321 	mutex_enter(&iport->lock);
322 	ua_priv = sas_phymap_lookup_uapriv(pwp->hss_phymap, iport->ua);
323 	if (ua_priv) {
324 		/* Non-NULL private data indicates the unit address is active */
325 		iport->ua_state = UA_ACTIVE;
326 		if (pmcs_iport_configure_phys(iport) != DDI_SUCCESS) {
327 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
328 			    "%s: failed to "
329 			    "configure phys on iport handle (0x%p), "
330 			    " unit address [%s]", __func__,
331 			    (void *)iport, iport_ua);
332 			mutex_exit(&iport->lock);
333 			goto iport_attach_fail2;
334 		}
335 	} else {
336 		iport->ua_state = UA_INACTIVE;
337 	}
338 	mutex_exit(&iport->lock);
339 
340 	/* Allocate string-based soft state pool for targets */
341 	iport->tgt_sstate = NULL;
342 	if (ddi_soft_state_bystr_init(&iport->tgt_sstate,
343 	    sizeof (pmcs_xscsi_t), PMCS_TGT_SSTATE_SZ) != 0) {
344 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
345 		    "cannot get iport tgt soft state");
346 		goto iport_attach_fail2;
347 	}
348 
349 	/* Create this iport's target map */
350 	if (pmcs_iport_tgtmap_create(iport) == B_FALSE) {
351 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
352 		    "Failed to create tgtmap on iport %d", inst);
353 		goto iport_attach_fail3;
354 	}
355 
356 	/* Set up the 'initiator-port' DDI property on this iport */
357 	init_port = kmem_zalloc(PMCS_MAX_UA_SIZE, KM_SLEEP);
358 	if (pwp->separate_ports) {
359 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
360 		    "%s: separate ports not supported", __func__);
361 	} else {
362 		/* Set initiator-port value to the HBA's base WWN */
363 		(void) scsi_wwn_to_wwnstr(pwp->sas_wwns[0], 1,
364 		    init_port);
365 	}
366 
367 	mutex_enter(&iport->lock);
368 	pmcs_smhba_add_iport_prop(iport, DATA_TYPE_STRING,
369 	    SCSI_ADDR_PROP_INITIATOR_PORT, init_port);
370 	kmem_free(init_port, PMCS_MAX_UA_SIZE);
371 
372 	/* Set up a 'num-phys' DDI property for the iport node */
373 	pmcs_smhba_add_iport_prop(iport, DATA_TYPE_INT32, PMCS_NUM_PHYS,
374 	    &iport->nphy);
375 	mutex_exit(&iport->lock);
376 
377 	/* Create kstats for each of the phys in this port */
378 	pmcs_create_all_phy_stats(iport);
379 
380 	/*
381 	 * Insert this iport handle into our list and set
382 	 * iports_attached on the HBA node.
383 	 */
384 	rw_enter(&pwp->iports_lock, RW_WRITER);
385 	ASSERT(!list_link_active(&iport->list_node));
386 	list_insert_tail(&pwp->iports, iport);
387 	pwp->iports_attached = 1;
388 	pwp->num_iports++;
389 	rw_exit(&pwp->iports_lock);
390 
391 	pmcs_prt(pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL,
392 	    "iport%d attached", inst);
393 	ddi_report_dev(dip);
394 	return (DDI_SUCCESS);
395 
396 	/* teardown and fail */
397 iport_attach_fail3:
398 	ddi_soft_state_bystr_fini(&iport->tgt_sstate);
399 iport_attach_fail2:
400 	list_destroy(&iport->phys);
401 	strfree(iport->ua);
402 	mutex_destroy(&iport->refcnt_lock);
403 	mutex_destroy(&iport->smp_lock);
404 	cv_destroy(&iport->refcnt_cv);
405 	cv_destroy(&iport->smp_cv);
406 	mutex_destroy(&iport->lock);
407 iport_attach_fail1:
408 	ddi_soft_state_free(pmcs_iport_softstate, inst);
409 	return (DDI_FAILURE);
410 }
411 
412 static int
413 pmcs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
414 {
415 	scsi_hba_tran_t *tran;
416 	char chiprev, *fwsupport, hw_rev[24], fw_rev[24];
417 	off_t set3size;
418 	int inst, i;
419 	int sm_hba = 1;
420 	int protocol = 0;
421 	int num_phys = 0;
422 	pmcs_hw_t *pwp;
423 	pmcs_phy_t *phyp;
424 	uint32_t num_threads;
425 	char buf[64];
426 	char *fwl_file;
427 
428 	switch (cmd) {
429 	case DDI_ATTACH:
430 		break;
431 
432 	case DDI_PM_RESUME:
433 	case DDI_RESUME:
434 		tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip);
435 		if (!tran) {
436 			return (DDI_FAILURE);
437 		}
438 		/* No DDI_?_RESUME on iport nodes */
439 		if (scsi_hba_iport_unit_address(dip) != NULL) {
440 			return (DDI_SUCCESS);
441 		}
442 		pwp = TRAN2PMC(tran);
443 		if (pwp == NULL) {
444 			return (DDI_FAILURE);
445 		}
446 
447 		mutex_enter(&pwp->lock);
448 		pwp->suspended = 0;
449 		if (pwp->tq) {
450 			ddi_taskq_resume(pwp->tq);
451 		}
452 		mutex_exit(&pwp->lock);
453 		return (DDI_SUCCESS);
454 
455 	default:
456 		return (DDI_FAILURE);
457 	}
458 
459 	/*
460 	 * If this is an iport node, invoke iport attach.
461 	 */
462 	if (scsi_hba_iport_unit_address(dip) != NULL) {
463 		return (pmcs_iport_attach(dip));
464 	}
465 
466 	/*
467 	 * From here on is attach for the HBA node
468 	 */
469 
470 #ifdef	DEBUG
471 	/*
472 	 * Check to see if this unit is to be disabled.  We can't disable
473 	 * on a per-iport node.  It's either the entire HBA or nothing.
474 	 */
475 	(void) snprintf(buf, sizeof (buf),
476 	    "disable-instance-%d", ddi_get_instance(dip));
477 	if (ddi_prop_get_int(DDI_DEV_T_ANY, dip,
478 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, buf, 0)) {
479 		cmn_err(CE_NOTE, "pmcs%d: disabled by configuration",
480 		    ddi_get_instance(dip));
481 		return (DDI_FAILURE);
482 	}
483 #endif
484 
485 	/*
486 	 * Allocate softstate
487 	 */
488 	inst = ddi_get_instance(dip);
489 	if (ddi_soft_state_zalloc(pmcs_softc_state, inst) != DDI_SUCCESS) {
490 		cmn_err(CE_WARN, "pmcs%d: Failed to alloc soft state", inst);
491 		return (DDI_FAILURE);
492 	}
493 
494 	pwp = ddi_get_soft_state(pmcs_softc_state, inst);
495 	if (pwp == NULL) {
496 		cmn_err(CE_WARN, "pmcs%d: cannot get soft state", inst);
497 		ddi_soft_state_free(pmcs_softc_state, inst);
498 		return (DDI_FAILURE);
499 	}
500 	pwp->dip = dip;
501 	STAILQ_INIT(&pwp->dq);
502 	STAILQ_INIT(&pwp->cq);
503 	STAILQ_INIT(&pwp->wf);
504 	STAILQ_INIT(&pwp->pf);
505 
506 	/*
507 	 * Create the list for iports and init its lock.
508 	 */
509 	list_create(&pwp->iports, sizeof (pmcs_iport_t),
510 	    offsetof(pmcs_iport_t, list_node));
511 	rw_init(&pwp->iports_lock, NULL, RW_DRIVER, NULL);
512 
513 	pwp->state = STATE_PROBING;
514 
515 	/*
516 	 * Get driver.conf properties
517 	 */
518 	pwp->debug_mask = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
519 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-debug-mask",
520 	    debug_mask);
521 	pwp->phyid_block_mask = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
522 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-phyid-block-mask",
523 	    block_mask);
524 	pwp->physpeed = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
525 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-physpeed", physpeed);
526 	pwp->phymode = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
527 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-phymode", phymode);
528 	pwp->fwlog = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
529 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-fwlog", fwlog_level);
530 	if (pwp->fwlog > PMCS_FWLOG_MAX) {
531 		pwp->fwlog = PMCS_FWLOG_MAX;
532 	}
533 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "pmcs-fwlogfile",
534 	    &fwl_file) == DDI_SUCCESS)) {
535 		if (snprintf(pwp->fwlogfile_aap1, MAXPATHLEN, "%s%d-aap1.0",
536 		    fwl_file, ddi_get_instance(dip)) > MAXPATHLEN) {
537 			pwp->fwlogfile_aap1[0] = '\0';
538 			pwp->fwlogfile_iop[0] = '\0';
539 		} else if (snprintf(pwp->fwlogfile_iop, MAXPATHLEN,
540 		    "%s%d-iop.0", fwl_file,
541 		    ddi_get_instance(dip)) > MAXPATHLEN) {
542 			pwp->fwlogfile_aap1[0] = '\0';
543 			pwp->fwlogfile_iop[0] = '\0';
544 		}
545 		ddi_prop_free(fwl_file);
546 	} else {
547 		pwp->fwlogfile_aap1[0] = '\0';
548 		pwp->fwlogfile_iop[0] = '\0';
549 	}
550 
551 	pwp->open_retry_interval = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
552 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-open-retry-interval",
553 	    OPEN_RETRY_INTERVAL_DEF);
554 	if (pwp->open_retry_interval > OPEN_RETRY_INTERVAL_MAX) {
555 		pwp->open_retry_interval = OPEN_RETRY_INTERVAL_MAX;
556 	}
557 
558 	mutex_enter(&pmcs_trace_lock);
559 	if (pmcs_tbuf == NULL) {
560 		/* Allocate trace buffer */
561 		pmcs_tbuf_num_elems = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
562 		    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-tbuf-num-elems",
563 		    PMCS_TBUF_NUM_ELEMS_DEF);
564 		if ((pmcs_tbuf_num_elems == DDI_PROP_NOT_FOUND) ||
565 		    (pmcs_tbuf_num_elems == 0)) {
566 			pmcs_tbuf_num_elems = PMCS_TBUF_NUM_ELEMS_DEF;
567 		}
568 
569 		pmcs_tbuf = kmem_zalloc(pmcs_tbuf_num_elems *
570 		    sizeof (pmcs_tbuf_t), KM_SLEEP);
571 		pmcs_tbuf_ptr = pmcs_tbuf;
572 		pmcs_tbuf_idx = 0;
573 	}
574 	mutex_exit(&pmcs_trace_lock);
575 
576 	if (pwp->fwlog && strlen(pwp->fwlogfile_aap1) > 0) {
577 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
578 		    "%s: firmware event log files: %s, %s", __func__,
579 		    pwp->fwlogfile_aap1, pwp->fwlogfile_iop);
580 		pwp->fwlog_file = 1;
581 	} else {
582 		if (pwp->fwlog == 0) {
583 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
584 			    "%s: No firmware event log will be written "
585 			    "(event log disabled)", __func__);
586 		} else {
587 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
588 			    "%s: No firmware event log will be written "
589 			    "(no filename configured - too long?)", __func__);
590 		}
591 		pwp->fwlog_file = 0;
592 	}
593 
594 	disable_msix = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
595 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-disable-msix",
596 	    disable_msix);
597 	disable_msi = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
598 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-disable-msi",
599 	    disable_msi);
600 	maxqdepth = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
601 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-maxqdepth", maxqdepth);
602 	pwp->fw_force_update = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
603 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-fw-force-update", 0);
604 	if (pwp->fw_force_update == 0) {
605 		pwp->fw_disable_update = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
606 		    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
607 		    "pmcs-fw-disable-update", 0);
608 	}
609 	pwp->ioq_depth = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
610 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pmcs-num-io-qentries",
611 	    PMCS_NQENTRY);
612 
613 	/*
614 	 * Initialize FMA
615 	 */
616 	pwp->dev_acc_attr = pwp->reg_acc_attr = rattr;
617 	pwp->iqp_dma_attr = pwp->oqp_dma_attr =
618 	    pwp->regdump_dma_attr = pwp->cip_dma_attr =
619 	    pwp->fwlog_dma_attr = pmcs_dattr;
620 	pwp->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, pwp->dip,
621 	    DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, "fm-capable",
622 	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
623 	    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
624 	pmcs_fm_init(pwp);
625 
626 	/*
627 	 * Map registers
628 	 */
629 	if (pci_config_setup(dip, &pwp->pci_acc_handle)) {
630 		pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
631 		    "pci config setup failed");
632 		ddi_soft_state_free(pmcs_softc_state, inst);
633 		return (DDI_FAILURE);
634 	}
635 
636 	/*
637 	 * Get the size of register set 3.
638 	 */
639 	if (ddi_dev_regsize(dip, PMCS_REGSET_3, &set3size) != DDI_SUCCESS) {
640 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
641 		    "unable to get size of register set %d", PMCS_REGSET_3);
642 		pci_config_teardown(&pwp->pci_acc_handle);
643 		ddi_soft_state_free(pmcs_softc_state, inst);
644 		return (DDI_FAILURE);
645 	}
646 
647 	/*
648 	 * Map registers
649 	 */
650 	pwp->reg_acc_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
651 
652 	if (ddi_regs_map_setup(dip, PMCS_REGSET_0, (caddr_t *)&pwp->msg_regs,
653 	    0, 0, &pwp->reg_acc_attr, &pwp->msg_acc_handle)) {
654 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
655 		    "failed to map Message Unit registers");
656 		pci_config_teardown(&pwp->pci_acc_handle);
657 		ddi_soft_state_free(pmcs_softc_state, inst);
658 		return (DDI_FAILURE);
659 	}
660 
661 	if (ddi_regs_map_setup(dip, PMCS_REGSET_1, (caddr_t *)&pwp->top_regs,
662 	    0, 0, &pwp->reg_acc_attr, &pwp->top_acc_handle)) {
663 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
664 		    "failed to map TOP registers");
665 		ddi_regs_map_free(&pwp->msg_acc_handle);
666 		pci_config_teardown(&pwp->pci_acc_handle);
667 		ddi_soft_state_free(pmcs_softc_state, inst);
668 		return (DDI_FAILURE);
669 	}
670 
671 	if (ddi_regs_map_setup(dip, PMCS_REGSET_2, (caddr_t *)&pwp->gsm_regs,
672 	    0, 0, &pwp->reg_acc_attr, &pwp->gsm_acc_handle)) {
673 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
674 		    "failed to map GSM registers");
675 		ddi_regs_map_free(&pwp->top_acc_handle);
676 		ddi_regs_map_free(&pwp->msg_acc_handle);
677 		pci_config_teardown(&pwp->pci_acc_handle);
678 		ddi_soft_state_free(pmcs_softc_state, inst);
679 		return (DDI_FAILURE);
680 	}
681 
682 	if (ddi_regs_map_setup(dip, PMCS_REGSET_3, (caddr_t *)&pwp->mpi_regs,
683 	    0, 0, &pwp->reg_acc_attr, &pwp->mpi_acc_handle)) {
684 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
685 		    "failed to map MPI registers");
686 		ddi_regs_map_free(&pwp->top_acc_handle);
687 		ddi_regs_map_free(&pwp->gsm_acc_handle);
688 		ddi_regs_map_free(&pwp->msg_acc_handle);
689 		pci_config_teardown(&pwp->pci_acc_handle);
690 		ddi_soft_state_free(pmcs_softc_state, inst);
691 		return (DDI_FAILURE);
692 	}
693 	pwp->mpibar =
694 	    (((5U << 2) + 0x10) << PMCS_MSGU_MPI_BAR_SHIFT) | set3size;
695 
696 	/*
697 	 * Make sure we can support this card.
698 	 */
699 	pwp->chiprev = pmcs_rd_topunit(pwp, PMCS_DEVICE_REVISION);
700 
701 	switch (pwp->chiprev) {
702 	case PMCS_PM8001_REV_A:
703 	case PMCS_PM8001_REV_B:
704 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
705 		    "Rev A/B Card no longer supported");
706 		goto failure;
707 	case PMCS_PM8001_REV_C:
708 		break;
709 	default:
710 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
711 		    "Unknown chip revision (%d)", pwp->chiprev);
712 		goto failure;
713 	}
714 
715 	/*
716 	 * Allocate DMA addressable area for Inbound and Outbound Queue indices
717 	 * that the chip needs to access plus a space for scratch usage
718 	 */
719 	pwp->cip_dma_attr.dma_attr_align = sizeof (uint32_t);
720 	if (pmcs_dma_setup(pwp, &pwp->cip_dma_attr, &pwp->cip_acchdls,
721 	    &pwp->cip_handles, ptob(1), (caddr_t *)&pwp->cip,
722 	    &pwp->ciaddr) == B_FALSE) {
723 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
724 		    "Failed to setup DMA for index/scratch");
725 		goto failure;
726 	}
727 
728 	bzero(pwp->cip, ptob(1));
729 	pwp->scratch = &pwp->cip[PMCS_INDICES_SIZE];
730 	pwp->scratch_dma = pwp->ciaddr + PMCS_INDICES_SIZE;
731 
732 	/*
733 	 * Allocate DMA S/G list chunks
734 	 */
735 	(void) pmcs_add_more_chunks(pwp, ptob(1) * PMCS_MIN_CHUNK_PAGES);
736 
737 	/*
738 	 * Allocate a DMA addressable area for the firmware log (if needed)
739 	 */
740 	if (pwp->fwlog) {
741 		/*
742 		 * Align to event log header and entry size
743 		 */
744 		pwp->fwlog_dma_attr.dma_attr_align = 32;
745 		if (pmcs_dma_setup(pwp, &pwp->fwlog_dma_attr,
746 		    &pwp->fwlog_acchdl,
747 		    &pwp->fwlog_hndl, PMCS_FWLOG_SIZE,
748 		    (caddr_t *)&pwp->fwlogp,
749 		    &pwp->fwaddr) == B_FALSE) {
750 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
751 			    "Failed to setup DMA for fwlog area");
752 			pwp->fwlog = 0;
753 		} else {
754 			bzero(pwp->fwlogp, PMCS_FWLOG_SIZE);
755 			pwp->fwlogp_aap1 = (pmcs_fw_event_hdr_t *)pwp->fwlogp;
756 			pwp->fwlogp_iop = (pmcs_fw_event_hdr_t *)((void *)
757 			    ((caddr_t)pwp->fwlogp + (PMCS_FWLOG_SIZE / 2)));
758 		}
759 	}
760 
761 	if (pwp->flash_chunk_addr == NULL) {
762 		pwp->regdump_dma_attr.dma_attr_align = PMCS_FLASH_CHUNK_SIZE;
763 		if (pmcs_dma_setup(pwp, &pwp->regdump_dma_attr,
764 		    &pwp->regdump_acchdl,
765 		    &pwp->regdump_hndl, PMCS_FLASH_CHUNK_SIZE,
766 		    (caddr_t *)&pwp->flash_chunkp, &pwp->flash_chunk_addr) ==
767 		    B_FALSE) {
768 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
769 			    "Failed to setup DMA for register dump area");
770 			goto failure;
771 		}
772 		bzero(pwp->flash_chunkp, PMCS_FLASH_CHUNK_SIZE);
773 	}
774 
775 	/*
776 	 * More bits of local initialization...
777 	 */
778 	pwp->tq = ddi_taskq_create(dip, "_tq", 4, TASKQ_DEFAULTPRI, 0);
779 	if (pwp->tq == NULL) {
780 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
781 		    "unable to create worker taskq");
782 		goto failure;
783 	}
784 
785 	/*
786 	 * Cache of structures for dealing with I/O completion callbacks.
787 	 */
788 	(void) snprintf(buf, sizeof (buf), "pmcs_iocomp_cb_cache%d", inst);
789 	pwp->iocomp_cb_cache = kmem_cache_create(buf,
790 	    sizeof (pmcs_iocomp_cb_t), 16, NULL, NULL, NULL, NULL, NULL, 0);
791 
792 	/*
793 	 * Cache of PHY structures
794 	 */
795 	(void) snprintf(buf, sizeof (buf), "pmcs_phy_cache%d", inst);
796 	pwp->phy_cache = kmem_cache_create(buf, sizeof (pmcs_phy_t), 8,
797 	    pmcs_phy_constructor, pmcs_phy_destructor, NULL, (void *)pwp,
798 	    NULL, 0);
799 
800 	/*
801 	 * Allocate space for the I/O completion threads
802 	 */
803 	num_threads = ncpus_online;
804 	if (num_threads > PMCS_MAX_CQ_THREADS) {
805 		num_threads = PMCS_MAX_CQ_THREADS;
806 	}
807 
808 	pwp->cq_info.cq_thr_info = kmem_zalloc(sizeof (pmcs_cq_thr_info_t) *
809 	    num_threads, KM_SLEEP);
810 	pwp->cq_info.cq_threads = num_threads;
811 	pwp->cq_info.cq_next_disp_thr = 0;
812 	pwp->cq_info.cq_stop = B_FALSE;
813 
814 	/*
815 	 * Set the quantum value in clock ticks for the I/O interrupt
816 	 * coalescing timer.
817 	 */
818 	pwp->io_intr_coal.quantum = drv_usectohz(PMCS_QUANTUM_TIME_USECS);
819 
820 	/*
821 	 * We have a delicate dance here. We need to set up
822 	 * interrupts so we know how to set up some OQC
823 	 * tables. However, while we're setting up table
824 	 * access, we may need to flash new firmware and
825 	 * reset the card, which will take some finessing.
826 	 */
827 
828 	/*
829 	 * Set up interrupts here.
830 	 */
831 	switch (pmcs_setup_intr(pwp)) {
832 	case 0:
833 		break;
834 	case EIO:
835 		pwp->stuck = 1;
836 		/* FALLTHROUGH */
837 	default:
838 		goto failure;
839 	}
840 
841 	/*
842 	 * Set these up now becuase they are used to initialize the OQC tables.
843 	 *
844 	 * If we have MSI or MSI-X interrupts set up and we have enough
845 	 * vectors for each OQ, the Outbound Queue vectors can all be the
846 	 * same as the appropriate interrupt routine will have been called
847 	 * and the doorbell register automatically cleared.
848 	 * This keeps us from having to check the Outbound Doorbell register
849 	 * when the routines for these interrupts are called.
850 	 *
851 	 * If we have Legacy INT-X interrupts set up or we didn't have enough
852 	 * MSI/MSI-X vectors to uniquely identify each OQ, we point these
853 	 * vectors to the bits we would like to have set in the Outbound
854 	 * Doorbell register because pmcs_all_intr will read the doorbell
855 	 * register to find out why we have an interrupt and write the
856 	 * corresponding 'clear' bit for that interrupt.
857 	 */
858 
859 	switch (pwp->intr_cnt) {
860 	case 1:
861 		/*
862 		 * Only one vector, so we must check all OQs for MSI.  For
863 		 * INT-X, there's only one vector anyway, so we can just
864 		 * use the outbound queue bits to keep from having to
865 		 * check each queue for each interrupt.
866 		 */
867 		if (pwp->int_type == PMCS_INT_FIXED) {
868 			pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE;
869 			pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_GENERAL;
870 			pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_EVENTS;
871 		} else {
872 			pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE;
873 			pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_IODONE;
874 			pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_IODONE;
875 		}
876 		break;
877 	case 2:
878 		/* With 2, we can at least isolate IODONE */
879 		pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE;
880 		pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_GENERAL;
881 		pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_GENERAL;
882 		break;
883 	case 4:
884 		/* With 4 vectors, everybody gets one */
885 		pwp->oqvec[PMCS_OQ_IODONE] = PMCS_OQ_IODONE;
886 		pwp->oqvec[PMCS_OQ_GENERAL] = PMCS_OQ_GENERAL;
887 		pwp->oqvec[PMCS_OQ_EVENTS] = PMCS_OQ_EVENTS;
888 		break;
889 	}
890 
891 	/*
892 	 * Do the first part of setup
893 	 */
894 	if (pmcs_setup(pwp)) {
895 		goto failure;
896 	}
897 	pmcs_report_fwversion(pwp);
898 
899 	/*
900 	 * Now do some additonal allocations based upon information
901 	 * gathered during MPI setup.
902 	 */
903 	pwp->root_phys = kmem_zalloc(pwp->nphy * sizeof (pmcs_phy_t), KM_SLEEP);
904 	ASSERT(pwp->nphy < SAS2_PHYNUM_MAX);
905 	phyp = pwp->root_phys;
906 	for (i = 0; i < pwp->nphy; i++) {
907 		if (i < pwp->nphy-1) {
908 			phyp->sibling = (phyp + 1);
909 		}
910 		mutex_init(&phyp->phy_lock, NULL, MUTEX_DRIVER,
911 		    DDI_INTR_PRI(pwp->intr_pri));
912 		phyp->phynum = i & SAS2_PHYNUM_MASK;
913 		pmcs_phy_name(pwp, phyp, phyp->path, sizeof (phyp->path));
914 		phyp->pwp = pwp;
915 		phyp->device_id = PMCS_INVALID_DEVICE_ID;
916 		phyp->portid = PMCS_PHY_INVALID_PORT_ID;
917 		phyp++;
918 	}
919 
920 	pwp->work = kmem_zalloc(pwp->max_cmd * sizeof (pmcwork_t), KM_SLEEP);
921 	for (i = 0; i < pwp->max_cmd - 1; i++) {
922 		pmcwork_t *pwrk = &pwp->work[i];
923 		mutex_init(&pwrk->lock, NULL, MUTEX_DRIVER,
924 		    DDI_INTR_PRI(pwp->intr_pri));
925 		cv_init(&pwrk->sleep_cv, NULL, CV_DRIVER, NULL);
926 		STAILQ_INSERT_TAIL(&pwp->wf, pwrk, next);
927 
928 	}
929 	pwp->targets = (pmcs_xscsi_t **)
930 	    kmem_zalloc(pwp->max_dev * sizeof (pmcs_xscsi_t *), KM_SLEEP);
931 
932 	pwp->iqpt = (pmcs_iqp_trace_t *)
933 	    kmem_zalloc(sizeof (pmcs_iqp_trace_t), KM_SLEEP);
934 	pwp->iqpt->head = kmem_zalloc(PMCS_IQP_TRACE_BUFFER_SIZE, KM_SLEEP);
935 	pwp->iqpt->curpos = pwp->iqpt->head;
936 	pwp->iqpt->size_left = PMCS_IQP_TRACE_BUFFER_SIZE;
937 
938 	/*
939 	 * Start MPI communication.
940 	 */
941 	if (pmcs_start_mpi(pwp)) {
942 		if (pmcs_soft_reset(pwp, B_FALSE)) {
943 			goto failure;
944 		}
945 		pwp->last_reset_reason = PMCS_LAST_RST_ATTACH;
946 	}
947 
948 	/*
949 	 * Do some initial acceptance tests.
950 	 * This tests interrupts and queues.
951 	 */
952 	if (pmcs_echo_test(pwp)) {
953 		goto failure;
954 	}
955 
956 	/* Read VPD - if it exists */
957 	if (pmcs_get_nvmd(pwp, PMCS_NVMD_VPD, PMCIN_NVMD_VPD, 0, NULL, 0)) {
958 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
959 		    "%s: Unable to read VPD: "
960 		    "attempting to fabricate", __func__);
961 		/*
962 		 * When we release, this must goto failure and the call
963 		 * to pmcs_fabricate_wwid is removed.
964 		 */
965 		/* goto failure; */
966 		if (!pmcs_fabricate_wwid(pwp)) {
967 			goto failure;
968 		}
969 	}
970 
971 	/*
972 	 * We're now officially running
973 	 */
974 	pwp->state = STATE_RUNNING;
975 
976 	/*
977 	 * Check firmware versions and load new firmware
978 	 * if needed and reset.
979 	 */
980 	if (pmcs_firmware_update(pwp)) {
981 		pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
982 		    "%s: Firmware update failed", __func__);
983 		goto failure;
984 	}
985 
986 	/*
987 	 * Create completion threads.
988 	 */
989 	for (i = 0; i < pwp->cq_info.cq_threads; i++) {
990 		pwp->cq_info.cq_thr_info[i].cq_pwp = pwp;
991 		pwp->cq_info.cq_thr_info[i].cq_thread =
992 		    thread_create(NULL, 0, pmcs_scsa_cq_run,
993 		    &pwp->cq_info.cq_thr_info[i], 0, &p0, TS_RUN, minclsyspri);
994 	}
995 
996 	/*
997 	 * Create one thread to deal with the updating of the interrupt
998 	 * coalescing timer.
999 	 */
1000 	pwp->ict_thread = thread_create(NULL, 0, pmcs_check_intr_coal,
1001 	    pwp, 0, &p0, TS_RUN, minclsyspri);
1002 
1003 	/*
1004 	 * Kick off the watchdog
1005 	 */
1006 	pwp->wdhandle = timeout(pmcs_watchdog, pwp,
1007 	    drv_usectohz(PMCS_WATCH_INTERVAL));
1008 	/*
1009 	 * Do the SCSI attachment code (before starting phys)
1010 	 */
1011 	if (pmcs_scsa_init(pwp, &pmcs_dattr)) {
1012 		goto failure;
1013 	}
1014 	pwp->hba_attached = 1;
1015 
1016 	/* Check all acc & dma handles allocated in attach */
1017 	if (pmcs_check_acc_dma_handle(pwp)) {
1018 		ddi_fm_service_impact(pwp->dip, DDI_SERVICE_LOST);
1019 		goto failure;
1020 	}
1021 
1022 	/*
1023 	 * Create the phymap for this HBA instance
1024 	 */
1025 	if (sas_phymap_create(dip, phymap_stable_usec, PHYMAP_MODE_SIMPLE, NULL,
1026 	    pwp, pmcs_phymap_activate, pmcs_phymap_deactivate,
1027 	    &pwp->hss_phymap) != DDI_SUCCESS) {
1028 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1029 		    "%s: pmcs%d phymap_create failed", __func__, inst);
1030 		goto failure;
1031 	}
1032 	ASSERT(pwp->hss_phymap);
1033 
1034 	/*
1035 	 * Create the iportmap for this HBA instance
1036 	 */
1037 	if (scsi_hba_iportmap_create(dip, iportmap_csync_usec,
1038 	    iportmap_stable_usec, &pwp->hss_iportmap) != DDI_SUCCESS) {
1039 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1040 		    "%s: pmcs%d iportmap_create failed", __func__, inst);
1041 		goto failure;
1042 	}
1043 	ASSERT(pwp->hss_iportmap);
1044 
1045 	/*
1046 	 * Start the PHYs.
1047 	 */
1048 	if (pmcs_start_phys(pwp)) {
1049 		goto failure;
1050 	}
1051 
1052 	/*
1053 	 * From this point on, we can't fail.
1054 	 */
1055 	ddi_report_dev(dip);
1056 
1057 	/* SM-HBA */
1058 	pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_INT32, PMCS_SMHBA_SUPPORTED,
1059 	    &sm_hba);
1060 
1061 	/* SM-HBA */
1062 	pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_STRING, PMCS_DRV_VERSION,
1063 	    pmcs_driver_rev);
1064 
1065 	/* SM-HBA */
1066 	chiprev = 'A' + pwp->chiprev;
1067 	(void) snprintf(hw_rev, 2, "%s", &chiprev);
1068 	pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_STRING, PMCS_HWARE_VERSION,
1069 	    hw_rev);
1070 
1071 	/* SM-HBA */
1072 	switch (PMCS_FW_TYPE(pwp)) {
1073 	case PMCS_FW_TYPE_RELEASED:
1074 		fwsupport = "Released";
1075 		break;
1076 	case PMCS_FW_TYPE_DEVELOPMENT:
1077 		fwsupport = "Development";
1078 		break;
1079 	case PMCS_FW_TYPE_ALPHA:
1080 		fwsupport = "Alpha";
1081 		break;
1082 	case PMCS_FW_TYPE_BETA:
1083 		fwsupport = "Beta";
1084 		break;
1085 	default:
1086 		fwsupport = "Special";
1087 		break;
1088 	}
1089 	(void) snprintf(fw_rev, sizeof (fw_rev), "%x.%x.%x %s",
1090 	    PMCS_FW_MAJOR(pwp), PMCS_FW_MINOR(pwp), PMCS_FW_MICRO(pwp),
1091 	    fwsupport);
1092 	pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_STRING, PMCS_FWARE_VERSION,
1093 	    fw_rev);
1094 
1095 	/* SM-HBA */
1096 	num_phys = pwp->nphy;
1097 	pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_INT32, PMCS_NUM_PHYS_HBA,
1098 	    &num_phys);
1099 
1100 	/* SM-HBA */
1101 	protocol = SAS_SSP_SUPPORT | SAS_SATA_SUPPORT | SAS_SMP_SUPPORT;
1102 	pmcs_smhba_add_hba_prop(pwp, DATA_TYPE_INT32, PMCS_SUPPORTED_PROTOCOL,
1103 	    &protocol);
1104 
1105 	/* Receptacle properties (FMA) */
1106 	pwp->recept_labels[0] = PMCS_RECEPT_LABEL_0;
1107 	pwp->recept_pm[0] = PMCS_RECEPT_PM_0;
1108 	pwp->recept_labels[1] = PMCS_RECEPT_LABEL_1;
1109 	pwp->recept_pm[1] = PMCS_RECEPT_PM_1;
1110 	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip,
1111 	    SCSI_HBA_PROP_RECEPTACLE_LABEL, &pwp->recept_labels[0],
1112 	    PMCS_NUM_RECEPTACLES) != DDI_PROP_SUCCESS) {
1113 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1114 		    "%s: failed to create %s property", __func__,
1115 		    "receptacle-label");
1116 	}
1117 	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip,
1118 	    SCSI_HBA_PROP_RECEPTACLE_PM, &pwp->recept_pm[0],
1119 	    PMCS_NUM_RECEPTACLES) != DDI_PROP_SUCCESS) {
1120 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1121 		    "%s: failed to create %s property", __func__,
1122 		    "receptacle-pm");
1123 	}
1124 
1125 	return (DDI_SUCCESS);
1126 
1127 failure:
1128 	if (pmcs_unattach(pwp)) {
1129 		pwp->stuck = 1;
1130 	}
1131 	return (DDI_FAILURE);
1132 }
1133 
1134 int
1135 pmcs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1136 {
1137 	int inst = ddi_get_instance(dip);
1138 	pmcs_iport_t	*iport = NULL;
1139 	pmcs_hw_t	*pwp = NULL;
1140 	scsi_hba_tran_t	*tran;
1141 
1142 	if (scsi_hba_iport_unit_address(dip) != NULL) {
1143 		/* iport node */
1144 		iport = ddi_get_soft_state(pmcs_iport_softstate, inst);
1145 		ASSERT(iport);
1146 		if (iport == NULL) {
1147 			return (DDI_FAILURE);
1148 		}
1149 		pwp = iport->pwp;
1150 	} else {
1151 		/* hba node */
1152 		pwp = (pmcs_hw_t *)ddi_get_soft_state(pmcs_softc_state, inst);
1153 		ASSERT(pwp);
1154 		if (pwp == NULL) {
1155 			return (DDI_FAILURE);
1156 		}
1157 	}
1158 
1159 	switch (cmd) {
1160 	case DDI_DETACH:
1161 		if (iport) {
1162 			/* iport detach */
1163 			if (pmcs_iport_unattach(iport)) {
1164 				return (DDI_FAILURE);
1165 			}
1166 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1167 			    "iport%d detached", inst);
1168 			return (DDI_SUCCESS);
1169 		} else {
1170 			/* HBA detach */
1171 			if (pmcs_unattach(pwp)) {
1172 				return (DDI_FAILURE);
1173 			}
1174 			return (DDI_SUCCESS);
1175 		}
1176 
1177 	case DDI_SUSPEND:
1178 	case DDI_PM_SUSPEND:
1179 		/* No DDI_SUSPEND on iport nodes */
1180 		if (iport) {
1181 			return (DDI_SUCCESS);
1182 		}
1183 
1184 		if (pwp->stuck) {
1185 			return (DDI_FAILURE);
1186 		}
1187 		tran = (scsi_hba_tran_t *)ddi_get_driver_private(dip);
1188 		if (!tran) {
1189 			return (DDI_FAILURE);
1190 		}
1191 
1192 		pwp = TRAN2PMC(tran);
1193 		if (pwp == NULL) {
1194 			return (DDI_FAILURE);
1195 		}
1196 		mutex_enter(&pwp->lock);
1197 		if (pwp->tq) {
1198 			ddi_taskq_suspend(pwp->tq);
1199 		}
1200 		pwp->suspended = 1;
1201 		mutex_exit(&pwp->lock);
1202 		pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "PMC8X6G suspending");
1203 		return (DDI_SUCCESS);
1204 
1205 	default:
1206 		return (DDI_FAILURE);
1207 	}
1208 }
1209 
1210 static int
1211 pmcs_iport_unattach(pmcs_iport_t *iport)
1212 {
1213 	pmcs_hw_t	*pwp = iport->pwp;
1214 
1215 	/*
1216 	 * First, check if there are still any configured targets on this
1217 	 * iport.  If so, we fail detach.
1218 	 */
1219 	if (pmcs_iport_has_targets(pwp, iport)) {
1220 		pmcs_prt(pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL,
1221 		    "iport%d detach failure: iport has targets (luns)",
1222 		    ddi_get_instance(iport->dip));
1223 		return (DDI_FAILURE);
1224 	}
1225 
1226 	/*
1227 	 * Remove this iport from our list if it is inactive in the phymap.
1228 	 */
1229 	rw_enter(&pwp->iports_lock, RW_WRITER);
1230 	mutex_enter(&iport->lock);
1231 
1232 	if (iport->ua_state == UA_ACTIVE) {
1233 		mutex_exit(&iport->lock);
1234 		rw_exit(&pwp->iports_lock);
1235 		pmcs_prt(pwp, PMCS_PRT_DEBUG_IPORT, NULL, NULL,
1236 		    "iport%d detach failure: "
1237 		    "iport unit address active in phymap",
1238 		    ddi_get_instance(iport->dip));
1239 		return (DDI_FAILURE);
1240 	}
1241 
1242 	/* If it's our only iport, clear iports_attached */
1243 	ASSERT(pwp->num_iports >= 1);
1244 	if (--pwp->num_iports == 0) {
1245 		pwp->iports_attached = 0;
1246 	}
1247 
1248 	ASSERT(list_link_active(&iport->list_node));
1249 	list_remove(&pwp->iports, iport);
1250 	rw_exit(&pwp->iports_lock);
1251 
1252 	/*
1253 	 * We have removed the iport handle from the HBA's iports list,
1254 	 * there will be no new references to it. Two things must be
1255 	 * guarded against here.  First, we could have PHY up events,
1256 	 * adding themselves to the iport->phys list and grabbing ref's
1257 	 * on our iport handle.  Second, we could have existing references
1258 	 * to this iport handle from a point in time prior to the list
1259 	 * removal above.
1260 	 *
1261 	 * So first, destroy the phys list. Remove any phys that have snuck
1262 	 * in after the phymap deactivate, dropping the refcnt accordingly.
1263 	 * If these PHYs are still up if and when the phymap reactivates
1264 	 * (i.e. when this iport reattaches), we'll populate the list with
1265 	 * them and bump the refcnt back up.
1266 	 */
1267 	pmcs_remove_phy_from_iport(iport, NULL);
1268 	ASSERT(list_is_empty(&iport->phys));
1269 	list_destroy(&iport->phys);
1270 	mutex_exit(&iport->lock);
1271 
1272 	/*
1273 	 * Second, wait for any other references to this iport to be
1274 	 * dropped, then continue teardown.
1275 	 */
1276 	mutex_enter(&iport->refcnt_lock);
1277 	while (iport->refcnt != 0) {
1278 		cv_wait(&iport->refcnt_cv, &iport->refcnt_lock);
1279 	}
1280 	mutex_exit(&iport->refcnt_lock);
1281 
1282 	/* Delete kstats */
1283 	pmcs_destroy_phy_stats(iport);
1284 
1285 	/* Destroy the iport target map */
1286 	if (pmcs_iport_tgtmap_destroy(iport) == B_FALSE) {
1287 		return (DDI_FAILURE);
1288 	}
1289 
1290 	/* Free the tgt soft state */
1291 	if (iport->tgt_sstate != NULL) {
1292 		ddi_soft_state_bystr_fini(&iport->tgt_sstate);
1293 	}
1294 
1295 	/* Free our unit address string */
1296 	strfree(iport->ua);
1297 
1298 	/* Finish teardown and free the softstate */
1299 	mutex_destroy(&iport->refcnt_lock);
1300 	mutex_destroy(&iport->smp_lock);
1301 	ASSERT(iport->refcnt == 0);
1302 	cv_destroy(&iport->refcnt_cv);
1303 	cv_destroy(&iport->smp_cv);
1304 	mutex_destroy(&iport->lock);
1305 	ddi_soft_state_free(pmcs_iport_softstate, ddi_get_instance(iport->dip));
1306 
1307 	return (DDI_SUCCESS);
1308 }
1309 
1310 static int
1311 pmcs_unattach(pmcs_hw_t *pwp)
1312 {
1313 	int i;
1314 	enum pwpstate curstate;
1315 	pmcs_cq_thr_info_t *cqti;
1316 
1317 	/*
1318 	 * Tear down the interrupt infrastructure.
1319 	 */
1320 	if (pmcs_teardown_intr(pwp)) {
1321 		pwp->stuck = 1;
1322 	}
1323 	pwp->intr_cnt = 0;
1324 
1325 	/*
1326 	 * Grab a lock, if initted, to set state.
1327 	 */
1328 	if (pwp->locks_initted) {
1329 		mutex_enter(&pwp->lock);
1330 		if (pwp->state != STATE_DEAD) {
1331 			pwp->state = STATE_UNPROBING;
1332 		}
1333 		curstate = pwp->state;
1334 		mutex_exit(&pwp->lock);
1335 
1336 		/*
1337 		 * Stop the I/O completion threads.
1338 		 */
1339 		mutex_enter(&pwp->cq_lock);
1340 		pwp->cq_info.cq_stop = B_TRUE;
1341 		for (i = 0; i < pwp->cq_info.cq_threads; i++) {
1342 			if (pwp->cq_info.cq_thr_info[i].cq_thread) {
1343 				cqti = &pwp->cq_info.cq_thr_info[i];
1344 				mutex_enter(&cqti->cq_thr_lock);
1345 				cv_signal(&cqti->cq_cv);
1346 				mutex_exit(&cqti->cq_thr_lock);
1347 				mutex_exit(&pwp->cq_lock);
1348 				thread_join(cqti->cq_thread->t_did);
1349 				mutex_enter(&pwp->cq_lock);
1350 			}
1351 		}
1352 		mutex_exit(&pwp->cq_lock);
1353 
1354 		/*
1355 		 * Stop the interrupt coalescing timer thread
1356 		 */
1357 		if (pwp->ict_thread) {
1358 			mutex_enter(&pwp->ict_lock);
1359 			pwp->io_intr_coal.stop_thread = B_TRUE;
1360 			cv_signal(&pwp->ict_cv);
1361 			mutex_exit(&pwp->ict_lock);
1362 			thread_join(pwp->ict_thread->t_did);
1363 		}
1364 	} else {
1365 		if (pwp->state != STATE_DEAD) {
1366 			pwp->state = STATE_UNPROBING;
1367 		}
1368 		curstate = pwp->state;
1369 	}
1370 
1371 	/*
1372 	 * Make sure that any pending watchdog won't
1373 	 * be called from this point on out.
1374 	 */
1375 	(void) untimeout(pwp->wdhandle);
1376 	/*
1377 	 * After the above action, the watchdog
1378 	 * timer that starts up the worker task
1379 	 * may trigger but will exit immediately
1380 	 * on triggering.
1381 	 *
1382 	 * Now that this is done, we can destroy
1383 	 * the task queue, which will wait if we're
1384 	 * running something on it.
1385 	 */
1386 	if (pwp->tq) {
1387 		ddi_taskq_destroy(pwp->tq);
1388 		pwp->tq = NULL;
1389 	}
1390 
1391 	pmcs_fm_fini(pwp);
1392 
1393 	if (pwp->hba_attached) {
1394 		(void) scsi_hba_detach(pwp->dip);
1395 		pwp->hba_attached = 0;
1396 	}
1397 
1398 	/*
1399 	 * If the chip hasn't been marked dead, shut it down now
1400 	 * to bring it back to a known state without attempting
1401 	 * a soft reset.
1402 	 */
1403 	if (curstate != STATE_DEAD && pwp->locks_initted) {
1404 		/*
1405 		 * De-register all registered devices
1406 		 */
1407 		pmcs_deregister_devices(pwp, pwp->root_phys);
1408 
1409 		/*
1410 		 * Stop all the phys.
1411 		 */
1412 		pmcs_stop_phys(pwp);
1413 
1414 		/*
1415 		 * Shut Down Message Passing
1416 		 */
1417 		(void) pmcs_stop_mpi(pwp);
1418 
1419 		/*
1420 		 * Reset chip
1421 		 */
1422 		(void) pmcs_soft_reset(pwp, B_FALSE);
1423 		pwp->last_reset_reason = PMCS_LAST_RST_DETACH;
1424 	}
1425 
1426 	/*
1427 	 * Turn off interrupts on the chip
1428 	 */
1429 	if (pwp->mpi_acc_handle) {
1430 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, 0xffffffff);
1431 	}
1432 
1433 	if (pwp->hss_iportmap != NULL) {
1434 		/* Destroy the iportmap */
1435 		scsi_hba_iportmap_destroy(pwp->hss_iportmap);
1436 	}
1437 
1438 	if (pwp->hss_phymap != NULL) {
1439 		/* Destroy the phymap */
1440 		sas_phymap_destroy(pwp->hss_phymap);
1441 	}
1442 
1443 	/* Destroy the iports lock and list */
1444 	rw_destroy(&pwp->iports_lock);
1445 	ASSERT(list_is_empty(&pwp->iports));
1446 	list_destroy(&pwp->iports);
1447 
1448 	/* Destroy pwp's lock */
1449 	if (pwp->locks_initted) {
1450 		mutex_destroy(&pwp->lock);
1451 		mutex_destroy(&pwp->dma_lock);
1452 		mutex_destroy(&pwp->axil_lock);
1453 		mutex_destroy(&pwp->cq_lock);
1454 		mutex_destroy(&pwp->config_lock);
1455 		mutex_destroy(&pwp->ict_lock);
1456 		mutex_destroy(&pwp->wfree_lock);
1457 		mutex_destroy(&pwp->pfree_lock);
1458 		mutex_destroy(&pwp->dead_phylist_lock);
1459 #ifdef	DEBUG
1460 		mutex_destroy(&pwp->dbglock);
1461 #endif
1462 		cv_destroy(&pwp->config_cv);
1463 		cv_destroy(&pwp->ict_cv);
1464 		cv_destroy(&pwp->drain_cv);
1465 		pwp->locks_initted = 0;
1466 	}
1467 
1468 	/*
1469 	 * Free DMA handles and associated consistent memory
1470 	 */
1471 	if (pwp->regdump_hndl) {
1472 		if (ddi_dma_unbind_handle(pwp->regdump_hndl) != DDI_SUCCESS) {
1473 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1474 			    "Condition check failed "
1475 			    "at %s():%d", __func__, __LINE__);
1476 		}
1477 		ddi_dma_free_handle(&pwp->regdump_hndl);
1478 		ddi_dma_mem_free(&pwp->regdump_acchdl);
1479 		pwp->regdump_hndl = 0;
1480 	}
1481 	if (pwp->fwlog_hndl) {
1482 		if (ddi_dma_unbind_handle(pwp->fwlog_hndl) != DDI_SUCCESS) {
1483 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1484 			    "Condition check failed "
1485 			    "at %s():%d", __func__, __LINE__);
1486 		}
1487 		ddi_dma_free_handle(&pwp->fwlog_hndl);
1488 		ddi_dma_mem_free(&pwp->fwlog_acchdl);
1489 		pwp->fwlog_hndl = 0;
1490 	}
1491 	if (pwp->cip_handles) {
1492 		if (ddi_dma_unbind_handle(pwp->cip_handles) != DDI_SUCCESS) {
1493 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1494 			    "Condition check failed "
1495 			    "at %s():%d", __func__, __LINE__);
1496 		}
1497 		ddi_dma_free_handle(&pwp->cip_handles);
1498 		ddi_dma_mem_free(&pwp->cip_acchdls);
1499 		pwp->cip_handles = 0;
1500 	}
1501 	for (i = 0; i < PMCS_NOQ; i++) {
1502 		if (pwp->oqp_handles[i]) {
1503 			if (ddi_dma_unbind_handle(pwp->oqp_handles[i]) !=
1504 			    DDI_SUCCESS) {
1505 				pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1506 				    "Condition check failed at %s():%d",
1507 				    __func__, __LINE__);
1508 			}
1509 			ddi_dma_free_handle(&pwp->oqp_handles[i]);
1510 			ddi_dma_mem_free(&pwp->oqp_acchdls[i]);
1511 			pwp->oqp_handles[i] = 0;
1512 		}
1513 	}
1514 	for (i = 0; i < PMCS_NIQ; i++) {
1515 		if (pwp->iqp_handles[i]) {
1516 			if (ddi_dma_unbind_handle(pwp->iqp_handles[i]) !=
1517 			    DDI_SUCCESS) {
1518 				pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1519 				    "Condition check failed at %s():%d",
1520 				    __func__, __LINE__);
1521 			}
1522 			ddi_dma_free_handle(&pwp->iqp_handles[i]);
1523 			ddi_dma_mem_free(&pwp->iqp_acchdls[i]);
1524 			pwp->iqp_handles[i] = 0;
1525 		}
1526 	}
1527 
1528 	pmcs_free_dma_chunklist(pwp);
1529 
1530 	/*
1531 	 * Unmap registers and destroy access handles
1532 	 */
1533 	if (pwp->mpi_acc_handle) {
1534 		ddi_regs_map_free(&pwp->mpi_acc_handle);
1535 		pwp->mpi_acc_handle = 0;
1536 	}
1537 	if (pwp->top_acc_handle) {
1538 		ddi_regs_map_free(&pwp->top_acc_handle);
1539 		pwp->top_acc_handle = 0;
1540 	}
1541 	if (pwp->gsm_acc_handle) {
1542 		ddi_regs_map_free(&pwp->gsm_acc_handle);
1543 		pwp->gsm_acc_handle = 0;
1544 	}
1545 	if (pwp->msg_acc_handle) {
1546 		ddi_regs_map_free(&pwp->msg_acc_handle);
1547 		pwp->msg_acc_handle = 0;
1548 	}
1549 	if (pwp->pci_acc_handle) {
1550 		pci_config_teardown(&pwp->pci_acc_handle);
1551 		pwp->pci_acc_handle = 0;
1552 	}
1553 
1554 	/*
1555 	 * Do memory allocation cleanup.
1556 	 */
1557 	while (pwp->dma_freelist) {
1558 		pmcs_dmachunk_t *this = pwp->dma_freelist;
1559 		pwp->dma_freelist = this->nxt;
1560 		kmem_free(this, sizeof (pmcs_dmachunk_t));
1561 	}
1562 
1563 	/*
1564 	 * Free pools
1565 	 */
1566 	if (pwp->iocomp_cb_cache) {
1567 		kmem_cache_destroy(pwp->iocomp_cb_cache);
1568 	}
1569 
1570 	/*
1571 	 * Free all PHYs (at level > 0), then free the cache
1572 	 */
1573 	pmcs_free_all_phys(pwp, pwp->root_phys);
1574 	if (pwp->phy_cache) {
1575 		kmem_cache_destroy(pwp->phy_cache);
1576 	}
1577 
1578 	/*
1579 	 * Free root PHYs
1580 	 */
1581 	if (pwp->root_phys) {
1582 		pmcs_phy_t *phyp = pwp->root_phys;
1583 		for (i = 0; i < pwp->nphy; i++) {
1584 			mutex_destroy(&phyp->phy_lock);
1585 			phyp = phyp->sibling;
1586 		}
1587 		kmem_free(pwp->root_phys, pwp->nphy * sizeof (pmcs_phy_t));
1588 		pwp->root_phys = NULL;
1589 		pwp->nphy = 0;
1590 	}
1591 
1592 	/* Free the targets list */
1593 	if (pwp->targets) {
1594 		kmem_free(pwp->targets,
1595 		    sizeof (pmcs_xscsi_t *) * pwp->max_dev);
1596 	}
1597 
1598 	/*
1599 	 * Free work structures
1600 	 */
1601 
1602 	if (pwp->work && pwp->max_cmd) {
1603 		for (i = 0; i < pwp->max_cmd - 1; i++) {
1604 			pmcwork_t *pwrk = &pwp->work[i];
1605 			mutex_destroy(&pwrk->lock);
1606 			cv_destroy(&pwrk->sleep_cv);
1607 		}
1608 		kmem_free(pwp->work, sizeof (pmcwork_t) * pwp->max_cmd);
1609 		pwp->work = NULL;
1610 		pwp->max_cmd = 0;
1611 	}
1612 
1613 	/*
1614 	 * Do last property and SCSA cleanup
1615 	 */
1616 	if (pwp->tran) {
1617 		scsi_hba_tran_free(pwp->tran);
1618 		pwp->tran = NULL;
1619 	}
1620 	if (pwp->reset_notify_listf) {
1621 		scsi_hba_reset_notify_tear_down(pwp->reset_notify_listf);
1622 		pwp->reset_notify_listf = NULL;
1623 	}
1624 	ddi_prop_remove_all(pwp->dip);
1625 	if (pwp->stuck) {
1626 		return (-1);
1627 	}
1628 
1629 	/* Free register dump area if allocated */
1630 	if (pwp->regdumpp) {
1631 		kmem_free(pwp->regdumpp, PMCS_REG_DUMP_SIZE);
1632 		pwp->regdumpp = NULL;
1633 	}
1634 	if (pwp->iqpt && pwp->iqpt->head) {
1635 		kmem_free(pwp->iqpt->head, PMCS_IQP_TRACE_BUFFER_SIZE);
1636 		pwp->iqpt->head = pwp->iqpt->curpos = NULL;
1637 	}
1638 	if (pwp->iqpt) {
1639 		kmem_free(pwp->iqpt, sizeof (pmcs_iqp_trace_t));
1640 		pwp->iqpt = NULL;
1641 	}
1642 
1643 	ddi_soft_state_free(pmcs_softc_state, ddi_get_instance(pwp->dip));
1644 	return (0);
1645 }
1646 
1647 /*
1648  * quiesce (9E) entry point
1649  *
1650  * This function is called when the system is single-threaded at high PIL
1651  * with preemption disabled. Therefore, the function must not block/wait/sleep.
1652  *
1653  * Returns DDI_SUCCESS or DDI_FAILURE.
1654  *
1655  */
1656 static int
1657 pmcs_quiesce(dev_info_t *dip)
1658 {
1659 	pmcs_hw_t	*pwp;
1660 	scsi_hba_tran_t	*tran;
1661 
1662 	if ((tran = ddi_get_driver_private(dip)) == NULL)
1663 		return (DDI_SUCCESS);
1664 
1665 	/* No quiesce necessary on a per-iport basis */
1666 	if (scsi_hba_iport_unit_address(dip) != NULL) {
1667 		return (DDI_SUCCESS);
1668 	}
1669 
1670 	if ((pwp = TRAN2PMC(tran)) == NULL)
1671 		return (DDI_SUCCESS);
1672 
1673 	/* Stop MPI & Reset chip (no need to re-initialize) */
1674 	(void) pmcs_stop_mpi(pwp);
1675 	(void) pmcs_soft_reset(pwp, B_TRUE);
1676 	pwp->last_reset_reason = PMCS_LAST_RST_QUIESCE;
1677 
1678 	return (DDI_SUCCESS);
1679 }
1680 
1681 /*
1682  * Called with xp->statlock and PHY lock and scratch acquired.
1683  */
1684 static int
1685 pmcs_add_sata_device(pmcs_hw_t *pwp, pmcs_xscsi_t *xp)
1686 {
1687 	ata_identify_t *ati;
1688 	int result, i;
1689 	pmcs_phy_t *pptr;
1690 	uint16_t *a;
1691 	union {
1692 		uint8_t nsa[8];
1693 		uint16_t nsb[4];
1694 	} u;
1695 
1696 	/*
1697 	 * Safe defaults - use only if this target is brand new (i.e. doesn't
1698 	 * already have these settings configured)
1699 	 */
1700 	if (xp->capacity == 0) {
1701 		xp->capacity = (uint64_t)-1;
1702 		xp->ca = 1;
1703 		xp->qdepth = 1;
1704 		xp->pio = 1;
1705 	}
1706 
1707 	pptr = xp->phy;
1708 
1709 	/*
1710 	 * We only try and issue an IDENTIFY for first level
1711 	 * (direct attached) devices. We don't try and
1712 	 * set other quirks here (this will happen later,
1713 	 * if the device is fully configured)
1714 	 */
1715 	if (pptr->level) {
1716 		return (0);
1717 	}
1718 
1719 	mutex_exit(&xp->statlock);
1720 	result = pmcs_sata_identify(pwp, pptr);
1721 	mutex_enter(&xp->statlock);
1722 
1723 	if (result) {
1724 		return (result);
1725 	}
1726 	ati = pwp->scratch;
1727 	a = &ati->word108;
1728 	for (i = 0; i < 4; i++) {
1729 		u.nsb[i] = ddi_swap16(*a++);
1730 	}
1731 
1732 	/*
1733 	 * Check the returned data for being a valid (NAA=5) WWN.
1734 	 * If so, use that and override the SAS address we were
1735 	 * given at Link Up time.
1736 	 */
1737 	if ((u.nsa[0] >> 4) == 5) {
1738 		(void) memcpy(pptr->sas_address, u.nsa, 8);
1739 	}
1740 	pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
1741 	    "%s: %s has SAS ADDRESS " SAS_ADDR_FMT,
1742 	    __func__, pptr->path, SAS_ADDR_PRT(pptr->sas_address));
1743 	return (0);
1744 }
1745 
1746 /*
1747  * Called with PHY lock and target statlock held and scratch acquired
1748  */
1749 static boolean_t
1750 pmcs_add_new_device(pmcs_hw_t *pwp, pmcs_xscsi_t *target)
1751 {
1752 	ASSERT(target != NULL);
1753 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, target, "%s: target = 0x%p",
1754 	    __func__, (void *) target);
1755 
1756 	switch (target->phy->dtype) {
1757 	case SATA:
1758 		if (pmcs_add_sata_device(pwp, target) != 0) {
1759 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, target->phy,
1760 			    target, "%s: add_sata_device failed for tgt 0x%p",
1761 			    __func__, (void *) target);
1762 			return (B_FALSE);
1763 		}
1764 		break;
1765 	case SAS:
1766 		target->qdepth = maxqdepth;
1767 		break;
1768 	case EXPANDER:
1769 		target->qdepth = 1;
1770 		break;
1771 	}
1772 
1773 	target->new = 0;
1774 	target->assigned = 1;
1775 	target->dev_state = PMCS_DEVICE_STATE_OPERATIONAL;
1776 	target->dtype = target->phy->dtype;
1777 
1778 	/*
1779 	 * Set the PHY's config stop time to 0.  This is one of the final
1780 	 * stops along the config path, so we're indicating that we
1781 	 * successfully configured the PHY.
1782 	 */
1783 	target->phy->config_stop = 0;
1784 
1785 	return (B_TRUE);
1786 }
1787 
1788 void
1789 pmcs_worker(void *arg)
1790 {
1791 	pmcs_hw_t *pwp = arg;
1792 	ulong_t work_flags;
1793 
1794 	DTRACE_PROBE2(pmcs__worker, ulong_t, pwp->work_flags, boolean_t,
1795 	    pwp->config_changed);
1796 
1797 	if (pwp->state != STATE_RUNNING) {
1798 		return;
1799 	}
1800 
1801 	work_flags = atomic_swap_ulong(&pwp->work_flags, 0);
1802 
1803 	if (work_flags & PMCS_WORK_FLAG_DUMP_REGS) {
1804 		mutex_enter(&pwp->lock);
1805 		pmcs_register_dump_int(pwp);
1806 		mutex_exit(&pwp->lock);
1807 	}
1808 
1809 	if (work_flags & PMCS_WORK_FLAG_SAS_HW_ACK) {
1810 		pmcs_ack_events(pwp);
1811 	}
1812 
1813 	if (work_flags & PMCS_WORK_FLAG_SPINUP_RELEASE) {
1814 		mutex_enter(&pwp->lock);
1815 		pmcs_spinup_release(pwp, NULL);
1816 		mutex_exit(&pwp->lock);
1817 	}
1818 
1819 	if (work_flags & PMCS_WORK_FLAG_SSP_EVT_RECOVERY) {
1820 		pmcs_ssp_event_recovery(pwp);
1821 	}
1822 
1823 	if (work_flags & PMCS_WORK_FLAG_DS_ERR_RECOVERY) {
1824 		pmcs_dev_state_recovery(pwp, NULL);
1825 	}
1826 
1827 	if (work_flags & PMCS_WORK_FLAG_DEREGISTER_DEV) {
1828 		pmcs_deregister_device_work(pwp, NULL);
1829 	}
1830 
1831 	if (work_flags & PMCS_WORK_FLAG_DISCOVER) {
1832 		pmcs_discover(pwp);
1833 	}
1834 
1835 	if (work_flags & PMCS_WORK_FLAG_ABORT_HANDLE) {
1836 		if (pmcs_abort_handler(pwp)) {
1837 			SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE);
1838 		}
1839 	}
1840 
1841 	if (work_flags & PMCS_WORK_FLAG_SATA_RUN) {
1842 		pmcs_sata_work(pwp);
1843 	}
1844 
1845 	if (work_flags & PMCS_WORK_FLAG_RUN_QUEUES) {
1846 		pmcs_scsa_wq_run(pwp);
1847 		mutex_enter(&pwp->lock);
1848 		PMCS_CQ_RUN(pwp);
1849 		mutex_exit(&pwp->lock);
1850 	}
1851 
1852 	if (work_flags & PMCS_WORK_FLAG_ADD_DMA_CHUNKS) {
1853 		if (pmcs_add_more_chunks(pwp,
1854 		    ptob(1) * PMCS_ADDTL_CHUNK_PAGES)) {
1855 			SCHEDULE_WORK(pwp, PMCS_WORK_ADD_DMA_CHUNKS);
1856 		} else {
1857 			SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
1858 		}
1859 	}
1860 }
1861 
1862 static int
1863 pmcs_add_more_chunks(pmcs_hw_t *pwp, unsigned long nsize)
1864 {
1865 	pmcs_dmachunk_t *dc;
1866 	unsigned long dl;
1867 	pmcs_chunk_t	*pchunk = NULL;
1868 
1869 	pwp->cip_dma_attr.dma_attr_align = sizeof (uint32_t);
1870 
1871 	pchunk = kmem_zalloc(sizeof (pmcs_chunk_t), KM_SLEEP);
1872 	if (pchunk == NULL) {
1873 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1874 		    "Not enough memory for DMA chunks");
1875 		return (-1);
1876 	}
1877 
1878 	if (pmcs_dma_setup(pwp, &pwp->cip_dma_attr, &pchunk->acc_handle,
1879 	    &pchunk->dma_handle, nsize, (caddr_t *)&pchunk->addrp,
1880 	    &pchunk->dma_addr) == B_FALSE) {
1881 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1882 		    "Failed to setup DMA for chunks");
1883 		kmem_free(pchunk, sizeof (pmcs_chunk_t));
1884 		return (-1);
1885 	}
1886 
1887 	if ((pmcs_check_acc_handle(pchunk->acc_handle) != DDI_SUCCESS) ||
1888 	    (pmcs_check_dma_handle(pchunk->dma_handle) != DDI_SUCCESS)) {
1889 		ddi_fm_service_impact(pwp->dip, DDI_SERVICE_UNAFFECTED);
1890 		return (-1);
1891 	}
1892 
1893 	bzero(pchunk->addrp, nsize);
1894 	dc = NULL;
1895 	for (dl = 0; dl < (nsize / PMCS_SGL_CHUNKSZ); dl++) {
1896 		pmcs_dmachunk_t *tmp;
1897 		tmp = kmem_alloc(sizeof (pmcs_dmachunk_t), KM_SLEEP);
1898 		tmp->nxt = dc;
1899 		dc = tmp;
1900 	}
1901 	mutex_enter(&pwp->dma_lock);
1902 	pmcs_idma_chunks(pwp, dc, pchunk, nsize);
1903 	pwp->nchunks++;
1904 	mutex_exit(&pwp->dma_lock);
1905 	return (0);
1906 }
1907 
1908 static void
1909 pmcs_check_forward_progress(pmcs_hw_t *pwp)
1910 {
1911 	pmcwork_t	*wrkp;
1912 	uint32_t	*iqp;
1913 	uint32_t	cur_iqci;
1914 	uint32_t	cur_work_idx;
1915 	uint32_t	cur_msgu_tick;
1916 	uint32_t	cur_iop_tick;
1917 	int 		i;
1918 
1919 	mutex_enter(&pwp->lock);
1920 
1921 	if (pwp->state == STATE_IN_RESET) {
1922 		mutex_exit(&pwp->lock);
1923 		return;
1924 	}
1925 
1926 	/*
1927 	 * Ensure that inbound work is getting picked up.  First, check to
1928 	 * see if new work has been posted.  If it has, ensure that the
1929 	 * work is moving forward by checking the consumer index and the
1930 	 * last_htag for the work being processed against what we saw last
1931 	 * time.  Note: we use the work structure's 'last_htag' because at
1932 	 * any given moment it could be freed back, thus clearing 'htag'
1933 	 * and setting 'last_htag' (see pmcs_pwork).
1934 	 */
1935 	for (i = 0; i < PMCS_NIQ; i++) {
1936 		cur_iqci = pmcs_rd_iqci(pwp, i);
1937 		iqp = &pwp->iqp[i][cur_iqci * (PMCS_QENTRY_SIZE >> 2)];
1938 		cur_work_idx = PMCS_TAG_INDEX(LE_32(*(iqp+1)));
1939 		wrkp = &pwp->work[cur_work_idx];
1940 		if (cur_iqci == pwp->shadow_iqpi[i]) {
1941 			pwp->last_iqci[i] = cur_iqci;
1942 			pwp->last_htag[i] = wrkp->last_htag;
1943 			continue;
1944 		}
1945 		if ((cur_iqci == pwp->last_iqci[i]) &&
1946 		    (wrkp->last_htag == pwp->last_htag[i])) {
1947 			pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
1948 			    "Inbound Queue stall detected, issuing reset");
1949 			goto hot_reset;
1950 		}
1951 		pwp->last_iqci[i] = cur_iqci;
1952 		pwp->last_htag[i] = wrkp->last_htag;
1953 	}
1954 
1955 	/*
1956 	 * Check heartbeat on both the MSGU and IOP.  It is unlikely that
1957 	 * we'd ever fail here, as the inbound queue monitoring code above
1958 	 * would detect a stall due to either of these elements being
1959 	 * stalled, but we might as well keep an eye on them.
1960 	 */
1961 	cur_msgu_tick = pmcs_rd_gst_tbl(pwp, PMCS_GST_MSGU_TICK);
1962 	if (cur_msgu_tick == pwp->last_msgu_tick) {
1963 		pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
1964 		    "Stall detected on MSGU, issuing reset");
1965 		goto hot_reset;
1966 	}
1967 	pwp->last_msgu_tick = cur_msgu_tick;
1968 
1969 	cur_iop_tick  = pmcs_rd_gst_tbl(pwp, PMCS_GST_IOP_TICK);
1970 	if (cur_iop_tick == pwp->last_iop_tick) {
1971 		pmcs_prt(pwp, PMCS_PRT_WARN, NULL, NULL,
1972 		    "Stall detected on IOP, issuing reset");
1973 		goto hot_reset;
1974 	}
1975 	pwp->last_iop_tick = cur_iop_tick;
1976 
1977 	mutex_exit(&pwp->lock);
1978 	return;
1979 
1980 hot_reset:
1981 	pwp->state = STATE_DEAD;
1982 	/*
1983 	 * We've detected a stall. Attempt to recover service via hot
1984 	 * reset. In case of failure, pmcs_hot_reset() will handle the
1985 	 * failure and issue any required FM notifications.
1986 	 * See pmcs_subr.c for more details.
1987 	 */
1988 	if (pmcs_hot_reset(pwp)) {
1989 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
1990 		    "%s: hot reset failure", __func__);
1991 	} else {
1992 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
1993 		    "%s: hot reset complete", __func__);
1994 		pwp->last_reset_reason = PMCS_LAST_RST_STALL;
1995 	}
1996 	mutex_exit(&pwp->lock);
1997 }
1998 
1999 static void
2000 pmcs_check_commands(pmcs_hw_t *pwp)
2001 {
2002 	pmcs_cmd_t *sp;
2003 	size_t amt;
2004 	char path[32];
2005 	pmcwork_t *pwrk;
2006 	pmcs_xscsi_t *target;
2007 	pmcs_phy_t *phyp;
2008 	int rval;
2009 
2010 	for (pwrk = pwp->work; pwrk < &pwp->work[pwp->max_cmd]; pwrk++) {
2011 		mutex_enter(&pwrk->lock);
2012 
2013 		/*
2014 		 * If the command isn't active, we can't be timing it still.
2015 		 * Active means the tag is not free and the state is "on chip".
2016 		 */
2017 		if (!PMCS_COMMAND_ACTIVE(pwrk)) {
2018 			mutex_exit(&pwrk->lock);
2019 			continue;
2020 		}
2021 
2022 		/*
2023 		 * No timer active for this command.
2024 		 */
2025 		if (pwrk->timer == 0) {
2026 			mutex_exit(&pwrk->lock);
2027 			continue;
2028 		}
2029 
2030 		/*
2031 		 * Knock off bits for the time interval.
2032 		 */
2033 		if (pwrk->timer >= US2WT(PMCS_WATCH_INTERVAL)) {
2034 			pwrk->timer -= US2WT(PMCS_WATCH_INTERVAL);
2035 		} else {
2036 			pwrk->timer = 0;
2037 		}
2038 		if (pwrk->timer > 0) {
2039 			mutex_exit(&pwrk->lock);
2040 			continue;
2041 		}
2042 
2043 		/*
2044 		 * The command has now officially timed out.
2045 		 * Get the path for it. If it doesn't have
2046 		 * a phy pointer any more, it's really dead
2047 		 * and can just be put back on the free list.
2048 		 * There should *not* be any commands associated
2049 		 * with it any more.
2050 		 */
2051 		if (pwrk->phy == NULL) {
2052 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2053 			    "dead command with gone phy being recycled");
2054 			ASSERT(pwrk->xp == NULL);
2055 			pmcs_pwork(pwp, pwrk);
2056 			continue;
2057 		}
2058 		amt = sizeof (path);
2059 		amt = min(sizeof (pwrk->phy->path), amt);
2060 		(void) memcpy(path, pwrk->phy->path, amt);
2061 
2062 		/*
2063 		 * If this is a non-SCSA command, stop here. Eventually
2064 		 * we might do something with non-SCSA commands here-
2065 		 * but so far their timeout mechanisms are handled in
2066 		 * the WAIT_FOR macro.
2067 		 */
2068 		if (pwrk->xp == NULL) {
2069 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2070 			    "%s: non-SCSA cmd tag 0x%x timed out",
2071 			    path, pwrk->htag);
2072 			mutex_exit(&pwrk->lock);
2073 			continue;
2074 		}
2075 
2076 		sp = pwrk->arg;
2077 		ASSERT(sp != NULL);
2078 
2079 		/*
2080 		 * Mark it as timed out.
2081 		 */
2082 		CMD2PKT(sp)->pkt_reason = CMD_TIMEOUT;
2083 		CMD2PKT(sp)->pkt_statistics |= STAT_TIMEOUT;
2084 #ifdef	DEBUG
2085 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pwrk->phy, pwrk->xp,
2086 		    "%s: SCSA cmd tag 0x%x timed out (state %x) onwire=%d",
2087 		    path, pwrk->htag, pwrk->state, pwrk->onwire);
2088 #else
2089 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pwrk->phy, pwrk->xp,
2090 		    "%s: SCSA cmd tag 0x%x timed out (state %x)",
2091 		    path, pwrk->htag, pwrk->state);
2092 #endif
2093 		/*
2094 		 * Mark the work structure as timed out.
2095 		 */
2096 		pwrk->state = PMCS_WORK_STATE_TIMED_OUT;
2097 		phyp = pwrk->phy;
2098 		target = pwrk->xp;
2099 		mutex_exit(&pwrk->lock);
2100 
2101 		pmcs_lock_phy(phyp);
2102 		mutex_enter(&target->statlock);
2103 
2104 		/*
2105 		 * No point attempting recovery if the device is gone
2106 		 */
2107 		if (target->dev_gone) {
2108 			mutex_exit(&target->statlock);
2109 			pmcs_unlock_phy(phyp);
2110 			pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, target,
2111 			    "%s: tgt(0x%p) is gone. Returning CMD_DEV_GONE "
2112 			    "for htag 0x%08x", __func__,
2113 			    (void *)target, pwrk->htag);
2114 			mutex_enter(&pwrk->lock);
2115 			if (!PMCS_COMMAND_DONE(pwrk)) {
2116 				/* Complete this command here */
2117 				pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, target,
2118 				    "%s: Completing cmd (htag 0x%08x) "
2119 				    "anyway", __func__, pwrk->htag);
2120 				pwrk->dead = 1;
2121 				CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE;
2122 				CMD2PKT(sp)->pkt_state = STATE_GOT_BUS;
2123 				pmcs_complete_work_impl(pwp, pwrk, NULL, 0);
2124 			} else {
2125 				mutex_exit(&pwrk->lock);
2126 			}
2127 			continue;
2128 		}
2129 
2130 		mutex_exit(&target->statlock);
2131 		rval = pmcs_abort(pwp, phyp, pwrk->htag, 0, 1);
2132 		if (rval) {
2133 			pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, target,
2134 			    "%s: Bad status (%d) on abort of HTAG 0x%08x",
2135 			    __func__, rval, pwrk->htag);
2136 			pmcs_unlock_phy(phyp);
2137 			mutex_enter(&pwrk->lock);
2138 			if (!PMCS_COMMAND_DONE(pwrk)) {
2139 				/* Complete this command here */
2140 				pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, target,
2141 				    "%s: Completing cmd (htag 0x%08x) "
2142 				    "anyway", __func__, pwrk->htag);
2143 				if (target->dev_gone) {
2144 					pwrk->dead = 1;
2145 					CMD2PKT(sp)->pkt_reason = CMD_DEV_GONE;
2146 					CMD2PKT(sp)->pkt_state = STATE_GOT_BUS;
2147 				}
2148 				pmcs_complete_work_impl(pwp, pwrk, NULL, 0);
2149 			} else {
2150 				mutex_exit(&pwrk->lock);
2151 			}
2152 			pmcs_lock_phy(phyp);
2153 			/*
2154 			 * No need to reschedule ABORT if we get any other
2155 			 * status
2156 			 */
2157 			if (rval == ENOMEM) {
2158 				phyp->abort_sent = 0;
2159 				phyp->abort_pending = 1;
2160 				SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE);
2161 			}
2162 		}
2163 		pmcs_unlock_phy(phyp);
2164 	}
2165 	/*
2166 	 * Run any completions that may have been queued up.
2167 	 */
2168 	PMCS_CQ_RUN(pwp);
2169 }
2170 
2171 static void
2172 pmcs_watchdog(void *arg)
2173 {
2174 	pmcs_hw_t *pwp = arg;
2175 
2176 	DTRACE_PROBE2(pmcs__watchdog, ulong_t, pwp->work_flags, boolean_t,
2177 	    pwp->config_changed);
2178 
2179 	/*
2180 	 * Check forward progress on the chip
2181 	 */
2182 	if (++pwp->watchdog_count == PMCS_FWD_PROG_TRIGGER) {
2183 		pwp->watchdog_count = 0;
2184 		pmcs_check_forward_progress(pwp);
2185 	}
2186 
2187 	/*
2188 	 * Check to see if we need to kick discovery off again
2189 	 */
2190 	mutex_enter(&pwp->config_lock);
2191 	if (pwp->config_restart &&
2192 	    (ddi_get_lbolt() >= pwp->config_restart_time)) {
2193 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
2194 		    "%s: Timer expired for re-enumeration: Start discovery",
2195 		    __func__);
2196 		pwp->config_restart = B_FALSE;
2197 		SCHEDULE_WORK(pwp, PMCS_WORK_DISCOVER);
2198 	}
2199 	mutex_exit(&pwp->config_lock);
2200 
2201 	mutex_enter(&pwp->lock);
2202 	if (pwp->state != STATE_RUNNING) {
2203 		mutex_exit(&pwp->lock);
2204 		return;
2205 	}
2206 
2207 	if (atomic_cas_ulong(&pwp->work_flags, 0, 0) != 0) {
2208 		if (ddi_taskq_dispatch(pwp->tq, pmcs_worker, pwp,
2209 		    DDI_NOSLEEP) != DDI_SUCCESS) {
2210 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2211 			    "Could not dispatch to worker thread");
2212 		}
2213 	}
2214 	pwp->wdhandle = timeout(pmcs_watchdog, pwp,
2215 	    drv_usectohz(PMCS_WATCH_INTERVAL));
2216 
2217 	mutex_exit(&pwp->lock);
2218 
2219 	pmcs_check_commands(pwp);
2220 	pmcs_handle_dead_phys(pwp);
2221 }
2222 
2223 static int
2224 pmcs_remove_ihandlers(pmcs_hw_t *pwp, int icnt)
2225 {
2226 	int i, r, rslt = 0;
2227 	for (i = 0; i < icnt; i++) {
2228 		r = ddi_intr_remove_handler(pwp->ih_table[i]);
2229 		if (r == DDI_SUCCESS) {
2230 			continue;
2231 		}
2232 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2233 		    "%s: unable to remove interrupt handler %d", __func__, i);
2234 		rslt = -1;
2235 		break;
2236 	}
2237 	return (rslt);
2238 }
2239 
2240 static int
2241 pmcs_disable_intrs(pmcs_hw_t *pwp, int icnt)
2242 {
2243 	if (pwp->intr_cap & DDI_INTR_FLAG_BLOCK) {
2244 		int r = ddi_intr_block_disable(&pwp->ih_table[0],
2245 		    pwp->intr_cnt);
2246 		if (r != DDI_SUCCESS) {
2247 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2248 			    "unable to disable interrupt block");
2249 			return (-1);
2250 		}
2251 	} else {
2252 		int i;
2253 		for (i = 0; i < icnt; i++) {
2254 			if (ddi_intr_disable(pwp->ih_table[i]) == DDI_SUCCESS) {
2255 				continue;
2256 			}
2257 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2258 			    "unable to disable interrupt %d", i);
2259 			return (-1);
2260 		}
2261 	}
2262 	return (0);
2263 }
2264 
2265 static int
2266 pmcs_free_intrs(pmcs_hw_t *pwp, int icnt)
2267 {
2268 	int i;
2269 	for (i = 0; i < icnt; i++) {
2270 		if (ddi_intr_free(pwp->ih_table[i]) == DDI_SUCCESS) {
2271 			continue;
2272 		}
2273 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2274 		    "unable to free interrupt %d", i);
2275 		return (-1);
2276 	}
2277 	kmem_free(pwp->ih_table, pwp->ih_table_size);
2278 	pwp->ih_table_size = 0;
2279 	return (0);
2280 }
2281 
2282 /*
2283  * Try to set up interrupts of type "type" with a minimum number of interrupts
2284  * of "min".
2285  */
2286 static void
2287 pmcs_setup_intr_impl(pmcs_hw_t *pwp, int type, int min)
2288 {
2289 	int rval, avail, count, actual, max;
2290 
2291 	rval = ddi_intr_get_nintrs(pwp->dip, type, &count);
2292 	if ((rval != DDI_SUCCESS) || (count < min)) {
2293 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
2294 		    "%s: get_nintrs failed; type: %d rc: %d count: %d min: %d",
2295 		    __func__, type, rval, count, min);
2296 		return;
2297 	}
2298 
2299 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
2300 	    "%s: nintrs = %d for type: %d", __func__, count, type);
2301 
2302 	rval = ddi_intr_get_navail(pwp->dip, type, &avail);
2303 	if ((rval != DDI_SUCCESS) || (avail < min)) {
2304 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
2305 		    "%s: get_navail failed; type: %d rc: %d avail: %d min: %d",
2306 		    __func__, type, rval, avail, min);
2307 		return;
2308 	}
2309 
2310 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
2311 	    "%s: navail = %d for type: %d", __func__, avail, type);
2312 
2313 	pwp->ih_table_size = avail * sizeof (ddi_intr_handle_t);
2314 	pwp->ih_table = kmem_alloc(pwp->ih_table_size, KM_SLEEP);
2315 
2316 	switch (type) {
2317 	case DDI_INTR_TYPE_MSIX:
2318 		pwp->int_type = PMCS_INT_MSIX;
2319 		max = PMCS_MAX_MSIX;
2320 		break;
2321 	case DDI_INTR_TYPE_MSI:
2322 		pwp->int_type = PMCS_INT_MSI;
2323 		max = PMCS_MAX_MSI;
2324 		break;
2325 	case DDI_INTR_TYPE_FIXED:
2326 	default:
2327 		pwp->int_type = PMCS_INT_FIXED;
2328 		max = PMCS_MAX_FIXED;
2329 		break;
2330 	}
2331 
2332 	rval = ddi_intr_alloc(pwp->dip, pwp->ih_table, type, 0, max, &actual,
2333 	    DDI_INTR_ALLOC_NORMAL);
2334 	if (rval != DDI_SUCCESS) {
2335 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
2336 		    "%s: ddi_intr_alloc failed; type: %d rc: %d",
2337 		    __func__, type, rval);
2338 		kmem_free(pwp->ih_table, pwp->ih_table_size);
2339 		pwp->ih_table = NULL;
2340 		pwp->ih_table_size = 0;
2341 		pwp->intr_cnt = 0;
2342 		pwp->int_type = PMCS_INT_NONE;
2343 		return;
2344 	}
2345 
2346 	pwp->intr_cnt = actual;
2347 }
2348 
2349 /*
2350  * Set up interrupts.
2351  * We return one of three values:
2352  *
2353  * 0 - success
2354  * EAGAIN - failure to set up interrupts
2355  * EIO - "" + we're now stuck partly enabled
2356  *
2357  * If EIO is returned, we can't unload the driver.
2358  */
2359 static int
2360 pmcs_setup_intr(pmcs_hw_t *pwp)
2361 {
2362 	int i, r, itypes, oqv_count;
2363 	ddi_intr_handler_t **iv_table;
2364 	size_t iv_table_size;
2365 	uint_t pri;
2366 
2367 	if (ddi_intr_get_supported_types(pwp->dip, &itypes) != DDI_SUCCESS) {
2368 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2369 		    "cannot get interrupt types");
2370 		return (EAGAIN);
2371 	}
2372 
2373 	if (disable_msix) {
2374 		itypes &= ~DDI_INTR_TYPE_MSIX;
2375 	}
2376 	if (disable_msi) {
2377 		itypes &= ~DDI_INTR_TYPE_MSI;
2378 	}
2379 
2380 	/*
2381 	 * We won't know what firmware we're running until we call pmcs_setup,
2382 	 * and we can't call pmcs_setup until we establish interrupts.
2383 	 */
2384 
2385 	pwp->int_type = PMCS_INT_NONE;
2386 
2387 	/*
2388 	 * We want PMCS_MAX_MSIX vectors for MSI-X.  Anything less would be
2389 	 * uncivilized.
2390 	 */
2391 	if (itypes & DDI_INTR_TYPE_MSIX) {
2392 		pmcs_setup_intr_impl(pwp, DDI_INTR_TYPE_MSIX, PMCS_MAX_MSIX);
2393 		if (pwp->int_type == PMCS_INT_MSIX) {
2394 			itypes = 0;
2395 		}
2396 	}
2397 
2398 	if (itypes & DDI_INTR_TYPE_MSI) {
2399 		pmcs_setup_intr_impl(pwp, DDI_INTR_TYPE_MSI, 1);
2400 		if (pwp->int_type == PMCS_INT_MSI) {
2401 			itypes = 0;
2402 		}
2403 	}
2404 
2405 	if (itypes & DDI_INTR_TYPE_FIXED) {
2406 		pmcs_setup_intr_impl(pwp, DDI_INTR_TYPE_FIXED, 1);
2407 		if (pwp->int_type == PMCS_INT_FIXED) {
2408 			itypes = 0;
2409 		}
2410 	}
2411 
2412 	if (pwp->intr_cnt == 0) {
2413 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
2414 		    "No interrupts available");
2415 		return (EAGAIN);
2416 	}
2417 
2418 	iv_table_size = sizeof (ddi_intr_handler_t *) * pwp->intr_cnt;
2419 	iv_table = kmem_alloc(iv_table_size, KM_SLEEP);
2420 
2421 	/*
2422 	 * Get iblock cookie and add handlers.
2423 	 */
2424 	switch (pwp->intr_cnt) {
2425 	case 1:
2426 		iv_table[0] = pmcs_all_intr;
2427 		break;
2428 	case 2:
2429 		iv_table[0] = pmcs_iodone_ix;
2430 		iv_table[1] = pmcs_nonio_ix;
2431 		break;
2432 	case 4:
2433 		iv_table[PMCS_MSIX_GENERAL] = pmcs_general_ix;
2434 		iv_table[PMCS_MSIX_IODONE] = pmcs_iodone_ix;
2435 		iv_table[PMCS_MSIX_EVENTS] = pmcs_event_ix;
2436 		iv_table[PMCS_MSIX_FATAL] = pmcs_fatal_ix;
2437 		break;
2438 	default:
2439 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2440 		    "%s: intr_cnt = %d - unexpected", __func__, pwp->intr_cnt);
2441 		kmem_free(iv_table, iv_table_size);
2442 		return (EAGAIN);
2443 	}
2444 
2445 	for (i = 0; i < pwp->intr_cnt; i++) {
2446 		r = ddi_intr_add_handler(pwp->ih_table[i], iv_table[i],
2447 		    (caddr_t)pwp, NULL);
2448 		if (r != DDI_SUCCESS) {
2449 			kmem_free(iv_table, iv_table_size);
2450 			if (pmcs_remove_ihandlers(pwp, i)) {
2451 				return (EIO);
2452 			}
2453 			if (pmcs_free_intrs(pwp, i)) {
2454 				return (EIO);
2455 			}
2456 			pwp->intr_cnt = 0;
2457 			return (EAGAIN);
2458 		}
2459 	}
2460 
2461 	kmem_free(iv_table, iv_table_size);
2462 
2463 	if (ddi_intr_get_cap(pwp->ih_table[0], &pwp->intr_cap) != DDI_SUCCESS) {
2464 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2465 		    "unable to get int capabilities");
2466 		if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) {
2467 			return (EIO);
2468 		}
2469 		if (pmcs_free_intrs(pwp, pwp->intr_cnt)) {
2470 			return (EIO);
2471 		}
2472 		pwp->intr_cnt = 0;
2473 		return (EAGAIN);
2474 	}
2475 
2476 	if (pwp->intr_cap & DDI_INTR_FLAG_BLOCK) {
2477 		r = ddi_intr_block_enable(&pwp->ih_table[0], pwp->intr_cnt);
2478 		if (r != DDI_SUCCESS) {
2479 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2480 			    "intr blk enable failed");
2481 			if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) {
2482 				return (EIO);
2483 			}
2484 			if (pmcs_free_intrs(pwp, pwp->intr_cnt)) {
2485 				return (EIO);
2486 			}
2487 			pwp->intr_cnt = 0;
2488 			return (EFAULT);
2489 		}
2490 	} else {
2491 		for (i = 0; i < pwp->intr_cnt; i++) {
2492 			r = ddi_intr_enable(pwp->ih_table[i]);
2493 			if (r == DDI_SUCCESS) {
2494 				continue;
2495 			}
2496 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2497 			    "unable to enable interrupt %d", i);
2498 			if (pmcs_disable_intrs(pwp, i)) {
2499 				return (EIO);
2500 			}
2501 			if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) {
2502 				return (EIO);
2503 			}
2504 			if (pmcs_free_intrs(pwp, pwp->intr_cnt)) {
2505 				return (EIO);
2506 			}
2507 			pwp->intr_cnt = 0;
2508 			return (EAGAIN);
2509 		}
2510 	}
2511 
2512 	/*
2513 	 * Set up locks.
2514 	 */
2515 	if (ddi_intr_get_pri(pwp->ih_table[0], &pri) != DDI_SUCCESS) {
2516 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2517 		    "unable to get interrupt priority");
2518 		if (pmcs_disable_intrs(pwp, pwp->intr_cnt)) {
2519 			return (EIO);
2520 		}
2521 		if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) {
2522 			return (EIO);
2523 		}
2524 		if (pmcs_free_intrs(pwp, pwp->intr_cnt)) {
2525 			return (EIO);
2526 		}
2527 		pwp->intr_cnt = 0;
2528 		return (EAGAIN);
2529 	}
2530 
2531 	pwp->locks_initted = 1;
2532 	pwp->intr_pri = pri;
2533 	mutex_init(&pwp->lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2534 	mutex_init(&pwp->dma_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2535 	mutex_init(&pwp->axil_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2536 	mutex_init(&pwp->cq_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2537 	mutex_init(&pwp->ict_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2538 	mutex_init(&pwp->config_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2539 	mutex_init(&pwp->wfree_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2540 	mutex_init(&pwp->pfree_lock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2541 	mutex_init(&pwp->dead_phylist_lock, NULL, MUTEX_DRIVER,
2542 	    DDI_INTR_PRI(pri));
2543 #ifdef	DEBUG
2544 	mutex_init(&pwp->dbglock, NULL, MUTEX_DRIVER, DDI_INTR_PRI(pri));
2545 #endif
2546 	cv_init(&pwp->ict_cv, NULL, CV_DRIVER, NULL);
2547 	cv_init(&pwp->drain_cv, NULL, CV_DRIVER, NULL);
2548 	cv_init(&pwp->config_cv, NULL, CV_DRIVER, NULL);
2549 	for (i = 0; i < PMCS_NIQ; i++) {
2550 		mutex_init(&pwp->iqp_lock[i], NULL,
2551 		    MUTEX_DRIVER, DDI_INTR_PRI(pwp->intr_pri));
2552 	}
2553 	for (i = 0; i < pwp->cq_info.cq_threads; i++) {
2554 		mutex_init(&pwp->cq_info.cq_thr_info[i].cq_thr_lock, NULL,
2555 		    MUTEX_DRIVER, DDI_INTR_PRI(pwp->intr_pri));
2556 		cv_init(&pwp->cq_info.cq_thr_info[i].cq_cv, NULL,
2557 		    CV_DRIVER, NULL);
2558 	}
2559 
2560 	pmcs_prt(pwp, PMCS_PRT_INFO, NULL, NULL, "%d %s interrup%s configured",
2561 	    pwp->intr_cnt, (pwp->int_type == PMCS_INT_MSIX)? "MSI-X" :
2562 	    ((pwp->int_type == PMCS_INT_MSI)? "MSI" : "INT-X"),
2563 	    pwp->intr_cnt == 1? "t" : "ts");
2564 
2565 
2566 	/*
2567 	 * Enable Interrupts
2568 	 */
2569 	if (pwp->intr_cnt > PMCS_NOQ) {
2570 		oqv_count = pwp->intr_cnt;
2571 	} else {
2572 		oqv_count = PMCS_NOQ;
2573 	}
2574 	for (pri = 0xffffffff, i = 0; i < oqv_count; i++) {
2575 		pri ^= (1 << i);
2576 	}
2577 
2578 	mutex_enter(&pwp->lock);
2579 	pwp->intr_mask = pri;
2580 	pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_MASK, pwp->intr_mask);
2581 	pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, 0xffffffff);
2582 	mutex_exit(&pwp->lock);
2583 
2584 	return (0);
2585 }
2586 
2587 static int
2588 pmcs_teardown_intr(pmcs_hw_t *pwp)
2589 {
2590 	if (pwp->intr_cnt) {
2591 		if (pmcs_disable_intrs(pwp, pwp->intr_cnt)) {
2592 			return (EIO);
2593 		}
2594 		if (pmcs_remove_ihandlers(pwp, pwp->intr_cnt)) {
2595 			return (EIO);
2596 		}
2597 		if (pmcs_free_intrs(pwp, pwp->intr_cnt)) {
2598 			return (EIO);
2599 		}
2600 		pwp->intr_cnt = 0;
2601 	}
2602 	return (0);
2603 }
2604 
2605 static uint_t
2606 pmcs_general_ix(caddr_t arg1, caddr_t arg2)
2607 {
2608 	pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1);
2609 	_NOTE(ARGUNUSED(arg2));
2610 	pmcs_general_intr(pwp);
2611 	return (DDI_INTR_CLAIMED);
2612 }
2613 
2614 static uint_t
2615 pmcs_event_ix(caddr_t arg1, caddr_t arg2)
2616 {
2617 	pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1);
2618 	_NOTE(ARGUNUSED(arg2));
2619 	pmcs_event_intr(pwp);
2620 	return (DDI_INTR_CLAIMED);
2621 }
2622 
2623 static uint_t
2624 pmcs_iodone_ix(caddr_t arg1, caddr_t arg2)
2625 {
2626 	_NOTE(ARGUNUSED(arg2));
2627 	pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1);
2628 
2629 	/*
2630 	 * It's possible that if we just turned interrupt coalescing off
2631 	 * (and thus, re-enabled auto clear for interrupts on the I/O outbound
2632 	 * queue) that there was an interrupt already pending.  We use
2633 	 * io_intr_coal.int_cleared to ensure that we still drop in here and
2634 	 * clear the appropriate interrupt bit one last time.
2635 	 */
2636 	mutex_enter(&pwp->ict_lock);
2637 	if (pwp->io_intr_coal.timer_on ||
2638 	    (pwp->io_intr_coal.int_cleared == B_FALSE)) {
2639 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR,
2640 		    (1 << PMCS_OQ_IODONE));
2641 		pwp->io_intr_coal.int_cleared = B_TRUE;
2642 	}
2643 	mutex_exit(&pwp->ict_lock);
2644 
2645 	pmcs_iodone_intr(pwp);
2646 
2647 	return (DDI_INTR_CLAIMED);
2648 }
2649 
2650 static uint_t
2651 pmcs_fatal_ix(caddr_t arg1, caddr_t arg2)
2652 {
2653 	pmcs_hw_t *pwp = (pmcs_hw_t *)((void *)arg1);
2654 	_NOTE(ARGUNUSED(arg2));
2655 	pmcs_fatal_handler(pwp);
2656 	return (DDI_INTR_CLAIMED);
2657 }
2658 
2659 static uint_t
2660 pmcs_nonio_ix(caddr_t arg1, caddr_t arg2)
2661 {
2662 	_NOTE(ARGUNUSED(arg2));
2663 	pmcs_hw_t *pwp = (void *)arg1;
2664 	uint32_t obdb = pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB);
2665 
2666 	/*
2667 	 * Check for Fatal Interrupts
2668 	 */
2669 	if (obdb & (1 << PMCS_FATAL_INTERRUPT)) {
2670 		pmcs_fatal_handler(pwp);
2671 		return (DDI_INTR_CLAIMED);
2672 	}
2673 
2674 	if (obdb & (1 << PMCS_OQ_GENERAL)) {
2675 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR,
2676 		    (1 << PMCS_OQ_GENERAL));
2677 		pmcs_general_intr(pwp);
2678 		pmcs_event_intr(pwp);
2679 	}
2680 
2681 	return (DDI_INTR_CLAIMED);
2682 }
2683 
2684 static uint_t
2685 pmcs_all_intr(caddr_t arg1, caddr_t arg2)
2686 {
2687 	_NOTE(ARGUNUSED(arg2));
2688 	pmcs_hw_t *pwp = (void *) arg1;
2689 	uint32_t obdb;
2690 	int handled = 0;
2691 
2692 	obdb = pmcs_rd_msgunit(pwp, PMCS_MSGU_OBDB);
2693 
2694 	/*
2695 	 * Check for Fatal Interrupts
2696 	 */
2697 	if (obdb & (1 << PMCS_FATAL_INTERRUPT)) {
2698 		pmcs_fatal_handler(pwp);
2699 		return (DDI_INTR_CLAIMED);
2700 	}
2701 
2702 	/*
2703 	 * Check for Outbound Queue service needed
2704 	 */
2705 	if (obdb & (1 << PMCS_OQ_IODONE)) {
2706 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR,
2707 		    (1 << PMCS_OQ_IODONE));
2708 		obdb ^= (1 << PMCS_OQ_IODONE);
2709 		handled++;
2710 		pmcs_iodone_intr(pwp);
2711 	}
2712 	if (obdb & (1 << PMCS_OQ_GENERAL)) {
2713 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR,
2714 		    (1 << PMCS_OQ_GENERAL));
2715 		obdb ^= (1 << PMCS_OQ_GENERAL);
2716 		handled++;
2717 		pmcs_general_intr(pwp);
2718 	}
2719 	if (obdb & (1 << PMCS_OQ_EVENTS)) {
2720 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR,
2721 		    (1 << PMCS_OQ_EVENTS));
2722 		obdb ^= (1 << PMCS_OQ_EVENTS);
2723 		handled++;
2724 		pmcs_event_intr(pwp);
2725 	}
2726 	if (obdb) {
2727 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
2728 		    "interrupt bits not handled (0x%x)", obdb);
2729 		pmcs_wr_msgunit(pwp, PMCS_MSGU_OBDB_CLEAR, obdb);
2730 		handled++;
2731 	}
2732 	if (pwp->int_type == PMCS_INT_MSI) {
2733 		handled++;
2734 	}
2735 	return (handled? DDI_INTR_CLAIMED : DDI_INTR_UNCLAIMED);
2736 }
2737 
2738 void
2739 pmcs_fatal_handler(pmcs_hw_t *pwp)
2740 {
2741 	pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL, "Fatal Interrupt caught");
2742 
2743 	mutex_enter(&pwp->lock);
2744 	pwp->state = STATE_DEAD;
2745 
2746 	/*
2747 	 * Attempt a hot reset. In case of failure, pmcs_hot_reset() will
2748 	 * handle the failure and issue any required FM notifications.
2749 	 * See pmcs_subr.c for more details.
2750 	 */
2751 	if (pmcs_hot_reset(pwp)) {
2752 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
2753 		    "%s: hot reset failure", __func__);
2754 	} else {
2755 		pmcs_prt(pwp, PMCS_PRT_ERR, NULL, NULL,
2756 		    "%s: hot reset complete", __func__);
2757 		pwp->last_reset_reason = PMCS_LAST_RST_FATAL_ERROR;
2758 	}
2759 	mutex_exit(&pwp->lock);
2760 }
2761 
2762 /*
2763  * Called with PHY lock and target statlock held and scratch acquired.
2764  */
2765 boolean_t
2766 pmcs_assign_device(pmcs_hw_t *pwp, pmcs_xscsi_t *tgt)
2767 {
2768 	pmcs_phy_t *pptr = tgt->phy;
2769 
2770 	switch (pptr->dtype) {
2771 	case SAS:
2772 	case EXPANDER:
2773 		break;
2774 	case SATA:
2775 		tgt->ca = 1;
2776 		break;
2777 	default:
2778 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt,
2779 		    "%s: Target %p has PHY %p with invalid dtype",
2780 		    __func__, (void *)tgt, (void *)pptr);
2781 		return (B_FALSE);
2782 	}
2783 
2784 	tgt->new = 1;
2785 	tgt->dev_gone = 0;
2786 	tgt->recover_wait = 0;
2787 
2788 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt,
2789 	    "%s: config %s vtgt %u for " SAS_ADDR_FMT, __func__,
2790 	    pptr->path, tgt->target_num, SAS_ADDR_PRT(pptr->sas_address));
2791 
2792 	if (pmcs_add_new_device(pwp, tgt) != B_TRUE) {
2793 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, tgt,
2794 		    "%s: Failed for vtgt %u / WWN " SAS_ADDR_FMT, __func__,
2795 		    tgt->target_num, SAS_ADDR_PRT(pptr->sas_address));
2796 		mutex_destroy(&tgt->statlock);
2797 		mutex_destroy(&tgt->wqlock);
2798 		mutex_destroy(&tgt->aqlock);
2799 		return (B_FALSE);
2800 	}
2801 
2802 	return (B_TRUE);
2803 }
2804 
2805 /*
2806  * Called with softstate lock held
2807  */
2808 void
2809 pmcs_remove_device(pmcs_hw_t *pwp, pmcs_phy_t *pptr)
2810 {
2811 	pmcs_xscsi_t *xp;
2812 	unsigned int vtgt;
2813 
2814 	ASSERT(mutex_owned(&pwp->lock));
2815 
2816 	for (vtgt = 0; vtgt < pwp->max_dev; vtgt++) {
2817 		xp = pwp->targets[vtgt];
2818 		if (xp == NULL) {
2819 			continue;
2820 		}
2821 
2822 		mutex_enter(&xp->statlock);
2823 		if (xp->phy == pptr) {
2824 			if (xp->new) {
2825 				xp->new = 0;
2826 				pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, xp,
2827 				    "cancel config of vtgt %u", vtgt);
2828 			} else {
2829 				pmcs_clear_xp(pwp, xp);
2830 				pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, xp,
2831 				    "Removed tgt 0x%p vtgt %u",
2832 				    (void *)xp, vtgt);
2833 			}
2834 			mutex_exit(&xp->statlock);
2835 			break;
2836 		}
2837 		mutex_exit(&xp->statlock);
2838 	}
2839 }
2840 
2841 void
2842 pmcs_prt_impl(pmcs_hw_t *pwp, pmcs_prt_level_t level,
2843     pmcs_phy_t *phyp, pmcs_xscsi_t *target, const char *fmt, ...)
2844 {
2845 	va_list	ap;
2846 	int written = 0;
2847 	char *ptr;
2848 	uint32_t elem_size = PMCS_TBUF_ELEM_SIZE - 1;
2849 	boolean_t system_log;
2850 	int system_log_level;
2851 	hrtime_t hrtimestamp;
2852 
2853 	switch (level) {
2854 	case PMCS_PRT_DEBUG_DEVEL:
2855 	case PMCS_PRT_DEBUG_DEV_STATE:
2856 	case PMCS_PRT_DEBUG_PHY_LOCKING:
2857 	case PMCS_PRT_DEBUG_SCSI_STATUS:
2858 	case PMCS_PRT_DEBUG_UNDERFLOW:
2859 	case PMCS_PRT_DEBUG_CONFIG:
2860 	case PMCS_PRT_DEBUG_IPORT:
2861 	case PMCS_PRT_DEBUG_MAP:
2862 	case PMCS_PRT_DEBUG3:
2863 	case PMCS_PRT_DEBUG2:
2864 	case PMCS_PRT_DEBUG1:
2865 	case PMCS_PRT_DEBUG:
2866 		system_log = B_FALSE;
2867 		break;
2868 	case PMCS_PRT_INFO:
2869 		system_log = B_TRUE;
2870 		system_log_level = CE_CONT;
2871 		break;
2872 	case PMCS_PRT_WARN:
2873 		system_log = B_TRUE;
2874 		system_log_level = CE_NOTE;
2875 		break;
2876 	case PMCS_PRT_ERR:
2877 		system_log = B_TRUE;
2878 		system_log_level = CE_WARN;
2879 		break;
2880 	default:
2881 		return;
2882 	}
2883 
2884 	mutex_enter(&pmcs_trace_lock);
2885 	hrtimestamp = gethrtime();
2886 	gethrestime(&pmcs_tbuf_ptr->timestamp);
2887 
2888 	if (pwp->fw_timestamp != 0) {
2889 		/* Calculate the approximate firmware time stamp... */
2890 		pmcs_tbuf_ptr->fw_timestamp = pwp->fw_timestamp +
2891 		    ((hrtimestamp - pwp->hrtimestamp) / PMCS_FWLOG_TIMER_DIV);
2892 	} else {
2893 		pmcs_tbuf_ptr->fw_timestamp = 0;
2894 	}
2895 
2896 	ptr = pmcs_tbuf_ptr->buf;
2897 
2898 	/*
2899 	 * Store the pertinent PHY and target information if there is any
2900 	 */
2901 	if (target == NULL) {
2902 		pmcs_tbuf_ptr->target_num = PMCS_INVALID_TARGET_NUM;
2903 		pmcs_tbuf_ptr->target_ua[0] = '\0';
2904 	} else {
2905 		pmcs_tbuf_ptr->target_num = target->target_num;
2906 		(void) strncpy(pmcs_tbuf_ptr->target_ua, target->ua,
2907 		    PMCS_TBUF_UA_MAX_SIZE);
2908 	}
2909 
2910 	if (phyp == NULL) {
2911 		(void) memset(pmcs_tbuf_ptr->phy_sas_address, 0, 8);
2912 		pmcs_tbuf_ptr->phy_path[0] = '\0';
2913 		pmcs_tbuf_ptr->phy_dtype = NOTHING;
2914 	} else {
2915 		(void) memcpy(pmcs_tbuf_ptr->phy_sas_address,
2916 		    phyp->sas_address, 8);
2917 		(void) strncpy(pmcs_tbuf_ptr->phy_path, phyp->path, 32);
2918 		pmcs_tbuf_ptr->phy_dtype = phyp->dtype;
2919 	}
2920 
2921 	written += snprintf(ptr, elem_size, "pmcs%d:%d: ",
2922 	    ddi_get_instance(pwp->dip), level);
2923 	ptr += strlen(ptr);
2924 	va_start(ap, fmt);
2925 	written += vsnprintf(ptr, elem_size - written, fmt, ap);
2926 	va_end(ap);
2927 	if (written > elem_size - 1) {
2928 		/* Indicate truncation */
2929 		pmcs_tbuf_ptr->buf[elem_size - 1] = '+';
2930 	}
2931 	if (++pmcs_tbuf_idx == pmcs_tbuf_num_elems) {
2932 		pmcs_tbuf_ptr = pmcs_tbuf;
2933 		pmcs_tbuf_wrap = B_TRUE;
2934 		pmcs_tbuf_idx = 0;
2935 	} else {
2936 		++pmcs_tbuf_ptr;
2937 	}
2938 	mutex_exit(&pmcs_trace_lock);
2939 
2940 	/*
2941 	 * When pmcs_force_syslog in non-zero, everything goes also
2942 	 * to syslog, at CE_CONT level.
2943 	 */
2944 	if (pmcs_force_syslog) {
2945 		system_log = B_TRUE;
2946 		system_log_level = CE_CONT;
2947 	}
2948 
2949 	/*
2950 	 * Anything that comes in with PMCS_PRT_INFO, WARN, or ERR also
2951 	 * goes to syslog.
2952 	 */
2953 	if (system_log) {
2954 		char local[196];
2955 
2956 		switch (system_log_level) {
2957 		case CE_CONT:
2958 			(void) snprintf(local, sizeof (local), "%sINFO: ",
2959 			    pmcs_console ? "" : "?");
2960 			break;
2961 		case CE_NOTE:
2962 		case CE_WARN:
2963 			local[0] = 0;
2964 			break;
2965 		default:
2966 			return;
2967 		}
2968 
2969 		ptr = local;
2970 		ptr += strlen(local);
2971 		(void) snprintf(ptr, (sizeof (local)) -
2972 		    ((size_t)ptr - (size_t)local), "pmcs%d: ",
2973 		    ddi_get_instance(pwp->dip));
2974 		ptr += strlen(ptr);
2975 		va_start(ap, fmt);
2976 		(void) vsnprintf(ptr,
2977 		    (sizeof (local)) - ((size_t)ptr - (size_t)local), fmt, ap);
2978 		va_end(ap);
2979 		if (level == CE_CONT) {
2980 			(void) strlcat(local, "\n", sizeof (local));
2981 		}
2982 		cmn_err(system_log_level, local);
2983 	}
2984 
2985 }
2986 
2987 /*
2988  * pmcs_acquire_scratch
2989  *
2990  * If "wait" is true, the caller will wait until it can acquire the scratch.
2991  * This implies the caller needs to be in a context where spinning for an
2992  * indeterminate amount of time is acceptable.
2993  */
2994 int
2995 pmcs_acquire_scratch(pmcs_hw_t *pwp, boolean_t wait)
2996 {
2997 	int rval;
2998 
2999 	if (!wait) {
3000 		return (atomic_swap_8(&pwp->scratch_locked, 1));
3001 	}
3002 
3003 	/*
3004 	 * Caller will wait for scratch.
3005 	 */
3006 	while ((rval = atomic_swap_8(&pwp->scratch_locked, 1)) != 0) {
3007 		drv_usecwait(100);
3008 	}
3009 
3010 	return (rval);
3011 }
3012 
3013 void
3014 pmcs_release_scratch(pmcs_hw_t *pwp)
3015 {
3016 	pwp->scratch_locked = 0;
3017 }
3018 
3019 /* Called with iport_lock and phy lock held */
3020 void
3021 pmcs_create_one_phy_stats(pmcs_iport_t *iport, pmcs_phy_t *phyp)
3022 {
3023 	sas_phy_stats_t		*ps;
3024 	pmcs_hw_t		*pwp;
3025 	int			ndata;
3026 	char			ks_name[KSTAT_STRLEN];
3027 
3028 	ASSERT(mutex_owned(&iport->lock));
3029 	pwp = iport->pwp;
3030 	ASSERT(pwp != NULL);
3031 	ASSERT(mutex_owned(&phyp->phy_lock));
3032 
3033 	if (phyp->phy_stats != NULL) {
3034 		/*
3035 		 * Delete existing kstats with name containing
3036 		 * old iport instance# and allow creation of
3037 		 * new kstats with new iport instance# in the name.
3038 		 */
3039 		kstat_delete(phyp->phy_stats);
3040 	}
3041 
3042 	ndata = (sizeof (sas_phy_stats_t)/sizeof (kstat_named_t));
3043 
3044 	(void) snprintf(ks_name, sizeof (ks_name),
3045 	    "%s.%llx.%d.%d", ddi_driver_name(iport->dip),
3046 	    (longlong_t)pwp->sas_wwns[0],
3047 	    ddi_get_instance(iport->dip), phyp->phynum);
3048 
3049 	phyp->phy_stats = kstat_create("pmcs",
3050 	    ddi_get_instance(iport->dip), ks_name, KSTAT_SAS_PHY_CLASS,
3051 	    KSTAT_TYPE_NAMED, ndata, 0);
3052 
3053 	if (phyp->phy_stats == NULL) {
3054 		pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
3055 		    "%s: Failed to create %s kstats for PHY(0x%p) at %s",
3056 		    __func__, ks_name, (void *)phyp, phyp->path);
3057 	}
3058 
3059 	ps = (sas_phy_stats_t *)phyp->phy_stats->ks_data;
3060 
3061 	kstat_named_init(&ps->seconds_since_last_reset,
3062 	    "SecondsSinceLastReset", KSTAT_DATA_ULONGLONG);
3063 	kstat_named_init(&ps->tx_frames,
3064 	    "TxFrames", KSTAT_DATA_ULONGLONG);
3065 	kstat_named_init(&ps->rx_frames,
3066 	    "RxFrames", KSTAT_DATA_ULONGLONG);
3067 	kstat_named_init(&ps->tx_words,
3068 	    "TxWords", KSTAT_DATA_ULONGLONG);
3069 	kstat_named_init(&ps->rx_words,
3070 	    "RxWords", KSTAT_DATA_ULONGLONG);
3071 	kstat_named_init(&ps->invalid_dword_count,
3072 	    "InvalidDwordCount", KSTAT_DATA_ULONGLONG);
3073 	kstat_named_init(&ps->running_disparity_error_count,
3074 	    "RunningDisparityErrorCount", KSTAT_DATA_ULONGLONG);
3075 	kstat_named_init(&ps->loss_of_dword_sync_count,
3076 	    "LossofDwordSyncCount", KSTAT_DATA_ULONGLONG);
3077 	kstat_named_init(&ps->phy_reset_problem_count,
3078 	    "PhyResetProblemCount", KSTAT_DATA_ULONGLONG);
3079 
3080 	phyp->phy_stats->ks_private = phyp;
3081 	phyp->phy_stats->ks_update = pmcs_update_phy_stats;
3082 	kstat_install(phyp->phy_stats);
3083 }
3084 
3085 static void
3086 pmcs_create_all_phy_stats(pmcs_iport_t *iport)
3087 {
3088 	pmcs_hw_t		*pwp;
3089 	pmcs_phy_t		*phyp;
3090 
3091 	ASSERT(iport != NULL);
3092 	pwp = iport->pwp;
3093 	ASSERT(pwp != NULL);
3094 
3095 	mutex_enter(&iport->lock);
3096 
3097 	for (phyp = list_head(&iport->phys);
3098 	    phyp != NULL;
3099 	    phyp = list_next(&iport->phys, phyp)) {
3100 
3101 		mutex_enter(&phyp->phy_lock);
3102 		pmcs_create_one_phy_stats(iport, phyp);
3103 		mutex_exit(&phyp->phy_lock);
3104 	}
3105 
3106 	mutex_exit(&iport->lock);
3107 }
3108 
3109 int
3110 pmcs_update_phy_stats(kstat_t *ks, int rw)
3111 {
3112 	int		val, ret = DDI_FAILURE;
3113 	pmcs_phy_t	*pptr = (pmcs_phy_t *)ks->ks_private;
3114 	pmcs_hw_t	*pwp = pptr->pwp;
3115 	sas_phy_stats_t	*ps = ks->ks_data;
3116 
3117 	_NOTE(ARGUNUSED(rw));
3118 	ASSERT((pptr != NULL) && (pwp != NULL));
3119 
3120 	/*
3121 	 * We just want to lock against other invocations of kstat;
3122 	 * we don't need to pmcs_lock_phy() for this.
3123 	 */
3124 	mutex_enter(&pptr->phy_lock);
3125 
3126 	/* Get Stats from Chip */
3127 	val = pmcs_get_diag_report(pwp, PMCS_INVALID_DWORD_CNT, pptr->phynum);
3128 	if (val == DDI_FAILURE)
3129 		goto fail;
3130 	ps->invalid_dword_count.value.ull = (unsigned long long)val;
3131 
3132 	val = pmcs_get_diag_report(pwp, PMCS_DISPARITY_ERR_CNT, pptr->phynum);
3133 	if (val == DDI_FAILURE)
3134 		goto fail;
3135 	ps->running_disparity_error_count.value.ull = (unsigned long long)val;
3136 
3137 	val = pmcs_get_diag_report(pwp, PMCS_LOST_DWORD_SYNC_CNT, pptr->phynum);
3138 	if (val == DDI_FAILURE)
3139 		goto fail;
3140 	ps->loss_of_dword_sync_count.value.ull = (unsigned long long)val;
3141 
3142 	val = pmcs_get_diag_report(pwp, PMCS_RESET_FAILED_CNT, pptr->phynum);
3143 	if (val == DDI_FAILURE)
3144 		goto fail;
3145 	ps->phy_reset_problem_count.value.ull = (unsigned long long)val;
3146 
3147 	ret = DDI_SUCCESS;
3148 fail:
3149 	mutex_exit(&pptr->phy_lock);
3150 	return (ret);
3151 }
3152 
3153 static void
3154 pmcs_destroy_phy_stats(pmcs_iport_t *iport)
3155 {
3156 	pmcs_phy_t		*phyp;
3157 
3158 	ASSERT(iport != NULL);
3159 	mutex_enter(&iport->lock);
3160 	phyp = iport->pptr;
3161 	if (phyp == NULL) {
3162 		mutex_exit(&iport->lock);
3163 		return;
3164 	}
3165 
3166 	for (phyp = list_head(&iport->phys);
3167 	    phyp != NULL;
3168 	    phyp = list_next(&iport->phys, phyp)) {
3169 
3170 		mutex_enter(&phyp->phy_lock);
3171 		if (phyp->phy_stats != NULL) {
3172 			kstat_delete(phyp->phy_stats);
3173 			phyp->phy_stats = NULL;
3174 		}
3175 		mutex_exit(&phyp->phy_lock);
3176 	}
3177 
3178 	mutex_exit(&iport->lock);
3179 }
3180 
3181 /*ARGSUSED*/
3182 static int
3183 pmcs_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
3184 {
3185 	/*
3186 	 * as the driver can always deal with an error in any dma or
3187 	 * access handle, we can just return the fme_status value.
3188 	 */
3189 	pci_ereport_post(dip, err, NULL);
3190 	return (err->fme_status);
3191 }
3192 
3193 static void
3194 pmcs_fm_init(pmcs_hw_t *pwp)
3195 {
3196 	ddi_iblock_cookie_t	fm_ibc;
3197 
3198 	/* Only register with IO Fault Services if we have some capability */
3199 	if (pwp->fm_capabilities) {
3200 		/* Adjust access and dma attributes for FMA */
3201 		pwp->reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
3202 		pwp->iqp_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3203 		pwp->oqp_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3204 		pwp->cip_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3205 		pwp->fwlog_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3206 
3207 		/*
3208 		 * Register capabilities with IO Fault Services.
3209 		 */
3210 		ddi_fm_init(pwp->dip, &pwp->fm_capabilities, &fm_ibc);
3211 
3212 		/*
3213 		 * Initialize pci ereport capabilities if ereport
3214 		 * capable (should always be.)
3215 		 */
3216 		if (DDI_FM_EREPORT_CAP(pwp->fm_capabilities) ||
3217 		    DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) {
3218 			pci_ereport_setup(pwp->dip);
3219 		}
3220 
3221 		/*
3222 		 * Register error callback if error callback capable.
3223 		 */
3224 		if (DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) {
3225 			ddi_fm_handler_register(pwp->dip,
3226 			    pmcs_fm_error_cb, (void *) pwp);
3227 		}
3228 	}
3229 }
3230 
3231 static void
3232 pmcs_fm_fini(pmcs_hw_t *pwp)
3233 {
3234 	/* Only unregister FMA capabilities if registered */
3235 	if (pwp->fm_capabilities) {
3236 		/*
3237 		 * Un-register error callback if error callback capable.
3238 		 */
3239 		if (DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) {
3240 			ddi_fm_handler_unregister(pwp->dip);
3241 		}
3242 
3243 		/*
3244 		 * Release any resources allocated by pci_ereport_setup()
3245 		 */
3246 		if (DDI_FM_EREPORT_CAP(pwp->fm_capabilities) ||
3247 		    DDI_FM_ERRCB_CAP(pwp->fm_capabilities)) {
3248 			pci_ereport_teardown(pwp->dip);
3249 		}
3250 
3251 		/* Unregister from IO Fault Services */
3252 		ddi_fm_fini(pwp->dip);
3253 
3254 		/* Adjust access and dma attributes for FMA */
3255 		pwp->reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
3256 		pwp->iqp_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3257 		pwp->oqp_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3258 		pwp->cip_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3259 		pwp->fwlog_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3260 	}
3261 }
3262 
3263 static boolean_t
3264 pmcs_fabricate_wwid(pmcs_hw_t *pwp)
3265 {
3266 	char *cp, c;
3267 	uint64_t adr;
3268 	int i;
3269 
3270 	cp = &c;
3271 	(void) ddi_strtoul(hw_serial, &cp, 10, (unsigned long *)&adr);
3272 
3273 	if (adr == 0) {
3274 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
3275 		    "%s: No serial number available to fabricate WWN",
3276 		    __func__);
3277 
3278 		adr = (uint64_t)gethrtime();
3279 	}
3280 
3281 	adr <<= 8;
3282 	adr |= ((uint64_t)ddi_get_instance(pwp->dip) << 52);
3283 	adr |= (5ULL << 60);
3284 
3285 	for (i = 0; i < PMCS_MAX_PORTS; i++) {
3286 		pwp->sas_wwns[i] = adr + i;
3287 	}
3288 
3289 	return (B_TRUE);
3290 }
3291