xref: /illumos-gate/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_scsa.c (revision 2dea4eed7ad1c66ae4770263aa2911815a8b86eb)
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 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * SCSI (SCSA) midlayer interface for PMC drier.
27  */
28 
29 #include <sys/scsi/adapters/pmcs/pmcs.h>
30 
31 extern scsi_lun_t scsi_lun64_to_lun(scsi_lun64_t lun64);
32 
33 static int pmcs_scsa_tran_tgt_init(dev_info_t *, dev_info_t *,
34     scsi_hba_tran_t *, struct scsi_device *);
35 static void pmcs_scsa_tran_tgt_free(dev_info_t *, dev_info_t *,
36     scsi_hba_tran_t *, struct scsi_device *);
37 static int pmcs_scsa_start(struct scsi_address *, struct scsi_pkt *);
38 static int pmcs_scsa_abort(struct scsi_address *, struct scsi_pkt *);
39 static int pmcs_scsa_reset(struct scsi_address *, int);
40 static int pmcs_scsi_reset_notify(struct scsi_address *, int,
41     void (*)(caddr_t), caddr_t);
42 static int pmcs_scsa_getcap(struct scsi_address *, char *, int);
43 static int pmcs_scsa_setcap(struct scsi_address *, char *, int, int);
44 static int pmcs_scsa_setup_pkt(struct scsi_pkt *, int (*)(caddr_t), caddr_t);
45 static void pmcs_scsa_teardown_pkt(struct scsi_pkt *);
46 
47 static int pmcs_smp_init(dev_info_t *, dev_info_t *, smp_hba_tran_t *,
48     smp_device_t *);
49 static void pmcs_smp_free(dev_info_t *, dev_info_t *, smp_hba_tran_t *,
50     smp_device_t *);
51 static int pmcs_smp_start(struct smp_pkt *);
52 
53 static int pmcs_scsi_quiesce(dev_info_t *);
54 static int pmcs_scsi_unquiesce(dev_info_t *);
55 
56 static int pmcs_cap(struct scsi_address *, char *, int, int, int);
57 static pmcs_xscsi_t *
58     pmcs_addr2xp(struct scsi_address *, uint64_t *, pmcs_cmd_t *);
59 static int pmcs_SAS_run(pmcs_cmd_t *, pmcwork_t *);
60 static void pmcs_SAS_done(pmcs_hw_t *, pmcwork_t *, uint32_t *);
61 
62 static int pmcs_SATA_run(pmcs_cmd_t *, pmcwork_t *);
63 static void pmcs_SATA_done(pmcs_hw_t *, pmcwork_t *, uint32_t *);
64 static uint8_t pmcs_SATA_rwparm(uint8_t *, uint32_t *, uint64_t *, uint64_t);
65 
66 static void pmcs_ioerror(pmcs_hw_t *, pmcs_dtype_t pmcs_dtype,
67     pmcwork_t *, uint32_t *);
68 
69 
70 int
71 pmcs_scsa_init(pmcs_hw_t *pwp, const ddi_dma_attr_t *ap)
72 {
73 	scsi_hba_tran_t *tran;
74 	ddi_dma_attr_t pmcs_scsa_dattr;
75 	int flags;
76 
77 	(void) memcpy(&pmcs_scsa_dattr, ap, sizeof (ddi_dma_attr_t));
78 	pmcs_scsa_dattr.dma_attr_sgllen =
79 	    ((PMCS_SGL_NCHUNKS - 1) * (PMCS_MAX_CHUNKS - 1)) + PMCS_SGL_NCHUNKS;
80 	pmcs_scsa_dattr.dma_attr_flags = DDI_DMA_RELAXED_ORDERING;
81 	pmcs_scsa_dattr.dma_attr_flags |= DDI_DMA_FLAGERR;
82 
83 	/*
84 	 * Allocate a transport structure
85 	 */
86 	tran = scsi_hba_tran_alloc(pwp->dip, SCSI_HBA_CANSLEEP);
87 	if (tran == NULL) {
88 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
89 		    "scsi_hba_tran_alloc failed");
90 		return (DDI_FAILURE);
91 	}
92 
93 	tran->tran_hba_private		= pwp;
94 	tran->tran_tgt_init		= pmcs_scsa_tran_tgt_init;
95 	tran->tran_tgt_free		= pmcs_scsa_tran_tgt_free;
96 	tran->tran_start		= pmcs_scsa_start;
97 	tran->tran_abort		= pmcs_scsa_abort;
98 	tran->tran_reset		= pmcs_scsa_reset;
99 	tran->tran_reset_notify		= pmcs_scsi_reset_notify;
100 	tran->tran_getcap		= pmcs_scsa_getcap;
101 	tran->tran_setcap		= pmcs_scsa_setcap;
102 	tran->tran_setup_pkt		= pmcs_scsa_setup_pkt;
103 	tran->tran_teardown_pkt		= pmcs_scsa_teardown_pkt;
104 	tran->tran_quiesce		= pmcs_scsi_quiesce;
105 	tran->tran_unquiesce		= pmcs_scsi_unquiesce;
106 	tran->tran_interconnect_type	= INTERCONNECT_SAS;
107 	tran->tran_hba_len		= sizeof (pmcs_cmd_t);
108 
109 	/*
110 	 * Attach this instance of the hba
111 	 */
112 
113 	flags = SCSI_HBA_TRAN_SCB | SCSI_HBA_TRAN_CDB | SCSI_HBA_ADDR_COMPLEX |
114 	    SCSI_HBA_TRAN_PHCI | SCSI_HBA_HBA;
115 
116 	if (scsi_hba_attach_setup(pwp->dip, &pmcs_scsa_dattr, tran, flags)) {
117 		scsi_hba_tran_free(tran);
118 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
119 		    "scsi_hba_attach failed");
120 		return (DDI_FAILURE);
121 	}
122 	pwp->tran = tran;
123 
124 	/*
125 	 * Attach the SMP part of this hba
126 	 */
127 	pwp->smp_tran = smp_hba_tran_alloc(pwp->dip);
128 	ASSERT(pwp->smp_tran != NULL);
129 	pwp->smp_tran->smp_tran_hba_private = pwp;
130 	pwp->smp_tran->smp_tran_init = pmcs_smp_init;
131 	pwp->smp_tran->smp_tran_free = pmcs_smp_free;
132 	pwp->smp_tran->smp_tran_start = pmcs_smp_start;
133 
134 	if (smp_hba_attach_setup(pwp->dip, pwp->smp_tran) != DDI_SUCCESS) {
135 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
136 		    "smp_hba_attach failed");
137 		smp_hba_tran_free(pwp->smp_tran);
138 		pwp->smp_tran = NULL;
139 		scsi_hba_tran_free(tran);
140 		return (DDI_FAILURE);
141 	}
142 
143 	return (DDI_SUCCESS);
144 }
145 
146 /*
147  * SCSA entry points
148  */
149 
150 static int
151 pmcs_scsa_tran_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
152     scsi_hba_tran_t *tran, struct scsi_device *sd)
153 {
154 	pmcs_hw_t	*pwp = NULL;
155 	int		rval;
156 	char		*variant_prop = "sata";
157 	char		*tgt_port = NULL, *ua = NULL;
158 	pmcs_xscsi_t	*tgt = NULL;
159 	pmcs_iport_t	*iport;
160 	pmcs_lun_t	*lun = NULL;
161 	pmcs_phy_t	*phyp = NULL;
162 	uint64_t	lun_num;
163 	boolean_t	got_scratch = B_FALSE;
164 
165 	/*
166 	 * First, make sure we're an iport and get the pointer to the HBA
167 	 * node's softstate
168 	 */
169 	if (scsi_hba_iport_unit_address(hba_dip) == NULL) {
170 		pmcs_prt(TRAN2PMC(tran), PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
171 		    "%s: We don't enumerate devices on the HBA node", __func__);
172 		goto tgt_init_fail;
173 	}
174 
175 	pwp = ITRAN2PMC(tran);
176 	iport = ITRAN2IPORT(tran);
177 
178 	/*
179 	 * Get the unit-address
180 	 */
181 	ua = scsi_device_unit_address(sd);
182 	if (ua == NULL) {
183 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
184 		    "%s: Couldn't get UA", __func__);
185 		pwp = NULL;
186 		goto tgt_init_fail;
187 	}
188 	pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, NULL,
189 	    "got ua '%s'", ua);
190 
191 	/*
192 	 * Get the target address
193 	 */
194 	rval = scsi_device_prop_lookup_string(sd, SCSI_DEVICE_PROP_PATH,
195 	    SCSI_ADDR_PROP_TARGET_PORT, &tgt_port);
196 	if (rval != DDI_PROP_SUCCESS) {
197 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
198 		    "Couldn't get target UA");
199 		pwp = NULL;
200 		goto tgt_init_fail;
201 	}
202 	pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, NULL,
203 	    "got tgt_port '%s'", tgt_port);
204 
205 	/*
206 	 * Validate that this tran_tgt_init is for an active iport.
207 	 */
208 	if (iport->ua_state == UA_INACTIVE) {
209 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
210 		    "%s: Got tran_tgt_init on inactive iport for '%s'",
211 		    __func__, tgt_port);
212 		pwp = NULL;
213 		goto tgt_init_fail;
214 	}
215 
216 	/*
217 	 * Since we're going to wait for scratch, be sure to acquire it while
218 	 * we're not holding any other locks
219 	 */
220 	(void) pmcs_acquire_scratch(pwp, B_TRUE);
221 	got_scratch = B_TRUE;
222 
223 	mutex_enter(&pwp->lock);
224 
225 	/*
226 	 * See if there's already a target softstate.  If not, allocate one.
227 	 */
228 	tgt = pmcs_get_target(iport, tgt_port);
229 
230 	if (tgt == NULL) {
231 		goto tgt_init_fail;
232 	}
233 
234 	phyp = tgt->phy;
235 	if (!IS_ROOT_PHY(phyp)) {
236 		pmcs_inc_phy_ref_count(phyp);
237 	}
238 	ASSERT(mutex_owned(&phyp->phy_lock));
239 
240 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, phyp, tgt, "@%s tgt = 0x%p, dip = 0x%p",
241 	    ua, (void *)tgt, (void *)tgt_dip);
242 
243 	/* Now get the lun */
244 	lun_num = scsi_device_prop_get_int64(sd, SCSI_DEVICE_PROP_PATH,
245 	    SCSI_ADDR_PROP_LUN64, SCSI_LUN64_ILLEGAL);
246 	if (lun_num == SCSI_LUN64_ILLEGAL) {
247 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
248 		    "No LUN for tgt %p", (void *)tgt);
249 		goto tgt_init_fail;
250 	}
251 
252 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt, "%s: @%s tgt 0x%p phy "
253 	    "0x%p (%s)", __func__, ua, (void *)tgt, (void *)phyp, phyp->path);
254 
255 	mutex_enter(&tgt->statlock);
256 	tgt->dtype = phyp->dtype;
257 	if (tgt->dtype != SAS && tgt->dtype != SATA) {
258 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
259 		    "PHY 0x%p went away?", (void *)phyp);
260 		goto tgt_init_fail;
261 	}
262 
263 	/* We don't support SATA devices at LUN > 0. */
264 	if ((tgt->dtype == SATA) && (lun_num > 0)) {
265 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
266 		    "%s: No support for SATA devices at LUN > 0 "
267 		    "(target = 0x%p)", __func__, (void *)tgt);
268 		goto tgt_init_fail;
269 	}
270 
271 	/*
272 	 * Allocate LU soft state. We use ddi_soft_state_bystr_zalloc instead
273 	 * of kmem_alloc because ddi_soft_state_bystr_zalloc allows us to
274 	 * verify that the framework never tries to initialize two scsi_device
275 	 * structures with the same unit-address at the same time.
276 	 */
277 	if (ddi_soft_state_bystr_zalloc(tgt->lun_sstate, ua) != DDI_SUCCESS) {
278 		pmcs_prt(pwp, PMCS_PRT_DEBUG2, phyp, tgt,
279 		    "Couldn't allocate LU soft state");
280 		goto tgt_init_fail;
281 	}
282 
283 	lun = ddi_soft_state_bystr_get(tgt->lun_sstate, ua);
284 	if (lun == NULL) {
285 		pmcs_prt(pwp, PMCS_PRT_DEBUG2, phyp, tgt,
286 		    "Couldn't get LU soft state");
287 		goto tgt_init_fail;
288 	}
289 	scsi_device_hba_private_set(sd, lun);
290 	lun->lun_num = lun_num;
291 
292 	/* convert the scsi_lun64_t value to SCSI standard form */
293 	lun->scsi_lun = scsi_lun64_to_lun(lun_num);
294 
295 	ASSERT(strlen(ua) < (PMCS_MAX_UA_SIZE - 1));
296 	bcopy(ua, lun->unit_address, strnlen(ua, PMCS_MAX_UA_SIZE - 1));
297 
298 	lun->target = tgt;
299 
300 	/*
301 	 * If this is the first tran_tgt_init, add this target to our list
302 	 */
303 	if (tgt->target_num == PMCS_INVALID_TARGET_NUM) {
304 		int target;
305 		for (target = 0; target < pwp->max_dev; target++) {
306 			if (pwp->targets[target] != NULL) {
307 				continue;
308 			}
309 
310 			pwp->targets[target] = tgt;
311 			tgt->target_num = (uint16_t)target;
312 			break;
313 		}
314 
315 		if (target == pwp->max_dev) {
316 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
317 			    "Target list full.");
318 			goto tgt_init_fail;
319 		}
320 	}
321 
322 	tgt->dip = sd->sd_dev;
323 	lun->sd = sd;
324 	list_insert_tail(&tgt->lun_list, lun);
325 
326 	if (!pmcs_assign_device(pwp, tgt)) {
327 		pmcs_release_scratch(pwp);
328 		pwp->targets[tgt->target_num] = NULL;
329 		tgt->target_num = PMCS_INVALID_TARGET_NUM;
330 		tgt->phy = NULL;
331 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
332 		    "%s: pmcs_assign_device failed for target 0x%p",
333 		    __func__, (void *)tgt);
334 		goto tgt_init_fail;
335 	}
336 
337 	pmcs_release_scratch(pwp);
338 	tgt->ref_count++;
339 
340 	(void) scsi_device_prop_update_int(sd, SCSI_DEVICE_PROP_PATH,
341 	    SCSI_ADDR_PROP_TARGET, (uint32_t)(tgt->target_num));
342 
343 	/* SM-HBA */
344 	if (tgt->dtype == SATA) {
345 		/* TCR in PSARC/1997/281 opinion */
346 		(void) scsi_device_prop_update_string(sd,
347 		    SCSI_DEVICE_PROP_PATH, "variant", variant_prop);
348 	}
349 
350 	tgt->phy_addressable = PMCS_PHY_ADDRESSABLE(phyp);
351 
352 	if (tgt->phy_addressable) {
353 		(void) scsi_device_prop_update_int(sd, SCSI_DEVICE_PROP_PATH,
354 		    SCSI_ADDR_PROP_SATA_PHY, phyp->phynum);
355 	}
356 
357 	/* SM-HBA */
358 	(void) pmcs_smhba_set_scsi_device_props(pwp, phyp, sd);
359 	/*
360 	 * Make sure attached port and target port pm props are updated
361 	 * By passing in 0s, we're not actually updating any values, but
362 	 * the properties should now get updated on the node.
363 	 */
364 
365 	mutex_exit(&tgt->statlock);
366 	pmcs_update_phy_pm_props(phyp, 0, 0, B_TRUE);
367 	pmcs_unlock_phy(phyp);
368 	mutex_exit(&pwp->lock);
369 	scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, tgt_port);
370 	return (DDI_SUCCESS);
371 
372 tgt_init_fail:
373 	scsi_device_hba_private_set(sd, NULL);
374 	if (got_scratch) {
375 		pmcs_release_scratch(pwp);
376 	}
377 	if (lun) {
378 		list_remove(&tgt->lun_list, lun);
379 		ddi_soft_state_bystr_free(tgt->lun_sstate, ua);
380 	}
381 	if (phyp) {
382 		mutex_exit(&tgt->statlock);
383 		pmcs_unlock_phy(phyp);
384 		/*
385 		 * phyp's ref count was incremented in pmcs_new_tport.
386 		 * We're failing configuration, we now need to decrement it.
387 		 */
388 		if (!IS_ROOT_PHY(phyp)) {
389 			pmcs_dec_phy_ref_count(phyp);
390 		}
391 		phyp->target = NULL;
392 	}
393 	if (tgt && tgt->ref_count == 0) {
394 		ddi_soft_state_bystr_free(iport->tgt_sstate, tgt_port);
395 	}
396 	if (pwp) {
397 		mutex_exit(&pwp->lock);
398 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
399 		    "%s: failed for @%s tgt 0x%p phy 0x%p", __func__, ua,
400 		    (void *)tgt, (void *)phyp);
401 	}
402 	if (tgt_port) {
403 		scsi_device_prop_free(sd, SCSI_DEVICE_PROP_PATH, tgt_port);
404 	}
405 	return (DDI_FAILURE);
406 }
407 
408 static void
409 pmcs_scsa_tran_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
410     scsi_hba_tran_t *tran, struct scsi_device *sd)
411 {
412 	_NOTE(ARGUNUSED(hba_dip, tgt_dip));
413 	pmcs_hw_t	*pwp;
414 	pmcs_lun_t	*lun;
415 	pmcs_xscsi_t	*target;
416 	char		*unit_address;
417 	pmcs_phy_t	*phyp;
418 
419 	if (scsi_hba_iport_unit_address(hba_dip) == NULL) {
420 		pwp = TRAN2PMC(tran);
421 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
422 		    "%s: We don't enumerate devices on the HBA node", __func__);
423 		return;
424 	}
425 
426 	lun = (pmcs_lun_t *)scsi_device_hba_private_get(sd);
427 
428 	ASSERT((lun != NULL) && (lun->target != NULL));
429 	ASSERT(lun->target->ref_count > 0);
430 
431 	target = lun->target;
432 	unit_address = lun->unit_address;
433 	list_remove(&target->lun_list, lun);
434 
435 	pwp = ITRAN2PMC(tran);
436 	mutex_enter(&pwp->lock);
437 	mutex_enter(&target->statlock);
438 	ASSERT(target->phy);
439 	phyp = target->phy;
440 
441 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, target,
442 	    "%s: for @%s tgt 0x%p phy 0x%p", __func__, unit_address,
443 	    (void *)target, (void *)phyp);
444 	ddi_soft_state_bystr_free(lun->target->lun_sstate, unit_address);
445 
446 	if (target->recover_wait) {
447 		mutex_exit(&target->statlock);
448 		mutex_exit(&pwp->lock);
449 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, target, "%s: "
450 		    "Target 0x%p in device state recovery, fail tran_tgt_free",
451 		    __func__, (void *)target);
452 		return;
453 	}
454 
455 	/*
456 	 * If this target still has a PHY pointer and that PHY's target pointer
457 	 * has been cleared, then that PHY has been reaped. In that case, there
458 	 * would be no need to decrement the reference count
459 	 */
460 	if (phyp && !IS_ROOT_PHY(phyp) && phyp->target) {
461 		pmcs_dec_phy_ref_count(phyp);
462 	}
463 
464 	if (--target->ref_count == 0) {
465 		/*
466 		 * Remove this target from our list.  The target soft
467 		 * state will remain, and the device will remain registered
468 		 * with the hardware unless/until we're told the device
469 		 * physically went away.
470 		 */
471 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, target,
472 		    "%s: Free target 0x%p (vtgt %d)", __func__, (void *)target,
473 		    target->target_num);
474 		pwp->targets[target->target_num] = NULL;
475 		target->target_num = PMCS_INVALID_TARGET_NUM;
476 		/*
477 		 * If the target still has a PHY pointer, break the linkage
478 		 */
479 		if (phyp) {
480 			phyp->target = NULL;
481 		}
482 		target->phy = NULL;
483 		pmcs_destroy_target(target);
484 	} else {
485 		mutex_exit(&target->statlock);
486 	}
487 
488 	mutex_exit(&pwp->lock);
489 }
490 
491 static int
492 pmcs_scsa_start(struct scsi_address *ap, struct scsi_pkt *pkt)
493 {
494 	pmcs_cmd_t *sp = PKT2CMD(pkt);
495 	pmcs_hw_t *pwp = ADDR2PMC(ap);
496 	pmcs_xscsi_t *xp;
497 	boolean_t blocked;
498 	uint32_t hba_state;
499 
500 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL,
501 	    "%s: pkt %p sd %p cdb0=0x%02x dl=%lu", __func__, (void *)pkt,
502 	    (void *)scsi_address_device(&pkt->pkt_address),
503 	    pkt->pkt_cdbp[0] & 0xff, pkt->pkt_dma_len);
504 
505 	if (pkt->pkt_flags & FLAG_NOINTR) {
506 		pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, NULL,
507 		    "%s: nointr pkt", __func__);
508 		return (TRAN_BADPKT);
509 	}
510 
511 	sp->cmd_tag = 0;
512 	pkt->pkt_state = pkt->pkt_statistics = 0;
513 	pkt->pkt_reason = CMD_INCOMPLETE;
514 
515 	mutex_enter(&pwp->lock);
516 	hba_state = pwp->state;
517 	blocked = pwp->blocked;
518 	mutex_exit(&pwp->lock);
519 
520 	if (hba_state != STATE_RUNNING) {
521 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
522 		    "%s: hba dead", __func__);
523 		return (TRAN_FATAL_ERROR);
524 	}
525 
526 	xp = pmcs_addr2xp(ap, NULL, sp);
527 	if (xp == NULL) {
528 		pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL,
529 		    "%s: dropping due to null target", __func__);
530 		goto dead_target;
531 	}
532 	ASSERT(mutex_owned(&xp->statlock));
533 
534 	/*
535 	 * First, check to see if the device is gone.
536 	 */
537 	if (xp->dev_gone) {
538 		xp->actv_pkts++;
539 		mutex_exit(&xp->statlock);
540 		pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, xp,
541 		    "%s: dropping due to dead target 0x%p",
542 		    __func__, (void *)xp);
543 		goto dead_target;
544 	}
545 
546 	/*
547 	 * If we're blocked (quiesced) just return.
548 	 */
549 	if (blocked) {
550 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
551 		    "%s: hba blocked", __func__);
552 		xp->actv_pkts++;
553 		mutex_exit(&xp->statlock);
554 		mutex_enter(&xp->wqlock);
555 		STAILQ_INSERT_TAIL(&xp->wq, sp, cmd_next);
556 		mutex_exit(&xp->wqlock);
557 		return (TRAN_ACCEPT);
558 	}
559 
560 	/*
561 	 * If we're draining or resetting, queue and return.
562 	 */
563 	if (xp->draining || xp->resetting || xp->recover_wait) {
564 		xp->actv_pkts++;
565 		mutex_exit(&xp->statlock);
566 		mutex_enter(&xp->wqlock);
567 		STAILQ_INSERT_TAIL(&xp->wq, sp, cmd_next);
568 		mutex_exit(&xp->wqlock);
569 		pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, xp,
570 		    "%s: draining/resetting/recovering (cnt %u)",
571 		    __func__, xp->actv_cnt);
572 		/*
573 		 * By the time we get here, draining or
574 		 * resetting may have come and gone, not
575 		 * yet noticing that we had put something
576 		 * on the wait queue, so schedule a worker
577 		 * to look at this later.
578 		 */
579 		SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
580 		return (TRAN_ACCEPT);
581 	}
582 
583 	xp->actv_pkts++;
584 	mutex_exit(&xp->statlock);
585 
586 	/*
587 	 * Queue this command to the tail of the wait queue.
588 	 * This keeps us getting commands out of order.
589 	 */
590 	mutex_enter(&xp->wqlock);
591 	STAILQ_INSERT_TAIL(&xp->wq, sp, cmd_next);
592 	mutex_exit(&xp->wqlock);
593 
594 	/*
595 	 * Now run the queue for this device.
596 	 */
597 	(void) pmcs_scsa_wq_run_one(pwp, xp);
598 
599 	return (TRAN_ACCEPT);
600 
601 dead_target:
602 	pkt->pkt_state = STATE_GOT_BUS;
603 	pkt->pkt_reason = CMD_DEV_GONE;
604 	mutex_enter(&pwp->cq_lock);
605 	STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
606 	PMCS_CQ_RUN_LOCKED(pwp);
607 	mutex_exit(&pwp->cq_lock);
608 	return (TRAN_ACCEPT);
609 }
610 
611 /* Return code 1 = Success */
612 static int
613 pmcs_scsa_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
614 {
615 	pmcs_hw_t *pwp = ADDR2PMC(ap);
616 	pmcs_cmd_t *sp = NULL;
617 	pmcs_xscsi_t *xp = NULL;
618 	pmcs_phy_t *pptr = NULL;
619 	pmcs_lun_t *pmcs_lun = (pmcs_lun_t *)
620 	    scsi_device_hba_private_get(scsi_address_device(ap));
621 	uint32_t tag;
622 	uint64_t lun;
623 	pmcwork_t *pwrk;
624 
625 	mutex_enter(&pwp->lock);
626 	if (pwp->state != STATE_RUNNING) {
627 		mutex_exit(&pwp->lock);
628 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
629 		    "%s: hba dead", __func__);
630 		return (0);
631 	}
632 	mutex_exit(&pwp->lock);
633 
634 	if (pkt == NULL) {
635 		if (pmcs_lun == NULL) {
636 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: "
637 			    "No pmcs_lun_t struct to do ABORT_ALL", __func__);
638 			return (0);
639 		}
640 		xp = pmcs_lun->target;
641 		if (xp != NULL) {
642 			pptr = xp->phy;
643 		}
644 		if (pptr == NULL) {
645 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp, "%s: pkt is "
646 			    "NULL. No tgt/phy to do ABORT_ALL", __func__);
647 			return (0);
648 		}
649 		pmcs_lock_phy(pptr);
650 		if (pmcs_abort(pwp, pptr, 0, 1, 0)) {
651 			pptr->abort_pending = 1;
652 			SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE);
653 		}
654 		pmcs_unlock_phy(pptr);
655 		return (1);
656 	}
657 
658 	sp = PKT2CMD(pkt);
659 	xp = sp->cmd_target;
660 
661 	if (sp->cmd_lun) {
662 		lun = sp->cmd_lun->lun_num;
663 	} else {
664 		lun = 0;
665 	}
666 	if (xp == NULL) {
667 		return (0);
668 	}
669 
670 	/*
671 	 * See if we have a real work structure associated with this cmd.
672 	 */
673 	pwrk = pmcs_tag2wp(pwp, sp->cmd_tag);
674 	if (pwrk && pwrk->arg == sp) {
675 		tag = pwrk->htag;
676 		pptr = pwrk->phy;
677 		pwrk->timer = 0;	/* we don't time this here */
678 		ASSERT(pwrk->state == PMCS_WORK_STATE_ONCHIP);
679 		mutex_exit(&pwrk->lock);
680 		pmcs_lock_phy(pptr);
681 		if (pptr->dtype == SAS) {
682 			if (pmcs_ssp_tmf(pwp, pptr, SAS_ABORT_TASK, tag, lun,
683 			    NULL)) {
684 				pptr->abort_pending = 1;
685 				pmcs_unlock_phy(pptr);
686 				SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE);
687 				return (0);
688 			}
689 		} else {
690 			/*
691 			 * XXX: Was the command that was active an
692 			 * NCQ I/O command?
693 			 */
694 			pptr->need_rl_ext = 1;
695 			if (pmcs_sata_abort_ncq(pwp, pptr)) {
696 				pptr->abort_pending = 1;
697 				pmcs_unlock_phy(pptr);
698 				SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE);
699 				return (0);
700 			}
701 		}
702 		pptr->abort_pending = 1;
703 		pmcs_unlock_phy(pptr);
704 		SCHEDULE_WORK(pwp, PMCS_WORK_ABORT_HANDLE);
705 		return (1);
706 	}
707 	if (pwrk) {
708 		mutex_exit(&pwrk->lock);
709 	}
710 	/*
711 	 * Okay, those weren't the droids we were looking for.
712 	 * See if the command is on any of the wait queues.
713 	 */
714 	mutex_enter(&xp->wqlock);
715 	sp = NULL;
716 	STAILQ_FOREACH(sp, &xp->wq, cmd_next) {
717 		if (sp == PKT2CMD(pkt)) {
718 			STAILQ_REMOVE(&xp->wq, sp, pmcs_cmd, cmd_next);
719 			break;
720 		}
721 	}
722 	mutex_exit(&xp->wqlock);
723 	if (sp) {
724 		pkt->pkt_reason = CMD_ABORTED;
725 		pkt->pkt_statistics |= STAT_ABORTED;
726 		mutex_enter(&pwp->cq_lock);
727 		STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
728 		PMCS_CQ_RUN_LOCKED(pwp);
729 		mutex_exit(&pwp->cq_lock);
730 		return (1);
731 	}
732 	return (0);
733 }
734 
735 /*
736  * SCSA reset functions
737  */
738 static int
739 pmcs_scsa_reset(struct scsi_address *ap, int level)
740 {
741 	pmcs_hw_t *pwp = ADDR2PMC(ap);
742 	pmcs_phy_t *pptr;
743 	pmcs_xscsi_t *xp;
744 	uint64_t lun = (uint64_t)-1, *lp = NULL;
745 	int rval;
746 
747 	mutex_enter(&pwp->lock);
748 	if (pwp->state != STATE_RUNNING) {
749 		mutex_exit(&pwp->lock);
750 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
751 		    "%s: hba dead", __func__);
752 		return (0);
753 	}
754 	mutex_exit(&pwp->lock);
755 
756 	switch (level)  {
757 	case RESET_ALL:
758 		rval = 0;
759 		break;
760 	case RESET_LUN:
761 		/*
762 		 * Point lp at lun so that pmcs_addr2xp
763 		 * will fill out the 64 bit lun number.
764 		 */
765 		lp = &lun;
766 		/* FALLTHROUGH */
767 	case RESET_TARGET:
768 		xp = pmcs_addr2xp(ap, lp, NULL);
769 		if (xp == NULL) {
770 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
771 			    "%s: no xp found for this scsi address", __func__);
772 			return (0);
773 		}
774 
775 		if (xp->dev_gone) {
776 			mutex_exit(&xp->statlock);
777 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
778 			    "%s: Target 0x%p has gone away", __func__,
779 			    (void *)xp);
780 			return (0);
781 		}
782 
783 		/*
784 		 * If we're already performing this action, or if device
785 		 * state recovery is already running, just return failure.
786 		 */
787 		if (xp->resetting || xp->recover_wait) {
788 			mutex_exit(&xp->statlock);
789 			return (0);
790 		}
791 		xp->reset_wait = 0;
792 		xp->reset_success = 0;
793 		xp->resetting = 1;
794 		pptr = xp->phy;
795 		mutex_exit(&xp->statlock);
796 
797 		if (pmcs_reset_dev(pwp, pptr, lun)) {
798 			rval = 0;
799 		} else {
800 			rval = 1;
801 		}
802 
803 		mutex_enter(&xp->statlock);
804 		if (rval == 1) {
805 			xp->reset_success = 1;
806 		}
807 		if (xp->reset_wait) {
808 			xp->reset_wait = 0;
809 			cv_signal(&xp->reset_cv);
810 		}
811 		xp->resetting = 0;
812 		mutex_exit(&xp->statlock);
813 		SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
814 		break;
815 	default:
816 		rval = 0;
817 		break;
818 	}
819 
820 	return (rval);
821 }
822 
823 static int
824 pmcs_scsi_reset_notify(struct scsi_address *ap, int flag,
825     void (*callback)(caddr_t), caddr_t arg)
826 {
827 	pmcs_hw_t *pwp = ADDR2PMC(ap);
828 	return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
829 	    &pwp->lock, &pwp->reset_notify_listf));
830 }
831 
832 
833 static int
834 pmcs_cap(struct scsi_address *ap, char *cap, int val, int tonly, int set)
835 {
836 	_NOTE(ARGUNUSED(val, tonly));
837 	int cidx, rval = 0;
838 	pmcs_xscsi_t *xp;
839 
840 	cidx = scsi_hba_lookup_capstr(cap);
841 	if (cidx == -1) {
842 		return (-1);
843 	}
844 
845 	xp = pmcs_addr2xp(ap, NULL, NULL);
846 	if (xp == NULL) {
847 		return (-1);
848 	}
849 
850 	switch (cidx) {
851 	case SCSI_CAP_DMA_MAX:
852 	case SCSI_CAP_INITIATOR_ID:
853 		if (set == 0) {
854 			rval = INT_MAX;	/* argh */
855 		}
856 		break;
857 	case SCSI_CAP_DISCONNECT:
858 	case SCSI_CAP_SYNCHRONOUS:
859 	case SCSI_CAP_WIDE_XFER:
860 	case SCSI_CAP_PARITY:
861 	case SCSI_CAP_ARQ:
862 	case SCSI_CAP_UNTAGGED_QING:
863 		if (set == 0) {
864 			rval = 1;
865 		}
866 		break;
867 
868 	case SCSI_CAP_TAGGED_QING:
869 		rval = 1;
870 		break;
871 
872 	case SCSI_CAP_MSG_OUT:
873 	case SCSI_CAP_RESET_NOTIFICATION:
874 	case SCSI_CAP_QFULL_RETRIES:
875 	case SCSI_CAP_QFULL_RETRY_INTERVAL:
876 		break;
877 	case SCSI_CAP_SCSI_VERSION:
878 		if (set == 0) {
879 			rval = SCSI_VERSION_3;
880 		}
881 		break;
882 	case SCSI_CAP_INTERCONNECT_TYPE:
883 		if (set) {
884 			break;
885 		}
886 		if (xp->phy_addressable) {
887 			rval = INTERCONNECT_SATA;
888 		} else {
889 			rval = INTERCONNECT_SAS;
890 		}
891 		break;
892 	case SCSI_CAP_CDB_LEN:
893 		if (set == 0) {
894 			rval = 16;
895 		}
896 		break;
897 	case SCSI_CAP_LUN_RESET:
898 		if (set) {
899 			break;
900 		}
901 		if (xp->dtype == SATA) {
902 			rval = 0;
903 		} else {
904 			rval = 1;
905 		}
906 		break;
907 	default:
908 		rval = -1;
909 		break;
910 	}
911 	mutex_exit(&xp->statlock);
912 	pmcs_prt(ADDR2PMC(ap), PMCS_PRT_DEBUG3, NULL, NULL,
913 	    "%s: cap %s val %d set %d rval %d",
914 	    __func__, cap, val, set, rval);
915 	return (rval);
916 }
917 
918 /*
919  * Returns with statlock held if the xp is found.
920  * Fills in pmcs_cmd_t with values if pmcs_cmd_t pointer non-NULL.
921  */
922 static pmcs_xscsi_t *
923 pmcs_addr2xp(struct scsi_address *ap, uint64_t *lp, pmcs_cmd_t *sp)
924 {
925 	pmcs_xscsi_t *xp;
926 	pmcs_lun_t *lun = (pmcs_lun_t *)
927 	    scsi_device_hba_private_get(scsi_address_device(ap));
928 
929 	if ((lun == NULL) || (lun->target == NULL)) {
930 		return (NULL);
931 	}
932 	xp = lun->target;
933 	mutex_enter(&xp->statlock);
934 
935 	if (xp->dev_gone || (xp->phy == NULL)) {
936 		/*
937 		 * This may be a retried packet, so it's possible cmd_target
938 		 * and cmd_lun may still be populated.  Clear them.
939 		 */
940 		if (sp != NULL) {
941 			sp->cmd_target = NULL;
942 			sp->cmd_lun = NULL;
943 		}
944 		mutex_exit(&xp->statlock);
945 		return (NULL);
946 	}
947 
948 	if (sp != NULL) {
949 		sp->cmd_target = xp;
950 		sp->cmd_lun = lun;
951 	}
952 	if (lp) {
953 		*lp = lun->lun_num;
954 	}
955 	return (xp);
956 }
957 
958 static int
959 pmcs_scsa_getcap(struct scsi_address *ap, char *cap, int whom)
960 {
961 	int r;
962 	if (cap == NULL) {
963 		return (-1);
964 	}
965 	r = pmcs_cap(ap, cap, 0, whom, 0);
966 	return (r);
967 }
968 
969 static int
970 pmcs_scsa_setcap(struct scsi_address *ap, char *cap, int value, int whom)
971 {
972 	int r;
973 	if (cap == NULL) {
974 		return (-1);
975 	}
976 	r = pmcs_cap(ap, cap, value, whom, 1);
977 	return (r);
978 }
979 
980 static int
981 pmcs_scsa_setup_pkt(struct scsi_pkt *pkt, int (*callback)(caddr_t),
982     caddr_t cbarg)
983 {
984 	_NOTE(ARGUNUSED(callback, cbarg));
985 	pmcs_cmd_t *sp = pkt->pkt_ha_private;
986 
987 	bzero(sp, sizeof (pmcs_cmd_t));
988 	sp->cmd_pkt = pkt;
989 	return (0);
990 }
991 
992 static void
993 pmcs_scsa_teardown_pkt(struct scsi_pkt *pkt)
994 {
995 	pmcs_cmd_t *sp = pkt->pkt_ha_private;
996 	sp->cmd_target = NULL;
997 	sp->cmd_lun = NULL;
998 }
999 
1000 static int
1001 pmcs_smp_start(struct smp_pkt *smp_pkt)
1002 {
1003 	struct pmcwork *pwrk;
1004 	const uint_t rdoff = SAS_SMP_MAX_PAYLOAD;
1005 	uint32_t msg[PMCS_MSG_SIZE], *ptr, htag, status;
1006 	uint64_t wwn;
1007 	pmcs_hw_t *pwp;
1008 	pmcs_phy_t *pptr;
1009 	pmcs_xscsi_t *xp;
1010 	uint_t reqsz, rspsz, will_retry;
1011 	int result;
1012 
1013 	pwp = smp_pkt->smp_pkt_address->smp_a_hba_tran->smp_tran_hba_private;
1014 	bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
1015 
1016 	pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, NULL,
1017 	    "%s: starting for wwn 0x%" PRIx64, __func__, wwn);
1018 
1019 	will_retry = smp_pkt->smp_pkt_will_retry;
1020 
1021 	(void) pmcs_acquire_scratch(pwp, B_TRUE);
1022 	reqsz = smp_pkt->smp_pkt_reqsize;
1023 	if (reqsz > SAS_SMP_MAX_PAYLOAD) {
1024 		reqsz = SAS_SMP_MAX_PAYLOAD;
1025 	}
1026 	(void) memcpy(pwp->scratch, smp_pkt->smp_pkt_req, reqsz);
1027 
1028 	rspsz = smp_pkt->smp_pkt_rspsize;
1029 	if (rspsz > SAS_SMP_MAX_PAYLOAD) {
1030 		rspsz = SAS_SMP_MAX_PAYLOAD;
1031 	}
1032 
1033 	/*
1034 	 * The request size from the SMP driver always includes 4 bytes
1035 	 * for the CRC. The PMCS chip, however, doesn't want to see those
1036 	 * counts as part of the transfer size.
1037 	 */
1038 	reqsz -= 4;
1039 
1040 	pptr = pmcs_find_phy_by_wwn(pwp, wwn);
1041 	/* PHY is now locked */
1042 	if (pptr == NULL || pptr->dtype != EXPANDER) {
1043 		if (pptr) {
1044 			pmcs_unlock_phy(pptr);
1045 		}
1046 		pmcs_release_scratch(pwp);
1047 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL,
1048 		    "%s: could not find phy", __func__);
1049 		smp_pkt->smp_pkt_reason = ENXIO;
1050 		return (DDI_FAILURE);
1051 	}
1052 
1053 	if ((pptr->iport == NULL) || !pptr->valid_device_id) {
1054 		pmcs_unlock_phy(pptr);
1055 		pmcs_release_scratch(pwp);
1056 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, pptr->target,
1057 		    "%s: Can't reach PHY %s", __func__, pptr->path);
1058 		smp_pkt->smp_pkt_reason = ENXIO;
1059 		return (DDI_FAILURE);
1060 	}
1061 
1062 	pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_WAIT, pptr);
1063 	if (pwrk == NULL) {
1064 		pmcs_unlock_phy(pptr);
1065 		pmcs_release_scratch(pwp);
1066 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, NULL,
1067 		    "%s: could not get work structure", __func__);
1068 		smp_pkt->smp_pkt_reason = will_retry ? EAGAIN : EBUSY;
1069 		return (DDI_FAILURE);
1070 	}
1071 
1072 	pwrk->arg = msg;
1073 	pwrk->dtype = EXPANDER;
1074 	mutex_enter(&pwp->iqp_lock[PMCS_IQ_OTHER]);
1075 	ptr = GET_IQ_ENTRY(pwp, PMCS_IQ_OTHER);
1076 	if (ptr == NULL) {
1077 		pmcs_pwork(pwp, pwrk);
1078 		mutex_exit(&pwp->iqp_lock[PMCS_IQ_OTHER]);
1079 		pmcs_unlock_phy(pptr);
1080 		pmcs_release_scratch(pwp);
1081 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1082 		    "%s: could not get IQ entry", __func__);
1083 		smp_pkt->smp_pkt_reason = will_retry ? EAGAIN :EBUSY;
1084 		return (DDI_FAILURE);
1085 	}
1086 	msg[0] = LE_32(PMCS_HIPRI(pwp, PMCS_OQ_GENERAL, PMCIN_SMP_REQUEST));
1087 	msg[1] = LE_32(pwrk->htag);
1088 	msg[2] = LE_32(pptr->device_id);
1089 	msg[3] = LE_32(SMP_INDIRECT_RESPONSE | SMP_INDIRECT_REQUEST);
1090 	msg[8] = LE_32(DWORD0(pwp->scratch_dma));
1091 	msg[9] = LE_32(DWORD1(pwp->scratch_dma));
1092 	msg[10] = LE_32(reqsz);
1093 	msg[11] = 0;
1094 	msg[12] = LE_32(DWORD0(pwp->scratch_dma+rdoff));
1095 	msg[13] = LE_32(DWORD1(pwp->scratch_dma+rdoff));
1096 	msg[14] = LE_32(rspsz);
1097 	msg[15] = 0;
1098 
1099 	COPY_MESSAGE(ptr, msg, PMCS_MSG_SIZE);
1100 	/* SMP serialization */
1101 	pmcs_smp_acquire(pptr->iport);
1102 
1103 	pwrk->state = PMCS_WORK_STATE_ONCHIP;
1104 	htag = pwrk->htag;
1105 	INC_IQ_ENTRY(pwp, PMCS_IQ_OTHER);
1106 
1107 	pmcs_unlock_phy(pptr);
1108 	WAIT_FOR(pwrk, smp_pkt->smp_pkt_timeout * 1000, result);
1109 	pmcs_pwork(pwp, pwrk);
1110 	/* Release SMP lock before reacquiring PHY lock */
1111 	pmcs_smp_release(pptr->iport);
1112 	pmcs_lock_phy(pptr);
1113 
1114 	if (result) {
1115 		pmcs_timed_out(pwp, htag, __func__);
1116 		if (pmcs_abort(pwp, pptr, htag, 0, 0)) {
1117 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target,
1118 			    "%s: Unable to issue SMP ABORT for htag 0x%08x",
1119 			    __func__, htag);
1120 		} else {
1121 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target,
1122 			    "%s: Issuing SMP ABORT for htag 0x%08x",
1123 			    __func__, htag);
1124 		}
1125 		pmcs_unlock_phy(pptr);
1126 		pmcs_release_scratch(pwp);
1127 		smp_pkt->smp_pkt_reason = ETIMEDOUT;
1128 		return (DDI_FAILURE);
1129 	}
1130 	status = LE_32(msg[2]);
1131 	if (status == PMCOUT_STATUS_OVERFLOW) {
1132 		status = PMCOUT_STATUS_OK;
1133 		smp_pkt->smp_pkt_reason = EOVERFLOW;
1134 	}
1135 	if (status != PMCOUT_STATUS_OK) {
1136 		const char *emsg = pmcs_status_str(status);
1137 		if (emsg == NULL) {
1138 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target,
1139 			    "SMP operation failed (0x%x)", status);
1140 		} else {
1141 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, pptr, pptr->target,
1142 			    "SMP operation failed (%s)", emsg);
1143 		}
1144 
1145 		if ((status == PMCOUT_STATUS_ERROR_HW_TIMEOUT) ||
1146 		    (status == PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT)) {
1147 			smp_pkt->smp_pkt_reason =
1148 			    will_retry ? EAGAIN : ETIMEDOUT;
1149 			result = DDI_FAILURE;
1150 		} else if (status ==
1151 		    PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS) {
1152 			xp = pptr->target;
1153 			if (xp == NULL) {
1154 				smp_pkt->smp_pkt_reason = EIO;
1155 				result = DDI_FAILURE;
1156 				goto out;
1157 			}
1158 			if (xp->dev_state !=
1159 			    PMCS_DEVICE_STATE_NON_OPERATIONAL) {
1160 				xp->dev_state =
1161 				    PMCS_DEVICE_STATE_NON_OPERATIONAL;
1162 				pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, xp->phy,
1163 				    xp, "%s: Got _IT_NEXUS_LOSS SMP status. "
1164 				    "Tgt(0x%p) dev_state set to "
1165 				    "_NON_OPERATIONAL", __func__,
1166 				    (void *)xp);
1167 			}
1168 			/* ABORT any pending commands related to this device */
1169 			if (pmcs_abort(pwp, pptr, pptr->device_id, 1, 1) != 0) {
1170 				pptr->abort_pending = 1;
1171 				smp_pkt->smp_pkt_reason = EIO;
1172 				result = DDI_FAILURE;
1173 			}
1174 		} else {
1175 			smp_pkt->smp_pkt_reason = will_retry ? EAGAIN : EIO;
1176 			result = DDI_FAILURE;
1177 		}
1178 	} else {
1179 		(void) memcpy(smp_pkt->smp_pkt_rsp,
1180 		    &((uint8_t *)pwp->scratch)[rdoff], rspsz);
1181 		if (smp_pkt->smp_pkt_reason == EOVERFLOW) {
1182 			result = DDI_FAILURE;
1183 		} else {
1184 			result = DDI_SUCCESS;
1185 		}
1186 	}
1187 out:
1188 	pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, pptr->target,
1189 	    "%s: done for wwn 0x%" PRIx64, __func__, wwn);
1190 
1191 	pmcs_unlock_phy(pptr);
1192 	pmcs_release_scratch(pwp);
1193 	return (result);
1194 }
1195 
1196 static int
1197 pmcs_smp_init(dev_info_t *self, dev_info_t *child,
1198     smp_hba_tran_t *tran, smp_device_t *smp_sd)
1199 {
1200 	_NOTE(ARGUNUSED(tran, smp_sd));
1201 	pmcs_iport_t *iport;
1202 	pmcs_hw_t *pwp;
1203 	pmcs_xscsi_t *tgt;
1204 	pmcs_phy_t *phy, *pphy;
1205 	uint64_t wwn;
1206 	char *addr, *tgt_port;
1207 	int ua_form = 1;
1208 
1209 	iport = ddi_get_soft_state(pmcs_iport_softstate,
1210 	    ddi_get_instance(self));
1211 	ASSERT(iport);
1212 	if (iport == NULL)
1213 		return (DDI_FAILURE);
1214 	pwp = iport->pwp;
1215 	ASSERT(pwp);
1216 	if (pwp == NULL)
1217 		return (DDI_FAILURE);
1218 
1219 	/* Get "target-port" prop from devinfo node */
1220 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1221 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1222 	    SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_SUCCESS) {
1223 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: Failed to "
1224 		    "lookup prop ("SCSI_ADDR_PROP_TARGET_PORT")", __func__);
1225 		/* Dont fail _smp_init() because we couldnt get/set a prop */
1226 		return (DDI_SUCCESS);
1227 	}
1228 
1229 	/*
1230 	 * Validate that this tran_tgt_init is for an active iport.
1231 	 */
1232 	if (iport->ua_state == UA_INACTIVE) {
1233 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1234 		    "%s: Init on inactive iport for '%s'", __func__, tgt_port);
1235 		ddi_prop_free(tgt_port);
1236 		return (DDI_FAILURE);
1237 	}
1238 
1239 	mutex_enter(&pwp->lock);
1240 
1241 	/* Retrieve softstate using unit-address */
1242 	tgt = pmcs_get_target(iport, tgt_port);
1243 	if (tgt == NULL) {
1244 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1245 		    "%s: tgt softstate not found", __func__);
1246 		ddi_prop_free(tgt_port);
1247 		mutex_exit(&pwp->lock);
1248 		return (DDI_FAILURE);
1249 	}
1250 
1251 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, tgt, "%s: %s (%s)",
1252 	    __func__, ddi_get_name(child), tgt_port);
1253 
1254 	mutex_enter(&tgt->statlock);
1255 	phy = tgt->phy;
1256 	ASSERT(mutex_owned(&phy->phy_lock));
1257 
1258 	if (IS_ROOT_PHY(phy)) {
1259 		/* Expander attached to HBA - don't ref_count it */
1260 		wwn = pwp->sas_wwns[0];
1261 	} else {
1262 		pmcs_inc_phy_ref_count(phy);
1263 
1264 		/*
1265 		 * Parent (in topology) is also an expander
1266 		 * Now that we've increased the ref count on phy, it's OK
1267 		 * to drop the lock so we can acquire the parent's lock.
1268 		 */
1269 		pphy = phy->parent;
1270 		mutex_exit(&tgt->statlock);
1271 		pmcs_unlock_phy(phy);
1272 		pmcs_lock_phy(pphy);
1273 		wwn = pmcs_barray2wwn(pphy->sas_address);
1274 		pmcs_unlock_phy(pphy);
1275 		pmcs_lock_phy(phy);
1276 		mutex_enter(&tgt->statlock);
1277 	}
1278 
1279 	/*
1280 	 * If this is the 1st smp_init, add this to our list.
1281 	 */
1282 	if (tgt->target_num == PMCS_INVALID_TARGET_NUM) {
1283 		int target;
1284 		for (target = 0; target < pwp->max_dev; target++) {
1285 			if (pwp->targets[target] != NULL) {
1286 				continue;
1287 			}
1288 
1289 			pwp->targets[target] = tgt;
1290 			tgt->target_num = (uint16_t)target;
1291 			tgt->assigned = 1;
1292 			tgt->dev_state = PMCS_DEVICE_STATE_OPERATIONAL;
1293 			break;
1294 		}
1295 
1296 		if (target == pwp->max_dev) {
1297 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, NULL,
1298 			    "Target list full.");
1299 			goto smp_init_fail;
1300 		}
1301 	}
1302 
1303 	if (!pmcs_assign_device(pwp, tgt)) {
1304 		pwp->targets[tgt->target_num] = NULL;
1305 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, tgt,
1306 		    "%s: pmcs_assign_device failed for target 0x%p",
1307 		    __func__, (void *)tgt);
1308 		goto smp_init_fail;
1309 	}
1310 
1311 	/*
1312 	 * Update the attached port and target port pm properties
1313 	 */
1314 	tgt->smpd = smp_sd;
1315 
1316 	pmcs_unlock_phy(phy);
1317 	mutex_exit(&pwp->lock);
1318 
1319 	tgt->ref_count++;
1320 	tgt->dtype = phy->dtype;
1321 	mutex_exit(&tgt->statlock);
1322 
1323 	pmcs_update_phy_pm_props(phy, 0, 0, B_TRUE);
1324 
1325 	addr = scsi_wwn_to_wwnstr(wwn, ua_form, NULL);
1326 	if (smp_device_prop_update_string(smp_sd, SCSI_ADDR_PROP_ATTACHED_PORT,
1327 	    addr) != DDI_SUCCESS) {
1328 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: Failed to set "
1329 		    "prop ("SCSI_ADDR_PROP_ATTACHED_PORT")", __func__);
1330 	}
1331 	(void) scsi_free_wwnstr(addr);
1332 	ddi_prop_free(tgt_port);
1333 	return (DDI_SUCCESS);
1334 
1335 smp_init_fail:
1336 	tgt->phy = NULL;
1337 	tgt->target_num = PMCS_INVALID_TARGET_NUM;
1338 	phy->target = NULL;
1339 	if (!IS_ROOT_PHY(phy)) {
1340 		pmcs_dec_phy_ref_count(phy);
1341 	}
1342 	mutex_exit(&tgt->statlock);
1343 	pmcs_unlock_phy(phy);
1344 	mutex_exit(&pwp->lock);
1345 	ddi_soft_state_bystr_free(iport->tgt_sstate, tgt->unit_address);
1346 	ddi_prop_free(tgt_port);
1347 	return (DDI_FAILURE);
1348 }
1349 
1350 static void
1351 pmcs_smp_free(dev_info_t *self, dev_info_t *child,
1352     smp_hba_tran_t *tran, smp_device_t *smp)
1353 {
1354 	_NOTE(ARGUNUSED(tran, smp));
1355 	pmcs_iport_t *iport;
1356 	pmcs_hw_t *pwp;
1357 	pmcs_xscsi_t *tgt;
1358 	char *tgt_port;
1359 
1360 	iport = ddi_get_soft_state(pmcs_iport_softstate,
1361 	    ddi_get_instance(self));
1362 	ASSERT(iport);
1363 	if (iport == NULL)
1364 		return;
1365 
1366 	pwp = iport->pwp;
1367 	if (pwp == NULL)
1368 		return;
1369 	ASSERT(pwp);
1370 
1371 	/* Get "target-port" prop from devinfo node */
1372 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
1373 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM,
1374 	    SCSI_ADDR_PROP_TARGET_PORT, &tgt_port) != DDI_SUCCESS) {
1375 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: Failed to "
1376 		    "lookup prop ("SCSI_ADDR_PROP_TARGET_PORT")", __func__);
1377 		return;
1378 	}
1379 
1380 	/* Retrieve softstate using unit-address */
1381 	mutex_enter(&pwp->lock);
1382 	tgt = ddi_soft_state_bystr_get(iport->tgt_sstate, tgt_port);
1383 	pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, tgt, "%s: %s (%s)", __func__,
1384 	    ddi_get_name(child), tgt_port);
1385 	ddi_prop_free(tgt_port);
1386 
1387 	if (tgt == NULL) {
1388 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1389 		    "%s: tgt softstate not found", __func__);
1390 		mutex_exit(&pwp->lock);
1391 		return;
1392 	}
1393 
1394 	mutex_enter(&tgt->statlock);
1395 	if (tgt->phy) {
1396 		if (!IS_ROOT_PHY(tgt->phy)) {
1397 			pmcs_dec_phy_ref_count(tgt->phy);
1398 		}
1399 	}
1400 
1401 	if (--tgt->ref_count == 0) {
1402 		/*
1403 		 * Remove this target from our list. The softstate
1404 		 * will remain, and the device will remain registered
1405 		 * with the hardware unless/until we're told that the
1406 		 * device physically went away.
1407 		 */
1408 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, NULL, tgt,
1409 		    "Removing target 0x%p (vtgt %d) from target list",
1410 		    (void *)tgt, tgt->target_num);
1411 		pwp->targets[tgt->target_num] = NULL;
1412 		tgt->target_num = PMCS_INVALID_TARGET_NUM;
1413 		tgt->phy->target = NULL;
1414 		tgt->phy = NULL;
1415 		pmcs_destroy_target(tgt);
1416 	} else {
1417 		mutex_exit(&tgt->statlock);
1418 	}
1419 
1420 	mutex_exit(&pwp->lock);
1421 }
1422 
1423 static int
1424 pmcs_scsi_quiesce(dev_info_t *dip)
1425 {
1426 	pmcs_hw_t *pwp;
1427 	int totactive = -1;
1428 	pmcs_xscsi_t *xp;
1429 	uint16_t target;
1430 
1431 	if (ddi_get_soft_state(pmcs_iport_softstate, ddi_get_instance(dip)))
1432 		return (0);		/* iport */
1433 
1434 	pwp  = ddi_get_soft_state(pmcs_softc_state, ddi_get_instance(dip));
1435 	if (pwp == NULL) {
1436 		return (-1);
1437 	}
1438 	mutex_enter(&pwp->lock);
1439 	if (pwp->state != STATE_RUNNING) {
1440 		mutex_exit(&pwp->lock);
1441 		return (-1);
1442 	}
1443 
1444 	pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s called", __func__);
1445 	pwp->blocked = 1;
1446 	while (totactive) {
1447 		totactive = 0;
1448 		for (target = 0; target < pwp->max_dev; target++) {
1449 			xp = pwp->targets[target];
1450 			if (xp == NULL) {
1451 				continue;
1452 			}
1453 			mutex_enter(&xp->statlock);
1454 			if (xp->actv_cnt) {
1455 				totactive += xp->actv_cnt;
1456 				xp->draining = 1;
1457 			}
1458 			mutex_exit(&xp->statlock);
1459 		}
1460 		if (totactive) {
1461 			cv_wait(&pwp->drain_cv, &pwp->lock);
1462 		}
1463 		/*
1464 		 * The pwp->blocked may have been reset. e.g a SCSI bus reset
1465 		 */
1466 		pwp->blocked = 1;
1467 	}
1468 
1469 	for (target = 0; target < pwp->max_dev; target++) {
1470 		xp = pwp->targets[target];
1471 		if (xp == NULL) {
1472 			continue;
1473 		}
1474 		mutex_enter(&xp->statlock);
1475 		xp->draining = 0;
1476 		mutex_exit(&xp->statlock);
1477 	}
1478 
1479 	mutex_exit(&pwp->lock);
1480 	if (totactive == 0) {
1481 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
1482 		    "%s drain complete", __func__);
1483 	}
1484 	return (0);
1485 }
1486 
1487 static int
1488 pmcs_scsi_unquiesce(dev_info_t *dip)
1489 {
1490 	pmcs_hw_t *pwp;
1491 
1492 	if (ddi_get_soft_state(pmcs_iport_softstate, ddi_get_instance(dip)))
1493 		return (0);		/* iport */
1494 
1495 	pwp  = ddi_get_soft_state(pmcs_softc_state, ddi_get_instance(dip));
1496 	if (pwp == NULL) {
1497 		return (-1);
1498 	}
1499 	mutex_enter(&pwp->lock);
1500 	if (pwp->state != STATE_RUNNING) {
1501 		mutex_exit(&pwp->lock);
1502 		return (-1);
1503 	}
1504 	pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s called", __func__);
1505 	pwp->blocked = 0;
1506 	mutex_exit(&pwp->lock);
1507 
1508 	/*
1509 	 * Run all pending commands.
1510 	 */
1511 	pmcs_scsa_wq_run(pwp);
1512 
1513 	/*
1514 	 * Complete all completed commands.
1515 	 * This also unlocks us.
1516 	 */
1517 	PMCS_CQ_RUN(pwp);
1518 	return (0);
1519 }
1520 
1521 /*
1522  * Start commands for a particular device
1523  * If the actual start of a command fails, return B_FALSE.  Any other result
1524  * is a B_TRUE return.
1525  */
1526 boolean_t
1527 pmcs_scsa_wq_run_one(pmcs_hw_t *pwp, pmcs_xscsi_t *xp)
1528 {
1529 	pmcs_cmd_t *sp;
1530 	pmcs_phy_t *phyp;
1531 	pmcwork_t *pwrk;
1532 	boolean_t run_one, blocked;
1533 	int rval;
1534 
1535 	/*
1536 	 * First, check to see if we're blocked or resource limited
1537 	 */
1538 	mutex_enter(&pwp->lock);
1539 	blocked = pwp->blocked;
1540 	/*
1541 	 * If resource_limited is set, we're resource constrained and
1542 	 * we will run only one work request for this target.
1543 	 */
1544 	run_one = pwp->resource_limited;
1545 	mutex_exit(&pwp->lock);
1546 
1547 	if (blocked) {
1548 		/* Queues will get restarted when we get unblocked */
1549 		return (B_TRUE);
1550 	}
1551 
1552 	/*
1553 	 * Might as well verify the queue is not empty before moving on
1554 	 */
1555 	mutex_enter(&xp->wqlock);
1556 	if (STAILQ_EMPTY(&xp->wq)) {
1557 		mutex_exit(&xp->wqlock);
1558 		return (B_TRUE);
1559 	}
1560 	mutex_exit(&xp->wqlock);
1561 
1562 	/*
1563 	 * If we're draining or resetting, just reschedule work queue and bail.
1564 	 */
1565 	mutex_enter(&xp->statlock);
1566 	if (xp->draining || xp->resetting || xp->special_running ||
1567 	    xp->special_needed) {
1568 		mutex_exit(&xp->statlock);
1569 		SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
1570 		return (B_TRUE);
1571 	}
1572 
1573 	/*
1574 	 * Next, check to see if the target is gone.
1575 	 */
1576 	if (xp->dev_gone) {
1577 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
1578 		    "%s: Flushing wait queue for dead tgt 0x%p", __func__,
1579 		    (void *)xp);
1580 		pmcs_flush_target_queues(pwp, xp, PMCS_TGT_WAIT_QUEUE);
1581 		mutex_exit(&xp->statlock);
1582 		return (B_TRUE);
1583 	}
1584 
1585 	/*
1586 	 * Increment the PHY's ref_count now so we know it won't go away
1587 	 * after we drop the target lock.  Drop it before returning.  If the
1588 	 * PHY dies, the commands we attempt to send will fail, but at least
1589 	 * we know we have a real PHY pointer.
1590 	 */
1591 	phyp = xp->phy;
1592 	pmcs_inc_phy_ref_count(phyp);
1593 	mutex_exit(&xp->statlock);
1594 
1595 	mutex_enter(&xp->wqlock);
1596 	while ((sp = STAILQ_FIRST(&xp->wq)) != NULL) {
1597 		pwrk = pmcs_gwork(pwp, PMCS_TAG_TYPE_CBACK, phyp);
1598 		if (pwrk == NULL) {
1599 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
1600 			    "%s: out of work structures", __func__);
1601 			SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
1602 			break;
1603 		}
1604 		STAILQ_REMOVE_HEAD(&xp->wq, cmd_next);
1605 		mutex_exit(&xp->wqlock);
1606 
1607 		pwrk->xp = xp;
1608 		pwrk->arg = sp;
1609 		sp->cmd_tag = pwrk->htag;
1610 		pwrk->timer = US2WT(CMD2PKT(sp)->pkt_time * 1000000);
1611 		if (pwrk->timer == 0) {
1612 			pwrk->timer = US2WT(1000000);
1613 		}
1614 
1615 		pwrk->dtype = xp->dtype;
1616 
1617 		if (xp->dtype == SAS) {
1618 			pwrk->ptr = (void *) pmcs_SAS_done;
1619 			if ((rval = pmcs_SAS_run(sp, pwrk)) != 0) {
1620 				sp->cmd_tag = NULL;
1621 				pmcs_dec_phy_ref_count(phyp);
1622 				pmcs_pwork(pwp, pwrk);
1623 				SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
1624 				if (rval == PMCS_WQ_RUN_FAIL_RES) {
1625 					return (B_FALSE);
1626 				} else {
1627 					return (B_TRUE);
1628 				}
1629 			}
1630 		} else {
1631 			ASSERT(xp->dtype == SATA);
1632 			pwrk->ptr = (void *) pmcs_SATA_done;
1633 			if ((rval = pmcs_SATA_run(sp, pwrk)) != 0) {
1634 				sp->cmd_tag = NULL;
1635 				pmcs_dec_phy_ref_count(phyp);
1636 				pmcs_pwork(pwp, pwrk);
1637 				SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
1638 				if (rval == PMCS_WQ_RUN_FAIL_RES) {
1639 					return (B_FALSE);
1640 				} else {
1641 					return (B_TRUE);
1642 				}
1643 			}
1644 		}
1645 
1646 		if (run_one) {
1647 			goto wq_out;
1648 		}
1649 		mutex_enter(&xp->wqlock);
1650 	}
1651 
1652 	mutex_exit(&xp->wqlock);
1653 
1654 wq_out:
1655 	pmcs_dec_phy_ref_count(phyp);
1656 	return (B_TRUE);
1657 }
1658 
1659 /*
1660  * Start commands for all devices.
1661  */
1662 void
1663 pmcs_scsa_wq_run(pmcs_hw_t *pwp)
1664 {
1665 	pmcs_xscsi_t *xp;
1666 	uint16_t target_start, target;
1667 	boolean_t	rval = B_TRUE;
1668 
1669 	mutex_enter(&pwp->lock);
1670 	target_start = pwp->last_wq_dev;
1671 	target = target_start;
1672 
1673 	do {
1674 		xp = pwp->targets[target];
1675 		if ((xp == NULL) || (STAILQ_EMPTY(&xp->wq))) {
1676 			if (++target == pwp->max_dev) {
1677 				target = 0;
1678 			}
1679 			continue;
1680 		}
1681 
1682 		mutex_exit(&pwp->lock);
1683 		rval = pmcs_scsa_wq_run_one(pwp, xp);
1684 		mutex_enter(&pwp->lock);
1685 
1686 		if (rval == B_FALSE) {
1687 			break;
1688 		}
1689 
1690 		if (++target == pwp->max_dev) {
1691 			target = 0;
1692 		}
1693 	} while (target != target_start);
1694 
1695 	if (rval) {
1696 		pwp->resource_limited = 0; /* Not resource-constrained */
1697 	} else {
1698 		pwp->resource_limited = 1; /* Give others a chance */
1699 	}
1700 
1701 	pwp->last_wq_dev = target;
1702 	mutex_exit(&pwp->lock);
1703 }
1704 
1705 /*
1706  * Pull the completion queue, drop the lock and complete all elements.
1707  */
1708 
1709 void
1710 pmcs_scsa_cq_run(void *arg)
1711 {
1712 	pmcs_cq_thr_info_t *cqti = (pmcs_cq_thr_info_t *)arg;
1713 	pmcs_hw_t *pwp = cqti->cq_pwp;
1714 	pmcs_cmd_t *sp, *nxt;
1715 	struct scsi_pkt *pkt;
1716 	pmcs_xscsi_t *tgt;
1717 	pmcs_iocomp_cb_t *ioccb, *ioccb_next;
1718 	pmcs_cb_t callback;
1719 	uint32_t niodone;
1720 
1721 	DTRACE_PROBE1(pmcs__scsa__cq__run__start, pmcs_cq_thr_info_t *, cqti);
1722 
1723 	mutex_enter(&pwp->cq_lock);
1724 
1725 	while (!pwp->cq_info.cq_stop) {
1726 		/*
1727 		 * First, check the I/O completion callback queue.
1728 		 */
1729 
1730 		ioccb = pwp->iocomp_cb_head;
1731 		pwp->iocomp_cb_head = NULL;
1732 		pwp->iocomp_cb_tail = NULL;
1733 		mutex_exit(&pwp->cq_lock);
1734 
1735 		niodone = 0;
1736 
1737 		while (ioccb) {
1738 			niodone++;
1739 			/*
1740 			 * Grab the lock on the work structure. The callback
1741 			 * routine is responsible for clearing it.
1742 			 */
1743 			mutex_enter(&ioccb->pwrk->lock);
1744 			ioccb_next = ioccb->next;
1745 			callback = (pmcs_cb_t)ioccb->pwrk->ptr;
1746 			(*callback)(pwp, ioccb->pwrk,
1747 			    (uint32_t *)((void *)ioccb->iomb));
1748 			kmem_cache_free(pwp->iocomp_cb_cache, ioccb);
1749 			ioccb = ioccb_next;
1750 		}
1751 
1752 		/*
1753 		 * Next, run the completion queue
1754 		 */
1755 
1756 		mutex_enter(&pwp->cq_lock);
1757 		sp = STAILQ_FIRST(&pwp->cq);
1758 		STAILQ_INIT(&pwp->cq);
1759 		mutex_exit(&pwp->cq_lock);
1760 
1761 		DTRACE_PROBE1(pmcs__scsa__cq__run__start__loop,
1762 		    pmcs_cq_thr_info_t *, cqti);
1763 
1764 		if (sp && pmcs_check_acc_dma_handle(pwp)) {
1765 			ddi_fm_service_impact(pwp->dip, DDI_SERVICE_UNAFFECTED);
1766 		}
1767 
1768 		while (sp) {
1769 			nxt = STAILQ_NEXT(sp, cmd_next);
1770 			pkt = CMD2PKT(sp);
1771 			tgt = sp->cmd_target;
1772 			pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, tgt,
1773 			    "%s: calling completion on %p for tgt %p", __func__,
1774 			    (void *)sp, (void *)tgt);
1775 			if (tgt) {
1776 				mutex_enter(&tgt->statlock);
1777 				ASSERT(tgt->actv_pkts != 0);
1778 				tgt->actv_pkts--;
1779 				mutex_exit(&tgt->statlock);
1780 			}
1781 			scsi_hba_pkt_comp(pkt);
1782 			sp = nxt;
1783 		}
1784 
1785 		DTRACE_PROBE1(pmcs__scsa__cq__run__end__loop,
1786 		    pmcs_cq_thr_info_t *, cqti);
1787 
1788 		mutex_enter(&cqti->cq_thr_lock);
1789 		cv_wait(&cqti->cq_cv, &cqti->cq_thr_lock);
1790 		mutex_exit(&cqti->cq_thr_lock);
1791 
1792 		mutex_enter(&pwp->cq_lock);
1793 	}
1794 
1795 	mutex_exit(&pwp->cq_lock);
1796 	DTRACE_PROBE1(pmcs__scsa__cq__run__stop, pmcs_cq_thr_info_t *, cqti);
1797 	thread_exit();
1798 }
1799 
1800 /*
1801  * Run a SAS command.  Called with pwrk->lock held, returns unlocked.
1802  */
1803 static int
1804 pmcs_SAS_run(pmcs_cmd_t *sp, pmcwork_t *pwrk)
1805 {
1806 	pmcs_hw_t *pwp = CMD2PMC(sp);
1807 	struct scsi_pkt *pkt = CMD2PKT(sp);
1808 	pmcs_xscsi_t *xp = pwrk->xp;
1809 	uint32_t iq, *ptr;
1810 	sas_ssp_cmd_iu_t sc;
1811 
1812 	mutex_enter(&xp->statlock);
1813 	if (!xp->assigned) {
1814 		mutex_exit(&xp->statlock);
1815 		return (PMCS_WQ_RUN_FAIL_OTHER);
1816 	}
1817 	if ((xp->actv_cnt >= xp->qdepth) || xp->recover_wait) {
1818 		mutex_exit(&xp->statlock);
1819 		mutex_enter(&xp->wqlock);
1820 		STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
1821 		mutex_exit(&xp->wqlock);
1822 		return (PMCS_WQ_RUN_FAIL_OTHER);
1823 	}
1824 	GET_IO_IQ_ENTRY(pwp, ptr, pwrk->phy->device_id, iq);
1825 	if (ptr == NULL) {
1826 		mutex_exit(&xp->statlock);
1827 		/*
1828 		 * This is a temporary failure not likely to unblocked by
1829 		 * commands completing as the test for scheduling the
1830 		 * restart of work is a per-device test.
1831 		 */
1832 		mutex_enter(&xp->wqlock);
1833 		STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
1834 		mutex_exit(&xp->wqlock);
1835 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
1836 		    "%s: Failed to get IO IQ entry for tgt %d",
1837 		    __func__, xp->target_num);
1838 		return (PMCS_WQ_RUN_FAIL_RES);
1839 
1840 	}
1841 
1842 	ptr[0] =
1843 	    LE_32(PMCS_IOMB_IN_SAS(PMCS_OQ_IODONE, PMCIN_SSP_INI_IO_START));
1844 	ptr[1] = LE_32(pwrk->htag);
1845 	ptr[2] = LE_32(pwrk->phy->device_id);
1846 	ptr[3] = LE_32(pkt->pkt_dma_len);
1847 	if (ptr[3]) {
1848 		ASSERT(pkt->pkt_numcookies);
1849 		if (pkt->pkt_dma_flags & DDI_DMA_READ) {
1850 			ptr[4] = LE_32(PMCIN_DATADIR_2_INI);
1851 		} else {
1852 			ptr[4] = LE_32(PMCIN_DATADIR_2_DEV);
1853 		}
1854 		if (pmcs_dma_load(pwp, sp, ptr)) {
1855 			mutex_exit(&pwp->iqp_lock[iq]);
1856 			mutex_exit(&xp->statlock);
1857 			mutex_enter(&xp->wqlock);
1858 			if (STAILQ_EMPTY(&xp->wq)) {
1859 				STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
1860 				mutex_exit(&xp->wqlock);
1861 			} else {
1862 				mutex_exit(&xp->wqlock);
1863 				CMD2PKT(sp)->pkt_scbp[0] = STATUS_QFULL;
1864 				CMD2PKT(sp)->pkt_reason = CMD_CMPLT;
1865 				CMD2PKT(sp)->pkt_state |= STATE_GOT_BUS |
1866 				    STATE_GOT_TARGET | STATE_SENT_CMD |
1867 				    STATE_GOT_STATUS;
1868 				mutex_enter(&pwp->cq_lock);
1869 				STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
1870 				mutex_exit(&pwp->cq_lock);
1871 				pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
1872 				    "%s: Failed to dma_load for tgt %d (QF)",
1873 				    __func__, xp->target_num);
1874 			}
1875 			return (PMCS_WQ_RUN_FAIL_RES);
1876 		}
1877 	} else {
1878 		ptr[4] = LE_32(PMCIN_DATADIR_NONE);
1879 		CLEAN_MESSAGE(ptr, 12);
1880 	}
1881 	xp->actv_cnt++;
1882 	if (xp->actv_cnt > xp->maxdepth) {
1883 		xp->maxdepth = xp->actv_cnt;
1884 		pmcs_prt(pwp, PMCS_PRT_DEBUG2, pwrk->phy, xp, "%s: max depth "
1885 		    "now %u", pwrk->phy->path, xp->maxdepth);
1886 	}
1887 	mutex_exit(&xp->statlock);
1888 
1889 
1890 #ifdef	DEBUG
1891 	/*
1892 	 * Generate a PMCOUT_STATUS_XFER_CMD_FRAME_ISSUED
1893 	 * event when this goes out on the wire.
1894 	 */
1895 	ptr[4] |= PMCIN_MESSAGE_REPORT;
1896 #endif
1897 	/*
1898 	 * Fill in the SSP IU
1899 	 */
1900 
1901 	bzero(&sc, sizeof (sas_ssp_cmd_iu_t));
1902 	bcopy((uint8_t *)&sp->cmd_lun->scsi_lun, sc.lun, sizeof (scsi_lun_t));
1903 
1904 	switch (pkt->pkt_flags & FLAG_TAGMASK) {
1905 	case FLAG_HTAG:
1906 		sc.task_attribute = SAS_CMD_TASK_ATTR_HEAD;
1907 		break;
1908 	case FLAG_OTAG:
1909 		sc.task_attribute = SAS_CMD_TASK_ATTR_ORDERED;
1910 		break;
1911 	case FLAG_STAG:
1912 	default:
1913 		sc.task_attribute = SAS_CMD_TASK_ATTR_SIMPLE;
1914 		break;
1915 	}
1916 	(void) memcpy(sc.cdb, pkt->pkt_cdbp,
1917 	    min(SCSA_CDBLEN(sp), sizeof (sc.cdb)));
1918 	(void) memcpy(&ptr[5], &sc, sizeof (sas_ssp_cmd_iu_t));
1919 	pwrk->state = PMCS_WORK_STATE_ONCHIP;
1920 	mutex_exit(&pwrk->lock);
1921 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL,
1922 	    "%s: giving pkt %p (tag %x) to the hardware", __func__,
1923 	    (void *)pkt, pwrk->htag);
1924 #ifdef DEBUG
1925 	pmcs_print_entry(pwp, PMCS_PRT_DEBUG3, "SAS INI Message", ptr);
1926 #endif
1927 	mutex_enter(&xp->aqlock);
1928 	STAILQ_INSERT_TAIL(&xp->aq, sp, cmd_next);
1929 	mutex_exit(&xp->aqlock);
1930 	INC_IQ_ENTRY(pwp, iq);
1931 
1932 	/*
1933 	 * If we just submitted the last command queued from device state
1934 	 * recovery, clear the wq_recovery_tail pointer.
1935 	 */
1936 	mutex_enter(&xp->wqlock);
1937 	if (xp->wq_recovery_tail == sp) {
1938 		xp->wq_recovery_tail = NULL;
1939 	}
1940 	mutex_exit(&xp->wqlock);
1941 
1942 	return (PMCS_WQ_RUN_SUCCESS);
1943 }
1944 
1945 /*
1946  * Complete a SAS command
1947  *
1948  * Called with pwrk lock held.
1949  * The free of pwrk releases the lock.
1950  */
1951 
1952 static void
1953 pmcs_SAS_done(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *msg)
1954 {
1955 	pmcs_cmd_t *sp = pwrk->arg;
1956 	pmcs_phy_t *pptr = pwrk->phy;
1957 	pmcs_xscsi_t *xp = pwrk->xp;
1958 	struct scsi_pkt *pkt = CMD2PKT(sp);
1959 	int dead;
1960 	uint32_t sts;
1961 	boolean_t aborted = B_FALSE;
1962 	boolean_t do_ds_recovery = B_FALSE;
1963 
1964 	ASSERT(xp != NULL);
1965 	ASSERT(sp != NULL);
1966 	ASSERT(pptr != NULL);
1967 
1968 	DTRACE_PROBE4(pmcs__io__done, uint64_t, pkt->pkt_dma_len, int,
1969 	    (pkt->pkt_dma_flags & DDI_DMA_READ) != 0, hrtime_t, pwrk->start,
1970 	    hrtime_t, gethrtime());
1971 
1972 	dead = pwrk->dead;
1973 
1974 	if (msg) {
1975 		sts = LE_32(msg[2]);
1976 	} else {
1977 		sts = 0;
1978 	}
1979 
1980 	if (dead != 0) {
1981 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, "%s: dead cmd tag "
1982 		    "0x%x for %s", __func__, pwrk->htag, pptr->path);
1983 		goto out;
1984 	}
1985 
1986 	if (sts == PMCOUT_STATUS_ABORTED) {
1987 		aborted = B_TRUE;
1988 	}
1989 
1990 	if (pwrk->state == PMCS_WORK_STATE_TIMED_OUT) {
1991 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
1992 		    "%s: cmd 0x%p (tag 0x%x) timed out for %s",
1993 		    __func__, (void *)sp, pwrk->htag, pptr->path);
1994 		CMD2PKT(sp)->pkt_scbp[0] = STATUS_GOOD;
1995 		CMD2PKT(sp)->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
1996 		    STATE_SENT_CMD;
1997 		CMD2PKT(sp)->pkt_statistics |= STAT_TIMEOUT;
1998 		goto out;
1999 	}
2000 
2001 	/*
2002 	 * If the status isn't okay but not underflow,
2003 	 * step to the side and parse the (possible) error.
2004 	 */
2005 #ifdef DEBUG
2006 	if (msg) {
2007 		pmcs_print_entry(pwp, PMCS_PRT_DEBUG3, "Outbound Message", msg);
2008 	}
2009 #endif
2010 	if (!msg) {
2011 		goto out;
2012 	}
2013 
2014 	switch (sts) {
2015 	case PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
2016 	case PMCOUT_STATUS_IO_DS_NON_OPERATIONAL:
2017 	case PMCOUT_STATUS_IO_DS_IN_RECOVERY:
2018 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2019 		    "%s: PHY %s requires DS recovery (status=%d)",
2020 		    __func__, pptr->path, sts);
2021 		do_ds_recovery = B_TRUE;
2022 		break;
2023 	case PMCOUT_STATUS_UNDERFLOW:
2024 		(void) pmcs_set_resid(pkt, pkt->pkt_dma_len, LE_32(msg[3]));
2025 		pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW, NULL, NULL,
2026 		    "%s: underflow %u for cdb 0x%x",
2027 		    __func__, LE_32(msg[3]), pkt->pkt_cdbp[0] & 0xff);
2028 		sts = PMCOUT_STATUS_OK;
2029 		msg[3] = 0;
2030 		break;
2031 	case PMCOUT_STATUS_OK:
2032 		pkt->pkt_resid = 0;
2033 		break;
2034 	}
2035 
2036 	if (sts != PMCOUT_STATUS_OK) {
2037 		pmcs_ioerror(pwp, SAS, pwrk, msg);
2038 	} else {
2039 		if (msg[3]) {
2040 			uint8_t local[PMCS_QENTRY_SIZE << 1], *xd;
2041 			sas_ssp_rsp_iu_t *rptr = (void *)local;
2042 			const int lim =
2043 			    (PMCS_QENTRY_SIZE << 1) - SAS_RSP_HDR_SIZE;
2044 			static const uint8_t ssp_rsp_evec[] = {
2045 				0x58, 0x61, 0x56, 0x72, 0x00
2046 			};
2047 
2048 			/*
2049 			 * Transform the the first part of the response
2050 			 * to host canonical form. This gives us enough
2051 			 * information to figure out what to do with the
2052 			 * rest (which remains unchanged in the incoming
2053 			 * message which can be up to two queue entries
2054 			 * in length).
2055 			 */
2056 			pmcs_endian_transform(pwp, local, &msg[5],
2057 			    ssp_rsp_evec);
2058 			xd = (uint8_t *)(&msg[5]);
2059 			xd += SAS_RSP_HDR_SIZE;
2060 
2061 			if (rptr->datapres == SAS_RSP_DATAPRES_RESPONSE_DATA) {
2062 				if (rptr->response_data_length != 4) {
2063 					pmcs_print_entry(pwp, PMCS_PRT_DEBUG,
2064 					    "Bad SAS RESPONSE DATA LENGTH",
2065 					    msg);
2066 					pkt->pkt_reason = CMD_TRAN_ERR;
2067 					goto out;
2068 				}
2069 				(void) memcpy(&sts, xd, sizeof (uint32_t));
2070 				sts = BE_32(sts);
2071 				/*
2072 				 * The only response code we should legally get
2073 				 * here is an INVALID FRAME response code.
2074 				 */
2075 				if (sts == SAS_RSP_INVALID_FRAME) {
2076 					pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2077 					    "%s: pkt %p tgt %u path %s "
2078 					    "completed: INVALID FRAME response",
2079 					    __func__, (void *)pkt,
2080 					    xp->target_num, pptr->path);
2081 				} else {
2082 					pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2083 					    "%s: pkt %p tgt %u path %s "
2084 					    "completed: illegal response 0x%x",
2085 					    __func__, (void *)pkt,
2086 					    xp->target_num, pptr->path, sts);
2087 				}
2088 				pkt->pkt_reason = CMD_TRAN_ERR;
2089 				goto out;
2090 			}
2091 			if (rptr->datapres == SAS_RSP_DATAPRES_SENSE_DATA) {
2092 				uint32_t slen;
2093 				slen = rptr->sense_data_length;
2094 				if (slen > lim) {
2095 					slen = lim;
2096 				}
2097 				pmcs_latch_status(pwp, sp, rptr->status, xd,
2098 				    slen, pptr->path);
2099 			} else if (rptr->datapres == SAS_RSP_DATAPRES_NO_DATA) {
2100 				pmcout_ssp_comp_t *sspcp;
2101 				sspcp = (pmcout_ssp_comp_t *)msg;
2102 				uint32_t *residp;
2103 				/*
2104 				 * This is the case for a plain SCSI status.
2105 				 * Note: If RESC_V is set and we're here, there
2106 				 * is a residual.  We need to find it and update
2107 				 * the packet accordingly.
2108 				 */
2109 				pmcs_latch_status(pwp, sp, rptr->status, NULL,
2110 				    0, pptr->path);
2111 
2112 				if (sspcp->resc_v) {
2113 					/*
2114 					 * Point residual to the SSP_RESP_IU
2115 					 */
2116 					residp = (uint32_t *)(sspcp + 1);
2117 					/*
2118 					 * param contains the number of bytes
2119 					 * between where the SSP_RESP_IU may
2120 					 * or may not be and the residual.
2121 					 * Increment residp by the appropriate
2122 					 * number of words: (param+resc_pad)/4).
2123 					 */
2124 					residp += (LE_32(sspcp->param) +
2125 					    sspcp->resc_pad) /
2126 					    sizeof (uint32_t);
2127 					pmcs_prt(pwp, PMCS_PRT_DEBUG_UNDERFLOW,
2128 					    pptr, xp, "%s: tgt 0x%p "
2129 					    "residual %d for pkt 0x%p",
2130 					    __func__, (void *) xp, *residp,
2131 					    (void *) pkt);
2132 					ASSERT(LE_32(*residp) <=
2133 					    pkt->pkt_dma_len);
2134 					(void) pmcs_set_resid(pkt,
2135 					    pkt->pkt_dma_len, LE_32(*residp));
2136 				}
2137 			} else {
2138 				pmcs_print_entry(pwp, PMCS_PRT_DEBUG,
2139 				    "illegal SAS response", msg);
2140 				pkt->pkt_reason = CMD_TRAN_ERR;
2141 				goto out;
2142 			}
2143 		} else {
2144 			pmcs_latch_status(pwp, sp, STATUS_GOOD, NULL, 0,
2145 			    pptr->path);
2146 		}
2147 		if (pkt->pkt_dma_len) {
2148 			pkt->pkt_state |= STATE_XFERRED_DATA;
2149 		}
2150 	}
2151 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, xp,
2152 	    "%s: pkt %p tgt %u done reason=%x state=%x resid=%ld status=%x",
2153 	    __func__, (void *)pkt, xp->target_num, pkt->pkt_reason,
2154 	    pkt->pkt_state, pkt->pkt_resid, pkt->pkt_scbp[0]);
2155 
2156 	if (pwrk->state == PMCS_WORK_STATE_ABORTED) {
2157 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2158 		    "%s: scsi_pkt 0x%p aborted for PHY %s; work = 0x%p",
2159 		    __func__, (void *)pkt, pptr->path, (void *)pwrk);
2160 		aborted = B_TRUE;
2161 	}
2162 
2163 out:
2164 	pmcs_pwork(pwp, pwrk);
2165 	pmcs_dma_unload(pwp, sp);
2166 
2167 	/*
2168 	 * If the status is other than OK, determine if it's something that
2169 	 * is worth re-attempting enumeration.  If so, mark the PHY.
2170 	 */
2171 	if (sts != PMCOUT_STATUS_OK) {
2172 		pmcs_status_disposition(pptr, sts);
2173 	}
2174 
2175 	mutex_enter(&xp->statlock);
2176 
2177 	/*
2178 	 * If the device is gone, we only put this command on the completion
2179 	 * queue if the work structure is not marked dead.  If it's marked
2180 	 * dead, it will already have been put there.
2181 	 */
2182 	if (xp->dev_gone) {
2183 		mutex_exit(&xp->statlock);
2184 		if (!dead) {
2185 			mutex_enter(&xp->aqlock);
2186 			STAILQ_REMOVE(&xp->aq, sp, pmcs_cmd, cmd_next);
2187 			mutex_exit(&xp->aqlock);
2188 			pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, xp,
2189 			    "%s: Removing cmd 0x%p (htag 0x%x) from aq",
2190 			    __func__, (void *)sp, sp->cmd_tag);
2191 			mutex_enter(&pwp->cq_lock);
2192 			STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
2193 			mutex_exit(&pwp->cq_lock);
2194 			pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, xp,
2195 			    "%s: Completing command for dead target 0x%p",
2196 			    __func__, (void *)xp);
2197 		}
2198 		return;
2199 	}
2200 
2201 	ASSERT(xp->actv_cnt > 0);
2202 	if (--(xp->actv_cnt) == 0) {
2203 		if (xp->draining) {
2204 			pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, xp,
2205 			    "%s: waking up drain waiters", __func__);
2206 			cv_signal(&pwp->drain_cv);
2207 		}
2208 	}
2209 	mutex_exit(&xp->statlock);
2210 	if (dead == 0) {
2211 #ifdef	DEBUG
2212 		pmcs_cmd_t *wp;
2213 		mutex_enter(&xp->aqlock);
2214 		STAILQ_FOREACH(wp, &xp->aq, cmd_next) {
2215 			if (wp == sp) {
2216 				break;
2217 			}
2218 		}
2219 		ASSERT(wp != NULL);
2220 #else
2221 		mutex_enter(&xp->aqlock);
2222 #endif
2223 		pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, xp,
2224 		    "%s: Removing cmd 0x%p (htag 0x%x) from aq", __func__,
2225 		    (void *)sp, sp->cmd_tag);
2226 		STAILQ_REMOVE(&xp->aq, sp, pmcs_cmd, cmd_next);
2227 		if (aborted) {
2228 			pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2229 			    "%s: Aborted cmd for tgt 0x%p, signaling waiters",
2230 			    __func__, (void *)xp);
2231 			cv_signal(&xp->abort_cv);
2232 		}
2233 		mutex_exit(&xp->aqlock);
2234 	}
2235 
2236 	/*
2237 	 * If do_ds_recovery is set, we need to initiate device state
2238 	 * recovery.  In this case, we put this I/O back on the head of
2239 	 * the wait queue to run again after recovery is complete
2240 	 */
2241 	if (do_ds_recovery) {
2242 		mutex_enter(&xp->statlock);
2243 		pmcs_start_dev_state_recovery(xp, pptr);
2244 		mutex_exit(&xp->statlock);
2245 		pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, xp, "%s: Putting cmd 0x%p "
2246 		    "back on wq during recovery for tgt 0x%p", __func__,
2247 		    (void *)sp, (void *)xp);
2248 		mutex_enter(&xp->wqlock);
2249 		if (xp->wq_recovery_tail == NULL) {
2250 			STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
2251 		} else {
2252 			/*
2253 			 * If there are other I/Os waiting at the head due to
2254 			 * device state recovery, add this one in the right spot
2255 			 * to maintain proper order.
2256 			 */
2257 			STAILQ_INSERT_AFTER(&xp->wq, xp->wq_recovery_tail, sp,
2258 			    cmd_next);
2259 		}
2260 		xp->wq_recovery_tail = sp;
2261 		mutex_exit(&xp->wqlock);
2262 	} else {
2263 		/*
2264 		 * If we're not initiating device state recovery and this
2265 		 * command was not "dead", put it on the completion queue
2266 		 */
2267 		if (!dead) {
2268 			mutex_enter(&pwp->cq_lock);
2269 			STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
2270 			mutex_exit(&pwp->cq_lock);
2271 		}
2272 	}
2273 }
2274 
2275 /*
2276  * Run a SATA command (normal reads and writes),
2277  * or block and schedule a SATL interpretation
2278  * of the command.
2279  *
2280  * Called with pwrk lock held, returns unlocked.
2281  */
2282 
2283 static int
2284 pmcs_SATA_run(pmcs_cmd_t *sp, pmcwork_t *pwrk)
2285 {
2286 	pmcs_hw_t *pwp = CMD2PMC(sp);
2287 	struct scsi_pkt *pkt = CMD2PKT(sp);
2288 	pmcs_xscsi_t *xp;
2289 	uint8_t cdb_base, asc, tag;
2290 	uint32_t *ptr, iq, nblk, i, mtype;
2291 	fis_t fis;
2292 	size_t amt;
2293 	uint64_t lba;
2294 
2295 	xp = pwrk->xp;
2296 
2297 	/*
2298 	 * First, see if this is just a plain read/write command.
2299 	 * If not, we have to queue it up for processing, block
2300 	 * any additional commands from coming in, and wake up
2301 	 * the thread that will process this command.
2302 	 */
2303 	cdb_base = pkt->pkt_cdbp[0] & 0x1f;
2304 	if (cdb_base != SCMD_READ && cdb_base != SCMD_WRITE) {
2305 		pmcs_prt(pwp, PMCS_PRT_DEBUG1, NULL, NULL,
2306 		    "%s: special SATA cmd %p", __func__, (void *)sp);
2307 
2308 		ASSERT(xp->phy != NULL);
2309 		pmcs_pwork(pwp, pwrk);
2310 		pmcs_lock_phy(xp->phy);
2311 		mutex_enter(&xp->statlock);
2312 		xp->special_needed = 1; /* Set the special_needed flag */
2313 		STAILQ_INSERT_TAIL(&xp->sq, sp, cmd_next);
2314 		if (pmcs_run_sata_special(pwp, xp)) {
2315 			SCHEDULE_WORK(pwp, PMCS_WORK_SATA_RUN);
2316 		}
2317 		mutex_exit(&xp->statlock);
2318 		pmcs_unlock_phy(xp->phy);
2319 
2320 		return (PMCS_WQ_RUN_SUCCESS);
2321 	}
2322 
2323 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL, "%s: regular cmd", __func__);
2324 
2325 	mutex_enter(&xp->statlock);
2326 	if (!xp->assigned) {
2327 		mutex_exit(&xp->statlock);
2328 		return (PMCS_WQ_RUN_FAIL_OTHER);
2329 	}
2330 	if (xp->special_running || xp->special_needed || xp->recover_wait) {
2331 		mutex_exit(&xp->statlock);
2332 		mutex_enter(&xp->wqlock);
2333 		STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
2334 		mutex_exit(&xp->wqlock);
2335 		/*
2336 		 * By the time we get here the special
2337 		 * commands running or waiting to be run
2338 		 * may have come and gone, so kick our
2339 		 * worker to run the waiting queues
2340 		 * just in case.
2341 		 */
2342 		SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
2343 		return (PMCS_WQ_RUN_FAIL_OTHER);
2344 	}
2345 	lba = xp->capacity;
2346 	mutex_exit(&xp->statlock);
2347 
2348 	/*
2349 	 * Extract data length and lba parameters out of the command. The
2350 	 * function pmcs_SATA_rwparm returns a non-zero ASC value if the CDB
2351 	 * values are considered illegal.
2352 	 */
2353 	asc = pmcs_SATA_rwparm(pkt->pkt_cdbp, &nblk, &lba, lba);
2354 	if (asc) {
2355 		uint8_t sns[18];
2356 		bzero(sns, sizeof (sns));
2357 		sns[0] = 0xf0;
2358 		sns[2] = 0x5;
2359 		sns[12] = asc;
2360 		pmcs_latch_status(pwp, sp, STATUS_CHECK, sns, sizeof (sns),
2361 		    pwrk->phy->path);
2362 		pmcs_pwork(pwp, pwrk);
2363 		mutex_enter(&pwp->cq_lock);
2364 		STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
2365 		PMCS_CQ_RUN_LOCKED(pwp);
2366 		mutex_exit(&pwp->cq_lock);
2367 		return (PMCS_WQ_RUN_SUCCESS);
2368 	}
2369 
2370 	/*
2371 	 * If the command decodes as not moving any data, complete it here.
2372 	 */
2373 	amt = nblk;
2374 	amt <<= 9;
2375 	amt = pmcs_set_resid(pkt, amt, nblk << 9);
2376 	if (amt == 0) {
2377 		pmcs_latch_status(pwp, sp, STATUS_GOOD, NULL, 0,
2378 		    pwrk->phy->path);
2379 		pmcs_pwork(pwp, pwrk);
2380 		mutex_enter(&pwp->cq_lock);
2381 		STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
2382 		PMCS_CQ_RUN_LOCKED(pwp);
2383 		mutex_exit(&pwp->cq_lock);
2384 		return (PMCS_WQ_RUN_SUCCESS);
2385 	}
2386 
2387 	/*
2388 	 * Get an inbound queue entry for this I/O
2389 	 */
2390 	GET_IO_IQ_ENTRY(pwp, ptr, xp->phy->device_id, iq);
2391 	if (ptr == NULL) {
2392 		/*
2393 		 * This is a temporary failure not likely to unblocked by
2394 		 * commands completing as the test for scheduling the
2395 		 * restart of work is a per-device test.
2396 		 */
2397 		mutex_enter(&xp->wqlock);
2398 		STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
2399 		mutex_exit(&xp->wqlock);
2400 		pmcs_dma_unload(pwp, sp);
2401 		SCHEDULE_WORK(pwp, PMCS_WORK_RUN_QUEUES);
2402 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
2403 		    "%s: Failed to get IO IQ entry for tgt %d",
2404 		    __func__, xp->target_num);
2405 		return (PMCS_WQ_RUN_FAIL_RES);
2406 	}
2407 
2408 	/*
2409 	 * Get a tag.  At this point, hold statlock until the tagmap is
2410 	 * updated (just prior to sending the cmd to the hardware).
2411 	 */
2412 	mutex_enter(&xp->statlock);
2413 	for (tag = 0; tag < xp->qdepth; tag++) {
2414 		if ((xp->tagmap & (1 << tag)) == 0) {
2415 			break;
2416 		}
2417 	}
2418 
2419 	if (tag == xp->qdepth) {
2420 		mutex_exit(&xp->statlock);
2421 		mutex_exit(&pwp->iqp_lock[iq]);
2422 		mutex_enter(&xp->wqlock);
2423 		STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
2424 		mutex_exit(&xp->wqlock);
2425 		return (PMCS_WQ_RUN_FAIL_OTHER);
2426 	}
2427 
2428 	sp->cmd_satltag = (uint8_t)tag;
2429 
2430 	/*
2431 	 * Set up the command
2432 	 */
2433 	bzero(fis, sizeof (fis));
2434 	ptr[0] =
2435 	    LE_32(PMCS_IOMB_IN_SAS(PMCS_OQ_IODONE, PMCIN_SATA_HOST_IO_START));
2436 	ptr[1] = LE_32(pwrk->htag);
2437 	ptr[2] = LE_32(pwrk->phy->device_id);
2438 	ptr[3] = LE_32(amt);
2439 
2440 	if (xp->ncq) {
2441 		mtype = SATA_PROTOCOL_FPDMA | (tag << 16);
2442 		fis[0] = ((nblk & 0xff) << 24) | (C_BIT << 8) | FIS_REG_H2DEV;
2443 		if (cdb_base == SCMD_READ) {
2444 			fis[0] |= (READ_FPDMA_QUEUED << 16);
2445 		} else {
2446 			fis[0] |= (WRITE_FPDMA_QUEUED << 16);
2447 		}
2448 		fis[1] = (FEATURE_LBA << 24) | (lba & 0xffffff);
2449 		fis[2] = ((nblk & 0xff00) << 16) | ((lba >> 24) & 0xffffff);
2450 		fis[3] = tag << 3;
2451 	} else {
2452 		int op;
2453 		fis[0] = (C_BIT << 8) | FIS_REG_H2DEV;
2454 		if (xp->pio) {
2455 			mtype = SATA_PROTOCOL_PIO;
2456 			if (cdb_base == SCMD_READ) {
2457 				op = READ_SECTORS_EXT;
2458 			} else {
2459 				op = WRITE_SECTORS_EXT;
2460 			}
2461 		} else {
2462 			mtype = SATA_PROTOCOL_DMA;
2463 			if (cdb_base == SCMD_READ) {
2464 				op = READ_DMA_EXT;
2465 			} else {
2466 				op = WRITE_DMA_EXT;
2467 			}
2468 		}
2469 		fis[0] |= (op << 16);
2470 		fis[1] = (FEATURE_LBA << 24) | (lba & 0xffffff);
2471 		fis[2] = (lba >> 24) & 0xffffff;
2472 		fis[3] = nblk;
2473 	}
2474 
2475 	if (cdb_base == SCMD_READ) {
2476 		ptr[4] = LE_32(mtype | PMCIN_DATADIR_2_INI);
2477 	} else {
2478 		ptr[4] = LE_32(mtype | PMCIN_DATADIR_2_DEV);
2479 	}
2480 #ifdef	DEBUG
2481 	/*
2482 	 * Generate a PMCOUT_STATUS_XFER_CMD_FRAME_ISSUED
2483 	 * event when this goes out on the wire.
2484 	 */
2485 	ptr[4] |= PMCIN_MESSAGE_REPORT;
2486 #endif
2487 	for (i = 0; i < (sizeof (fis_t))/(sizeof (uint32_t)); i++) {
2488 		ptr[i+5] = LE_32(fis[i]);
2489 	}
2490 	if (pmcs_dma_load(pwp, sp, ptr)) {
2491 		mutex_exit(&xp->statlock);
2492 		mutex_exit(&pwp->iqp_lock[iq]);
2493 		mutex_enter(&xp->wqlock);
2494 		STAILQ_INSERT_HEAD(&xp->wq, sp, cmd_next);
2495 		mutex_exit(&xp->wqlock);
2496 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, xp,
2497 		    "%s: Failed to dma_load for tgt %d",
2498 		    __func__, xp->target_num);
2499 		return (PMCS_WQ_RUN_FAIL_RES);
2500 
2501 	}
2502 
2503 	pwrk->state = PMCS_WORK_STATE_ONCHIP;
2504 	mutex_exit(&pwrk->lock);
2505 	xp->tagmap |= (1 << tag);
2506 	xp->actv_cnt++;
2507 	if (xp->actv_cnt > xp->maxdepth) {
2508 		xp->maxdepth = xp->actv_cnt;
2509 		pmcs_prt(pwp, PMCS_PRT_DEBUG2, pwrk->phy, xp,
2510 		    "%s: max depth now %u", pwrk->phy->path, xp->maxdepth);
2511 	}
2512 	mutex_exit(&xp->statlock);
2513 	mutex_enter(&xp->aqlock);
2514 	STAILQ_INSERT_TAIL(&xp->aq, sp, cmd_next);
2515 	mutex_exit(&xp->aqlock);
2516 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, NULL, NULL,
2517 	    "%s: giving pkt %p to hardware", __func__, (void *)pkt);
2518 #ifdef DEBUG
2519 	pmcs_print_entry(pwp, PMCS_PRT_DEBUG3, "SATA INI Message", ptr);
2520 #endif
2521 	INC_IQ_ENTRY(pwp, iq);
2522 
2523 	return (PMCS_WQ_RUN_SUCCESS);
2524 }
2525 
2526 /*
2527  * Complete a SATA command.  Called with pwrk lock held.
2528  */
2529 void
2530 pmcs_SATA_done(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *msg)
2531 {
2532 	pmcs_cmd_t *sp = pwrk->arg;
2533 	struct scsi_pkt *pkt = CMD2PKT(sp);
2534 	pmcs_phy_t *pptr = pwrk->phy;
2535 	int dead;
2536 	uint32_t sts;
2537 	pmcs_xscsi_t *xp;
2538 	boolean_t aborted = B_FALSE;
2539 
2540 	xp = pwrk->xp;
2541 	ASSERT(xp != NULL);
2542 
2543 	DTRACE_PROBE4(pmcs__io__done, uint64_t, pkt->pkt_dma_len, int,
2544 	    (pkt->pkt_dma_flags & DDI_DMA_READ) != 0, hrtime_t, pwrk->start,
2545 	    hrtime_t, gethrtime());
2546 
2547 	dead = pwrk->dead;
2548 
2549 	if (msg) {
2550 		sts = LE_32(msg[2]);
2551 	} else {
2552 		sts = 0;
2553 	}
2554 
2555 	if (dead != 0) {
2556 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp, "%s: dead cmd tag "
2557 		    "0x%x for %s", __func__, pwrk->htag, pptr->path);
2558 		goto out;
2559 	}
2560 	if ((pwrk->state == PMCS_WORK_STATE_TIMED_OUT) &&
2561 	    (sts != PMCOUT_STATUS_ABORTED)) {
2562 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2563 		    "%s: cmd 0x%p (tag 0x%x) timed out for %s",
2564 		    __func__, (void *)sp, pwrk->htag, pptr->path);
2565 		CMD2PKT(sp)->pkt_scbp[0] = STATUS_GOOD;
2566 		/* pkt_reason already set to CMD_TIMEOUT */
2567 		ASSERT(CMD2PKT(sp)->pkt_reason == CMD_TIMEOUT);
2568 		CMD2PKT(sp)->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
2569 		    STATE_SENT_CMD;
2570 		CMD2PKT(sp)->pkt_statistics |= STAT_TIMEOUT;
2571 		goto out;
2572 	}
2573 
2574 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, xp, "%s: pkt %p tgt %u done",
2575 	    __func__, (void *)pkt, xp->target_num);
2576 
2577 	/*
2578 	 * If the status isn't okay but not underflow,
2579 	 * step to the side and parse the (possible) error.
2580 	 */
2581 #ifdef DEBUG
2582 	if (msg) {
2583 		pmcs_print_entry(pwp, PMCS_PRT_DEBUG3, "Outbound Message", msg);
2584 	}
2585 #endif
2586 	if (!msg) {
2587 		goto out;
2588 	}
2589 
2590 	/*
2591 	 * If the status isn't okay or we got a FIS response of some kind,
2592 	 * step to the side and parse the (possible) error.
2593 	 */
2594 	if ((sts != PMCOUT_STATUS_OK) || (LE_32(msg[3]) != 0)) {
2595 		if (sts == PMCOUT_STATUS_IO_DS_NON_OPERATIONAL) {
2596 			mutex_exit(&pwrk->lock);
2597 			pmcs_lock_phy(pptr);
2598 			mutex_enter(&xp->statlock);
2599 			if ((xp->resetting == 0) && (xp->reset_success != 0) &&
2600 			    (xp->reset_wait == 0)) {
2601 				mutex_exit(&xp->statlock);
2602 				if (pmcs_reset_phy(pwp, pptr,
2603 				    PMCS_PHYOP_LINK_RESET) != 0) {
2604 					pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2605 					    "%s: PHY (%s) Local Control/Link "
2606 					    "Reset FAILED as part of error "
2607 					    "recovery", __func__, pptr->path);
2608 				}
2609 				mutex_enter(&xp->statlock);
2610 			}
2611 			mutex_exit(&xp->statlock);
2612 			pmcs_unlock_phy(pptr);
2613 			mutex_enter(&pwrk->lock);
2614 		}
2615 		pmcs_ioerror(pwp, SATA, pwrk, msg);
2616 	} else {
2617 		pmcs_latch_status(pwp, sp, STATUS_GOOD, NULL, 0,
2618 		    pwrk->phy->path);
2619 		pkt->pkt_state |= STATE_XFERRED_DATA;
2620 		pkt->pkt_resid = 0;
2621 	}
2622 
2623 	pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, xp,
2624 	    "%s: pkt %p tgt %u done reason=%x state=%x resid=%ld status=%x",
2625 	    __func__, (void *)pkt, xp->target_num, pkt->pkt_reason,
2626 	    pkt->pkt_state, pkt->pkt_resid, pkt->pkt_scbp[0]);
2627 
2628 	if (pwrk->state == PMCS_WORK_STATE_ABORTED) {
2629 		pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2630 		    "%s: scsi_pkt 0x%p aborted for PHY %s; work = 0x%p",
2631 		    __func__, (void *)pkt, pptr->path, (void *)pwrk);
2632 		aborted = B_TRUE;
2633 	}
2634 
2635 out:
2636 	pmcs_pwork(pwp, pwrk);
2637 	pmcs_dma_unload(pwp, sp);
2638 
2639 	/*
2640 	 * If the status is other than OK, determine if it's something that
2641 	 * is worth re-attempting enumeration.  If so, mark the PHY.
2642 	 */
2643 	if (sts != PMCOUT_STATUS_OK) {
2644 		pmcs_status_disposition(pptr, sts);
2645 	}
2646 
2647 	mutex_enter(&xp->statlock);
2648 	xp->tagmap &= ~(1 << sp->cmd_satltag);
2649 
2650 	if (xp->dev_gone) {
2651 		mutex_exit(&xp->statlock);
2652 		if (!dead) {
2653 			mutex_enter(&xp->aqlock);
2654 			STAILQ_REMOVE(&xp->aq, sp, pmcs_cmd, cmd_next);
2655 			mutex_exit(&xp->aqlock);
2656 			pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, xp,
2657 			    "%s: Removing cmd 0x%p (htag 0x%x) from aq",
2658 			    __func__, (void *)sp, sp->cmd_tag);
2659 			mutex_enter(&pwp->cq_lock);
2660 			STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
2661 			mutex_exit(&pwp->cq_lock);
2662 			pmcs_prt(pwp, PMCS_PRT_DEBUG2, pptr, xp,
2663 			    "%s: Completing command for dead target 0x%p",
2664 			    __func__, (void *)xp);
2665 		}
2666 		return;
2667 	}
2668 
2669 	ASSERT(xp->actv_cnt > 0);
2670 	if (--(xp->actv_cnt) == 0) {
2671 		if (xp->draining) {
2672 			pmcs_prt(pwp, PMCS_PRT_DEBUG1, pptr, xp,
2673 			    "%s: waking up drain waiters", __func__);
2674 			cv_signal(&pwp->drain_cv);
2675 		} else if (xp->special_needed) {
2676 			SCHEDULE_WORK(pwp, PMCS_WORK_SATA_RUN);
2677 		}
2678 	}
2679 	mutex_exit(&xp->statlock);
2680 
2681 	if (dead == 0) {
2682 #ifdef	DEBUG
2683 		pmcs_cmd_t *wp;
2684 		mutex_enter(&xp->aqlock);
2685 		STAILQ_FOREACH(wp, &xp->aq, cmd_next) {
2686 			if (wp == sp) {
2687 				break;
2688 			}
2689 		}
2690 		ASSERT(wp != NULL);
2691 #else
2692 		mutex_enter(&xp->aqlock);
2693 #endif
2694 		STAILQ_REMOVE(&xp->aq, sp, pmcs_cmd, cmd_next);
2695 		if (aborted) {
2696 			pmcs_prt(pwp, PMCS_PRT_DEBUG, pptr, xp,
2697 			    "%s: Aborted cmd for tgt 0x%p, signaling waiters",
2698 			    __func__, (void *)xp);
2699 			cv_signal(&xp->abort_cv);
2700 		}
2701 		mutex_exit(&xp->aqlock);
2702 		mutex_enter(&pwp->cq_lock);
2703 		STAILQ_INSERT_TAIL(&pwp->cq, sp, cmd_next);
2704 		mutex_exit(&pwp->cq_lock);
2705 	}
2706 }
2707 
2708 static uint8_t
2709 pmcs_SATA_rwparm(uint8_t *cdb, uint32_t *xfr, uint64_t *lba, uint64_t lbamax)
2710 {
2711 	uint8_t asc = 0;
2712 	switch (cdb[0]) {
2713 	case SCMD_READ_G5:
2714 	case SCMD_WRITE_G5:
2715 		*xfr =
2716 		    (((uint32_t)cdb[10]) <<  24) |
2717 		    (((uint32_t)cdb[11]) <<  16) |
2718 		    (((uint32_t)cdb[12]) <<   8) |
2719 		    ((uint32_t)cdb[13]);
2720 		*lba =
2721 		    (((uint64_t)cdb[2]) << 56) |
2722 		    (((uint64_t)cdb[3]) << 48) |
2723 		    (((uint64_t)cdb[4]) << 40) |
2724 		    (((uint64_t)cdb[5]) << 32) |
2725 		    (((uint64_t)cdb[6]) << 24) |
2726 		    (((uint64_t)cdb[7]) << 16) |
2727 		    (((uint64_t)cdb[8]) <<  8) |
2728 		    ((uint64_t)cdb[9]);
2729 		/* Check for illegal bits */
2730 		if (cdb[15]) {
2731 			asc = 0x24;	/* invalid field in cdb */
2732 		}
2733 		break;
2734 	case SCMD_READ_G4:
2735 	case SCMD_WRITE_G4:
2736 		*xfr =
2737 		    (((uint32_t)cdb[6]) <<  16) |
2738 		    (((uint32_t)cdb[7]) <<   8) |
2739 		    ((uint32_t)cdb[8]);
2740 		*lba =
2741 		    (((uint32_t)cdb[2]) << 24) |
2742 		    (((uint32_t)cdb[3]) << 16) |
2743 		    (((uint32_t)cdb[4]) <<  8) |
2744 		    ((uint32_t)cdb[5]);
2745 		/* Check for illegal bits */
2746 		if (cdb[11]) {
2747 			asc = 0x24;	/* invalid field in cdb */
2748 		}
2749 		break;
2750 	case SCMD_READ_G1:
2751 	case SCMD_WRITE_G1:
2752 		*xfr = (((uint32_t)cdb[7]) <<  8) | ((uint32_t)cdb[8]);
2753 		*lba =
2754 		    (((uint32_t)cdb[2]) << 24) |
2755 		    (((uint32_t)cdb[3]) << 16) |
2756 		    (((uint32_t)cdb[4]) <<  8) |
2757 		    ((uint32_t)cdb[5]);
2758 		/* Check for illegal bits */
2759 		if (cdb[9]) {
2760 			asc = 0x24;	/* invalid field in cdb */
2761 		}
2762 		break;
2763 	case SCMD_READ:
2764 	case SCMD_WRITE:
2765 		*xfr = cdb[4];
2766 		if (*xfr == 0) {
2767 			*xfr = 256;
2768 		}
2769 		*lba =
2770 		    (((uint32_t)cdb[1] & 0x1f) << 16) |
2771 		    (((uint32_t)cdb[2]) << 8) |
2772 		    ((uint32_t)cdb[3]);
2773 		/* Check for illegal bits */
2774 		if (cdb[5]) {
2775 			asc = 0x24;	/* invalid field in cdb */
2776 		}
2777 		break;
2778 	}
2779 
2780 	if (asc == 0) {
2781 		if ((*lba + *xfr) > lbamax) {
2782 			asc = 0x21;	/* logical block out of range */
2783 		}
2784 	}
2785 	return (asc);
2786 }
2787 
2788 /*
2789  * Called with pwrk lock held.
2790  */
2791 static void
2792 pmcs_ioerror(pmcs_hw_t *pwp, pmcs_dtype_t t, pmcwork_t *pwrk, uint32_t *w)
2793 {
2794 	static uint8_t por[] = {
2795 	    0xf0, 0x0, 0x6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x28
2796 	};
2797 	static uint8_t parity[] = {
2798 	    0xf0, 0x0, 0xb, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x47, 5
2799 	};
2800 	const char *msg;
2801 	char buf[20];
2802 	pmcs_cmd_t *sp = pwrk->arg;
2803 	pmcs_phy_t *phyp = pwrk->phy;
2804 	struct scsi_pkt *pkt = CMD2PKT(sp);
2805 	uint32_t status;
2806 	uint32_t resid;
2807 
2808 	ASSERT(w != NULL);
2809 	status = LE_32(w[2]);
2810 	resid = LE_32(w[3]);
2811 
2812 	msg = pmcs_status_str(status);
2813 	if (msg == NULL) {
2814 		(void) snprintf(buf, sizeof (buf), "Error 0x%x", status);
2815 		msg = buf;
2816 	}
2817 
2818 	if (status != PMCOUT_STATUS_OK) {
2819 		pmcs_prt(pwp, PMCS_PRT_DEBUG1, phyp, NULL,
2820 		    "%s: device %s tag 0x%x status %s @ %llu", __func__,
2821 		    phyp->path, pwrk->htag, msg,
2822 		    (unsigned long long)gethrtime());
2823 	}
2824 
2825 	pkt->pkt_reason = CMD_CMPLT;		/* default reason */
2826 
2827 	switch (status) {
2828 	case PMCOUT_STATUS_OK:
2829 		if (t == SATA) {
2830 			int i;
2831 			fis_t fis;
2832 			for (i = 0; i < sizeof (fis) / sizeof (fis[0]); i++) {
2833 				fis[i] = LE_32(w[4+i]);
2834 			}
2835 			if ((fis[0] & 0xff) != FIS_REG_D2H) {
2836 				pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
2837 				    "unexpected fis code 0x%x", fis[0] & 0xff);
2838 			} else {
2839 				pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
2840 				    "FIS ERROR");
2841 				pmcs_fis_dump(pwp, fis);
2842 			}
2843 			pkt->pkt_reason = CMD_TRAN_ERR;
2844 			break;
2845 		}
2846 		pmcs_latch_status(pwp, sp, STATUS_GOOD, NULL, 0, phyp->path);
2847 		break;
2848 
2849 	case PMCOUT_STATUS_ABORTED:
2850 		/*
2851 		 * Command successfully aborted.
2852 		 */
2853 		if (phyp->dead) {
2854 			pkt->pkt_reason = CMD_DEV_GONE;
2855 			pkt->pkt_state = STATE_GOT_BUS;
2856 		} else if (pwrk->ssp_event != 0) {
2857 			pkt->pkt_reason = CMD_TRAN_ERR;
2858 			pkt->pkt_state = STATE_GOT_BUS;
2859 		} else if (pwrk->state == PMCS_WORK_STATE_TIMED_OUT) {
2860 			pkt->pkt_reason = CMD_TIMEOUT;
2861 			pkt->pkt_statistics |= STAT_TIMEOUT;
2862 			pkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
2863 			    STATE_SENT_CMD;
2864 		} else {
2865 			pkt->pkt_reason = CMD_ABORTED;
2866 			pkt->pkt_statistics |= STAT_ABORTED;
2867 			pkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
2868 			    STATE_SENT_CMD;
2869 		}
2870 
2871 		/*
2872 		 * PMCS_WORK_STATE_TIMED_OUT doesn't need to be preserved past
2873 		 * this point, so go ahead and mark it as aborted.
2874 		 */
2875 		pwrk->state = PMCS_WORK_STATE_ABORTED;
2876 		break;
2877 
2878 	case PMCOUT_STATUS_UNDERFLOW:
2879 		/*
2880 		 * This will only get called for SATA
2881 		 */
2882 		pkt->pkt_resid = resid;
2883 		if (pkt->pkt_dma_len < pkt->pkt_resid) {
2884 			(void) pmcs_set_resid(pkt, pkt->pkt_dma_len, resid);
2885 		}
2886 		pmcs_latch_status(pwp, sp, STATUS_GOOD, NULL, 0, phyp->path);
2887 		break;
2888 
2889 	case PMCOUT_STATUS_NO_DEVICE:
2890 	case PMCOUT_STATUS_XFER_ERROR_SATA_LINK_TIMEOUT:
2891 		pkt->pkt_reason = CMD_DEV_GONE;
2892 		break;
2893 
2894 	case PMCOUT_STATUS_OPEN_CNX_ERROR_WRONG_DESTINATION:
2895 		/*
2896 		 * Need to do rediscovery. We probably have
2897 		 * the wrong device (disk swap), so kill
2898 		 * this one.
2899 		 */
2900 	case PMCOUT_STATUS_OPEN_CNX_PROTOCOL_NOT_SUPPORTED:
2901 	case PMCOUT_STATUS_OPEN_CNX_ERROR_ZONE_VIOLATION:
2902 	case PMCOUT_STATUS_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED:
2903 	case PMCOUT_STATUS_OPEN_CNX_ERROR_UNKNOWN_ERROR:
2904 		/*
2905 		 * Need to do rediscovery.
2906 		 */
2907 		if (!phyp->dead) {
2908 			mutex_exit(&pwrk->lock);
2909 			pmcs_lock_phy(pwrk->phy);
2910 			pmcs_kill_changed(pwp, pwrk->phy, 0);
2911 			pmcs_unlock_phy(pwrk->phy);
2912 			mutex_enter(&pwrk->lock);
2913 			pkt->pkt_reason = CMD_INCOMPLETE;
2914 			pkt->pkt_state = STATE_GOT_BUS;
2915 		} else {
2916 			pkt->pkt_reason = CMD_DEV_GONE;
2917 		}
2918 		break;
2919 
2920 	case PMCOUT_STATUS_OPEN_CNX_ERROR_BREAK:
2921 	case PMCOUT_STATUS_OPEN_CNX_ERROR_IT_NEXUS_LOSS:
2922 	case PMCOUT_STATUS_OPENCNX_ERROR_BAD_DESTINATION:
2923 	case PMCOUT_STATUS_IO_XFER_ERROR_NAK_RECEIVED:
2924 		/* cmd is pending on the target */
2925 	case PMCOUT_STATUS_XFER_ERROR_OFFSET_MISMATCH:
2926 	case PMCOUT_STATUS_XFER_ERROR_REJECTED_NCQ_MODE:
2927 		/* transitory - commands sent while in NCQ failure mode */
2928 	case PMCOUT_STATUS_XFER_ERROR_ABORTED_NCQ_MODE:
2929 		/* NCQ failure */
2930 	case PMCOUT_STATUS_IO_PORT_IN_RESET:
2931 	case PMCOUT_STATUS_XFER_ERR_BREAK:
2932 	case PMCOUT_STATUS_XFER_ERR_PHY_NOT_READY:
2933 		pkt->pkt_reason = CMD_INCOMPLETE;
2934 		pkt->pkt_state = STATE_GOT_BUS;
2935 		break;
2936 
2937 	case PMCOUT_STATUS_IO_XFER_OPEN_RETRY_TIMEOUT:
2938 		pmcs_latch_status(pwp, sp, STATUS_BUSY, NULL, 0, phyp->path);
2939 		break;
2940 
2941 	case PMCOUT_STATUS_OPEN_CNX_ERROR_STP_RESOURCES_BUSY:
2942 		/* synthesize a RESERVATION CONFLICT */
2943 		pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, phyp->target,
2944 		    "%s: Potential affiliation active on 0x%" PRIx64, __func__,
2945 		    pmcs_barray2wwn(phyp->sas_address));
2946 		pmcs_latch_status(pwp, sp, STATUS_RESERVATION_CONFLICT, NULL,
2947 		    0, phyp->path);
2948 		break;
2949 
2950 	case PMCOUT_STATUS_XFER_ERROR_ABORTED_DUE_TO_SRST:
2951 		/* synthesize a power-on/reset */
2952 		pmcs_latch_status(pwp, sp, STATUS_CHECK, por, sizeof (por),
2953 		    phyp->path);
2954 		break;
2955 
2956 	case PMCOUT_STATUS_XFER_ERROR_UNEXPECTED_PHASE:
2957 	case PMCOUT_STATUS_XFER_ERROR_RDY_OVERRUN:
2958 	case PMCOUT_STATUS_XFER_ERROR_RDY_NOT_EXPECTED:
2959 	case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT:
2960 	case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NACK:
2961 	case PMCOUT_STATUS_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK:
2962 		/* synthesize a PARITY ERROR */
2963 		pmcs_latch_status(pwp, sp, STATUS_CHECK, parity,
2964 		    sizeof (parity), phyp->path);
2965 		break;
2966 
2967 	case PMCOUT_STATUS_IO_XFER_ERROR_DMA:
2968 	case PMCOUT_STATUS_IO_NOT_VALID:
2969 	case PMCOUT_STATUS_PROG_ERROR:
2970 	case PMCOUT_STATUS_XFER_ERROR_PEER_ABORTED:
2971 	case PMCOUT_STATUS_XFER_ERROR_SATA: /* non-NCQ failure */
2972 	default:
2973 		pkt->pkt_reason = CMD_TRAN_ERR;
2974 		break;
2975 	}
2976 }
2977 
2978 /*
2979  * Latch up SCSI status
2980  */
2981 
2982 void
2983 pmcs_latch_status(pmcs_hw_t *pwp, pmcs_cmd_t *sp, uint8_t status,
2984     uint8_t *snsp, size_t snslen, char *path)
2985 {
2986 	static const char c1[] =
2987 	    "%s: Status Byte 0x%02x for CDB0=0x%02x (%02x %02x %02x) "
2988 	    "HTAG 0x%x @ %llu";
2989 	static const char c2[] =
2990 	    "%s: Status Byte 0x%02x for CDB0=0x%02x HTAG 0x%x @ %llu";
2991 
2992 	CMD2PKT(sp)->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET |
2993 	    STATE_SENT_CMD | STATE_GOT_STATUS;
2994 	CMD2PKT(sp)->pkt_scbp[0] = status;
2995 
2996 	if (status == STATUS_CHECK && snsp &&
2997 	    (size_t)SCSA_STSLEN(sp) >= sizeof (struct scsi_arq_status)) {
2998 		struct scsi_arq_status *aqp =
2999 		    (void *) CMD2PKT(sp)->pkt_scbp;
3000 		size_t amt = sizeof (struct scsi_extended_sense);
3001 		uint8_t key = scsi_sense_key(snsp);
3002 		uint8_t asc = scsi_sense_asc(snsp);
3003 		uint8_t ascq = scsi_sense_ascq(snsp);
3004 		if (amt > snslen) {
3005 			amt = snslen;
3006 		}
3007 		pmcs_prt(pwp, PMCS_PRT_DEBUG_SCSI_STATUS, NULL, NULL, c1, path,
3008 		    status, CMD2PKT(sp)->pkt_cdbp[0] & 0xff, key, asc, ascq,
3009 		    sp->cmd_tag, (unsigned long long)gethrtime());
3010 		CMD2PKT(sp)->pkt_state |= STATE_ARQ_DONE;
3011 		(*(uint8_t *)&aqp->sts_rqpkt_status) = STATUS_GOOD;
3012 		aqp->sts_rqpkt_statistics = 0;
3013 		aqp->sts_rqpkt_reason = CMD_CMPLT;
3014 		aqp->sts_rqpkt_state = STATE_GOT_BUS |
3015 		    STATE_GOT_TARGET | STATE_SENT_CMD |
3016 		    STATE_XFERRED_DATA | STATE_GOT_STATUS;
3017 		(void) memcpy(&aqp->sts_sensedata, snsp, amt);
3018 		if (aqp->sts_sensedata.es_class != CLASS_EXTENDED_SENSE) {
3019 			aqp->sts_rqpkt_reason = CMD_TRAN_ERR;
3020 			aqp->sts_rqpkt_state = 0;
3021 			aqp->sts_rqpkt_resid =
3022 			    sizeof (struct scsi_extended_sense);
3023 		} else {
3024 			aqp->sts_rqpkt_resid =
3025 			    sizeof (struct scsi_extended_sense) - amt;
3026 		}
3027 	} else if (status) {
3028 		pmcs_prt(pwp, PMCS_PRT_DEBUG_SCSI_STATUS, NULL, NULL, c2,
3029 		    path, status, CMD2PKT(sp)->pkt_cdbp[0] & 0xff,
3030 		    sp->cmd_tag, (unsigned long long)gethrtime());
3031 	}
3032 
3033 	CMD2PKT(sp)->pkt_reason = CMD_CMPLT;
3034 }
3035 
3036 /*
3037  * Calculate and set packet residual and return the amount
3038  * left over after applying various filters.
3039  */
3040 size_t
3041 pmcs_set_resid(struct scsi_pkt *pkt, size_t amt, uint32_t cdbamt)
3042 {
3043 	pkt->pkt_resid = cdbamt;
3044 	if (amt > pkt->pkt_resid) {
3045 		amt = pkt->pkt_resid;
3046 	}
3047 	if (amt > pkt->pkt_dma_len) {
3048 		amt = pkt->pkt_dma_len;
3049 	}
3050 	return (amt);
3051 }
3052 
3053 /*
3054  * Return the existing target softstate if there is one.  If there is,
3055  * the PHY is locked as well and that lock must be freed by the caller
3056  * after the target/PHY linkage is established.
3057  */
3058 pmcs_xscsi_t *
3059 pmcs_get_target(pmcs_iport_t *iport, char *tgt_port)
3060 {
3061 	pmcs_hw_t *pwp = iport->pwp;
3062 	pmcs_phy_t *phyp;
3063 	pmcs_xscsi_t *tgt;
3064 	uint64_t wwn;
3065 	char unit_address[PMCS_MAX_UA_SIZE];
3066 	int ua_form = 1;
3067 
3068 	/*
3069 	 * Find the PHY for this target
3070 	 */
3071 	phyp = pmcs_find_phy_by_sas_address(pwp, iport, NULL, tgt_port);
3072 	if (phyp == NULL) {
3073 		pmcs_prt(pwp, PMCS_PRT_DEBUG3, NULL, NULL,
3074 		    "%s: No PHY for target @ %s", __func__, tgt_port);
3075 		return (NULL);
3076 	}
3077 
3078 	tgt = ddi_soft_state_bystr_get(iport->tgt_sstate, tgt_port);
3079 
3080 	if (tgt) {
3081 		/*
3082 		 * There's already a target.  Check its PHY pointer to see
3083 		 * if we need to clear the old linkages
3084 		 */
3085 		if (tgt->phy && (tgt->phy != phyp)) {
3086 			pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
3087 			    "%s: Target PHY updated from %p to %p", __func__,
3088 			    (void *)tgt->phy, (void *)phyp);
3089 			if (!IS_ROOT_PHY(tgt->phy)) {
3090 				pmcs_dec_phy_ref_count(tgt->phy);
3091 				pmcs_inc_phy_ref_count(phyp);
3092 			}
3093 			tgt->phy->target = NULL;
3094 		}
3095 
3096 		tgt->phy = phyp;
3097 		phyp->target = tgt;
3098 		return (tgt);
3099 	}
3100 
3101 	/*
3102 	 * Make sure the PHY we found is on the correct iport
3103 	 */
3104 	if (phyp->iport != iport) {
3105 		pmcs_prt(pwp, PMCS_PRT_DEBUG, phyp, NULL,
3106 		    "%s: No target at %s on this iport", __func__, tgt_port);
3107 		pmcs_unlock_phy(phyp);
3108 		return (NULL);
3109 	}
3110 
3111 	/*
3112 	 * Allocate the new softstate
3113 	 */
3114 	wwn = pmcs_barray2wwn(phyp->sas_address);
3115 	(void) scsi_wwn_to_wwnstr(wwn, ua_form, unit_address);
3116 
3117 	if (ddi_soft_state_bystr_zalloc(iport->tgt_sstate, unit_address) !=
3118 	    DDI_SUCCESS) {
3119 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
3120 		    "%s: Couldn't alloc softstate for device at %s",
3121 		    __func__, unit_address);
3122 		pmcs_unlock_phy(phyp);
3123 		return (NULL);
3124 	}
3125 
3126 	tgt = ddi_soft_state_bystr_get(iport->tgt_sstate, unit_address);
3127 	STAILQ_INIT(&tgt->wq);
3128 	STAILQ_INIT(&tgt->aq);
3129 	STAILQ_INIT(&tgt->sq);
3130 	mutex_init(&tgt->statlock, NULL, MUTEX_DRIVER,
3131 	    DDI_INTR_PRI(pwp->intr_pri));
3132 	mutex_init(&tgt->wqlock, NULL, MUTEX_DRIVER,
3133 	    DDI_INTR_PRI(pwp->intr_pri));
3134 	mutex_init(&tgt->aqlock, NULL, MUTEX_DRIVER,
3135 	    DDI_INTR_PRI(pwp->intr_pri));
3136 	cv_init(&tgt->reset_cv, NULL, CV_DRIVER, NULL);
3137 	cv_init(&tgt->abort_cv, NULL, CV_DRIVER, NULL);
3138 	list_create(&tgt->lun_list, sizeof (pmcs_lun_t),
3139 	    offsetof(pmcs_lun_t, lun_list_next));
3140 	tgt->qdepth = 1;
3141 	tgt->target_num = PMCS_INVALID_TARGET_NUM;
3142 	bcopy(unit_address, tgt->unit_address, PMCS_MAX_UA_SIZE);
3143 	tgt->pwp = pwp;
3144 	tgt->ua = strdup(iport->ua);
3145 	tgt->phy = phyp;
3146 	ASSERT((phyp->target == NULL) || (phyp->target == tgt));
3147 	if (phyp->target == NULL) {
3148 		phyp->target = tgt;
3149 	}
3150 
3151 	/*
3152 	 * Don't allocate LUN softstate for SMP targets
3153 	 */
3154 	if (phyp->dtype == EXPANDER) {
3155 		return (tgt);
3156 	}
3157 
3158 	if (ddi_soft_state_bystr_init(&tgt->lun_sstate,
3159 	    sizeof (pmcs_lun_t), PMCS_LUN_SSTATE_SZ) != 0) {
3160 		pmcs_prt(pwp, PMCS_PRT_DEBUG_CONFIG, phyp, tgt,
3161 		    "%s: LUN soft_state_bystr_init failed", __func__);
3162 		ddi_soft_state_bystr_free(iport->tgt_sstate, tgt_port);
3163 		pmcs_unlock_phy(phyp);
3164 		return (NULL);
3165 	}
3166 
3167 	return (tgt);
3168 }
3169