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