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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * 1394 mass storage SBP-2 driver routines
30  */
31 
32 #include <sys/param.h>
33 #include <sys/errno.h>
34 #include <sys/cred.h>
35 #include <sys/conf.h>
36 #include <sys/modctl.h>
37 #include <sys/stat.h>
38 #include <sys/ddi.h>
39 #include <sys/sunddi.h>
40 
41 #include <sys/1394/targets/scsa1394/impl.h>
42 #include <sys/1394/targets/scsa1394/cmd.h>
43 #include <sys/sbp2/bus.h>
44 #include <sys/sbp2/driver.h>
45 
46 static void	scsa1394_sbp2_detect_symbios(scsa1394_state_t *);
47 static void	scsa1394_sbp2_worker_thread(void *);
48 static void	scsa1394_sbp2_status_cb(void *, sbp2_task_t *);
49 static void	scsa1394_sbp2_seg2pt_default(scsa1394_lun_t *,
50 		scsa1394_cmd_t *);
51 static void	scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *,
52 		scsa1394_cmd_t *);
53 static void	scsa1394_sbp2_req_status(scsa1394_lun_t *);
54 static void	scsa1394_sbp2_status_proc(scsa1394_lun_t *, scsa1394_cmd_t *,
55 		scsa1394_status_t *);
56 static int	scsa1394_sbp2_conv_status(scsa1394_cmd_t *,
57 		scsa1394_status_t *);
58 static void	scsa1394_sbp2_reset_proc(scsa1394_lun_t *, int,
59 		scsa1394_cmd_t *);
60 static boolean_t scsa1394_sbp2_logged_in(scsa1394_lun_t *);
61 
62 extern sbp2_bus_t scsa1394_sbp2_bus;
63 
64 /* tunables */
65 uint_t scsa1394_sbp2_max_payload_sub = 2;
66 extern int scsa1394_symbios_size_max;
67 extern int scsa1394_symbios_page_size;
68 extern int scsa1394_wrka_symbios;
69 
70 /* symbios workaround will be applied unless device is on this list */
71 scsa1394_bw_list_t scsa1394_sbp2_symbios_whitelist[] = {
72 	{ SCSA1394_BW_ONE, 0x0a27 },		/* Apple */
73 	{ SCSA1394_BW_ONE, 0xd04b }		/* LaCie */
74 };
75 
76 /*
77  *
78  * --- SBP-2 routines
79  *
80  */
81 int
82 scsa1394_sbp2_attach(scsa1394_state_t *sp)
83 {
84 	sbp2_tgt_t	*tp;
85 	scsa1394_lun_t	*lp;
86 	int		i;
87 
88 	/*
89 	 * target
90 	 */
91 	if (sbp2_tgt_init(sp, &scsa1394_sbp2_bus, NLUNS_PER_TARGET,
92 	    &sp->s_tgt) != SBP2_SUCCESS) {
93 		return (DDI_FAILURE);
94 	}
95 	tp = sp->s_tgt;
96 
97 	/*
98 	 * luns
99 	 */
100 	sp->s_nluns = tp->t_nluns;
101 	sp->s_lun = kmem_zalloc(sp->s_nluns * sizeof (scsa1394_lun_t),
102 	    KM_SLEEP);
103 
104 	for (i = 0; i < sp->s_nluns; i++) {
105 		lp = &sp->s_lun[i];
106 
107 		mutex_init(&lp->l_mutex, NULL, MUTEX_DRIVER,
108 		    sp->s_attachinfo.iblock_cookie);
109 
110 		lp->l_rmb_orig = -1;
111 		lp->l_lun = &tp->t_lun[i];
112 		lp->l_sp = sp;
113 		lp->l_lba_size = DEV_BSIZE;
114 	}
115 
116 	scsa1394_sbp2_detect_symbios(sp);
117 
118 	return (DDI_SUCCESS);
119 }
120 
121 void
122 scsa1394_sbp2_detach(scsa1394_state_t *sp)
123 {
124 	int		i;
125 	scsa1394_lun_t	*lp;
126 
127 	for (i = 0; i < sp->s_nluns; i++) {
128 		lp = &sp->s_lun[i];
129 		if (lp->l_sp != NULL) {
130 			mutex_destroy(&lp->l_mutex);
131 		}
132 	}
133 
134 	kmem_free(sp->s_lun, sp->s_nluns * sizeof (scsa1394_lun_t));
135 	sbp2_tgt_fini(sp->s_tgt);
136 }
137 
138 static void
139 scsa1394_sbp2_detect_symbios(scsa1394_state_t *sp)
140 {
141 	sbp2_cfgrom_ent_t *root = &sp->s_tgt->t_cfgrom.cr_root;
142 	sbp2_cfgrom_ent_t *ent;
143 	scsa1394_bw_list_t *wl;
144 	int	vid;
145 	int	i;
146 
147 
148 	if (!scsa1394_wrka_symbios) {
149 		sp->s_symbios = B_FALSE;
150 		return;
151 	} else {
152 		sp->s_symbios = B_TRUE;
153 	}
154 
155 	/* get device's vendor ID */
156 	if ((ent = sbp2_cfgrom_ent_by_key(root, IEEE1212_IMMEDIATE_TYPE,
157 	    IEEE1212_MODULE_VENDOR_ID, 0)) == NULL) {
158 		return;
159 	}
160 	vid = ent->ce_data.imm;
161 
162 	/* find a match in the whitelist */
163 	for (i = 0; i < NELEM(scsa1394_sbp2_symbios_whitelist); i++) {
164 		wl = &scsa1394_sbp2_symbios_whitelist[i];
165 		if ((wl->vid_match == SCSA1394_BW_ONE) && (wl->vid == vid)) {
166 			sp->s_symbios = B_FALSE;
167 			break;
168 		}
169 	}
170 }
171 
172 
173 /*
174  * functional equivalent of ddi_rep_get32() with big endian access handle
175  */
176 static void
177 bcopy_swap32(uint32_t *from, uint32_t *to, int count)
178 {
179 	int		i;
180 	uint32_t	data;
181 
182 	ASSERT((uintptr_t)to % 4 == 0);
183 
184 	for (i = 0; i < count; i++) {
185 		data = *from++;
186 		*to++ = SBP2_SWAP32(data);
187 	}
188 }
189 
190 /*
191  * Build an inquiry for a given device that doesn't like inquiry commands.
192  */
193 void
194 scsa1394_sbp2_fake_inquiry(scsa1394_state_t *sp, struct scsi_inquiry *inq)
195 {
196 	sbp2_cfgrom_ent_t *r = &sp->s_tgt->t_cfgrom.cr_root;
197 	sbp2_cfgrom_ent_t *e, *eref, *evid;
198 	int	i, len;
199 
200 	bzero(inq, sizeof (struct scsi_inquiry));
201 
202 	inq->inq_dtype = DTYPE_DIRECT;
203 	inq->inq_rmb = 1;
204 	inq->inq_ansi = 2;
205 	inq->inq_rdf = RDF_SCSI2;
206 	inq->inq_len = sizeof (struct scsi_inquiry) - 4;
207 
208 	(void) memset(inq->inq_vid, ' ', sizeof (inq->inq_vid));
209 	(void) memset(inq->inq_pid, ' ', sizeof (inq->inq_pid));
210 	(void) memset(inq->inq_revision, ' ', sizeof (inq->inq_revision));
211 
212 	/*
213 	 * vid/pid/rev can be derived from Config ROM textual descriptors
214 	 */
215 	for (i = 0; i < 256; i++) {
216 		if ((e = sbp2_cfgrom_ent_by_key(r, IEEE1212_LEAF_TYPE,
217 		    IEEE1212_TEXTUAL_DESCRIPTOR, i)) == NULL) {
218 			break;
219 		}
220 		eref = e->ce_ref;
221 		if ((eref == NULL) || (eref->ce_len < 3) &&
222 		    (eref->ce_kt != IEEE1212_IMMEDIATE_TYPE)) {
223 			continue;
224 		}
225 
226 		len = e->ce_len - 2;
227 		if (eref->ce_kv == IEEE1212_MODULE_VENDOR_ID) {
228 			evid = e;
229 			bcopy_swap32(&e->ce_data.leaf[2],
230 			    (uint32_t *)inq->inq_vid,
231 			    min(sizeof (inq->inq_vid) / 4, len));
232 		} else if (eref->ce_kv == 0x17) {
233 			bcopy_swap32(&e->ce_data.leaf[2],
234 			    (uint32_t *)inq->inq_pid,
235 			    min(sizeof (inq->inq_pid) / 4, len));
236 		} else if ((eref->ce_kv == IEEE1212_MODULE_HW_VERSION) ||
237 		    (eref == evid)) {
238 			bcopy_swap32(&e->ce_data.leaf[2],
239 			    (uint32_t *)inq->inq_revision,
240 			    min(sizeof (inq->inq_revision) / 4, len));
241 		}
242 	}
243 }
244 
245 int
246 scsa1394_sbp2_threads_init(scsa1394_state_t *sp)
247 {
248 	scsa1394_lun_t		*lp;
249 	scsa1394_thread_t	*thr;
250 	int			i;
251 
252 	for (i = 0; i < sp->s_nluns; i++) {
253 		lp = &sp->s_lun[i];
254 		thr = &lp->l_worker_thread;
255 
256 		thr->thr_func = scsa1394_sbp2_worker_thread;
257 		thr->thr_arg = thr;
258 		thr->thr_state = SCSA1394_THR_INIT;
259 		cv_init(&thr->thr_cv, NULL, CV_DRIVER, NULL);
260 		thr->thr_lun = lp;
261 		thr->thr_req = 0;
262 
263 		mutex_enter(&lp->l_mutex);
264 		if (scsa1394_thr_dispatch(thr) != DDI_SUCCESS) {
265 			mutex_exit(&lp->l_mutex);
266 			scsa1394_sbp2_threads_fini(sp);
267 			return (DDI_FAILURE);
268 		}
269 		mutex_exit(&lp->l_mutex);
270 	}
271 
272 	return (DDI_SUCCESS);
273 }
274 
275 void
276 scsa1394_sbp2_threads_fini(scsa1394_state_t *sp)
277 {
278 	scsa1394_lun_t		*lp;
279 	scsa1394_thread_t	*thr;
280 	int			i;
281 
282 	for (i = 0; i < sp->s_nluns; i++) {
283 		lp = &sp->s_lun[i];
284 		thr = &lp->l_worker_thread;
285 
286 		/* if thread wasn't initialized, thr_lun will be NULL */
287 		if (thr->thr_lun == lp) {
288 			mutex_enter(&lp->l_mutex);
289 			scsa1394_thr_cancel(thr);
290 			mutex_exit(&lp->l_mutex);
291 			ASSERT(thr->thr_state != SCSA1394_THR_RUN);
292 			cv_destroy(&thr->thr_cv);
293 		}
294 	}
295 }
296 
297 int
298 scsa1394_sbp2_get_lun_type(scsa1394_lun_t *lp)
299 {
300 	return (lp->l_lun->l_type);
301 }
302 
303 int
304 scsa1394_sbp2_login(scsa1394_state_t *sp, int lun)
305 {
306 	scsa1394_lun_t	*lp = &sp->s_lun[lun];
307 	int		berr;
308 
309 	if (sbp2_lun_login(lp->l_lun, &lp->l_ses,
310 	    scsa1394_sbp2_status_cb, lp, &berr) != SBP2_SUCCESS) {
311 		return (DDI_FAILURE);
312 	}
313 	ASSERT(lp->l_ses != NULL);
314 	return (DDI_SUCCESS);
315 }
316 
317 void
318 scsa1394_sbp2_logout(scsa1394_state_t *sp, int lun, boolean_t phys)
319 {
320 	scsa1394_lun_t	*lp = &sp->s_lun[lun];
321 	int		berr;
322 
323 	if (scsa1394_sbp2_logged_in(lp)) {
324 		(void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, phys);
325 	}
326 }
327 
328 void
329 scsa1394_sbp2_req(scsa1394_state_t *sp, int lun, int req)
330 {
331 	scsa1394_lun_t	*lp = &sp->s_lun[lun];
332 
333 	if (lp != NULL) {
334 		mutex_enter(&lp->l_mutex);
335 		scsa1394_thr_wake(&lp->l_worker_thread, req);
336 		mutex_exit(&lp->l_mutex);
337 	}
338 }
339 
340 void
341 scsa1394_sbp2_req_bus_reset(scsa1394_lun_t *lp)
342 {
343 	scsa1394_state_t	*sp = lp->l_sp;
344 	int			berr = 0;
345 
346 	if (t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0,
347 	    &sp->s_targetinfo) != DDI_SUCCESS) {
348 		goto disconnect;
349 	}
350 
351 	if (sp->s_targetinfo.target_nodeID == T1394_INVALID_NODEID) {
352 		goto disconnect;
353 	}
354 
355 	if (!scsa1394_sbp2_logged_in(lp)) {
356 		/* reconnect procedure is only for logged in hosts */
357 		return;
358 	}
359 
360 	/*
361 	 * Try SBP-2 RECONNECT procedure first. Note that we're passing
362 	 * local Node ID, which might have changed during bus reset.
363 	 * sbp2_ses_reconnect() will use it to update the ORBs.
364 	 */
365 	if (sbp2_ses_reconnect(lp->l_ses, &berr,
366 	    SCSA1394_NODEID(sp)) == SBP2_SUCCESS) {
367 		mutex_enter(&sp->s_mutex);
368 		sp->s_dev_state = SCSA1394_DEV_ONLINE;
369 		mutex_exit(&sp->s_mutex);
370 
371 		/* resume task processing */
372 		scsa1394_sbp2_nudge(lp);
373 
374 		return;
375 	}
376 
377 	if (berr == CMD1394_EDEVICE_REMOVED) {
378 		goto disconnect;
379 	}
380 
381 	/* reconnect failed, try to logout and login again */
382 	scsa1394_sbp2_flush_cmds(lp, CMD_TRAN_ERR, 0, STAT_BUS_RESET);
383 	(void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE);
384 
385 	if (scsa1394_sbp2_login(sp, 0) != SBP2_SUCCESS) {
386 		goto disconnect;
387 	}
388 
389 	mutex_enter(&sp->s_mutex);
390 	sp->s_dev_state = SCSA1394_DEV_ONLINE;
391 	mutex_exit(&sp->s_mutex);
392 
393 	return;
394 
395 disconnect:
396 	mutex_enter(&sp->s_mutex);
397 	sp->s_dev_state = SCSA1394_DEV_DISCONNECTED;
398 	mutex_exit(&sp->s_mutex);
399 	if (scsa1394_sbp2_logged_in(lp)) {
400 		scsa1394_sbp2_flush_cmds(lp, CMD_DEV_GONE, 0, STAT_BUS_RESET);
401 		(void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE);
402 	}
403 }
404 
405 /*ARGSUSED*/
406 void
407 scsa1394_sbp2_req_reconnect(scsa1394_lun_t *lp)
408 {
409 	scsa1394_state_t	*sp = lp->l_sp;
410 
411 	if (t1394_get_targetinfo(sp->s_t1394_hdl, SCSA1394_BUSGEN(sp), 0,
412 	    &sp->s_targetinfo) != DDI_SUCCESS) {
413 		return;
414 	}
415 
416 	mutex_enter(&sp->s_mutex);
417 	sp->s_dev_state = SCSA1394_DEV_ONLINE;
418 	mutex_exit(&sp->s_mutex);
419 
420 	if (sbp2_tgt_reconnect(sp->s_tgt) != SBP2_SUCCESS) {
421 		goto disconnect;
422 	}
423 
424 	if (scsa1394_sbp2_login(sp, 0) != SBP2_SUCCESS) {
425 		goto disconnect;
426 	}
427 
428 	cmn_err(CE_WARN, "scsa1394(%d): "
429 	    "Reinserted device is accessible again.\n", sp->s_instance);
430 
431 	return;
432 
433 disconnect:
434 	mutex_enter(&sp->s_mutex);
435 	sp->s_dev_state = SCSA1394_DEV_DISCONNECTED;
436 	mutex_exit(&sp->s_mutex);
437 }
438 
439 void
440 scsa1394_sbp2_disconnect(scsa1394_state_t *sp)
441 {
442 	scsa1394_lun_t	*lp = &sp->s_lun[0];
443 	int		berr;
444 
445 	scsa1394_sbp2_flush_cmds(lp, CMD_DEV_GONE, 0, STAT_BUS_RESET);
446 	if (scsa1394_sbp2_logged_in(lp)) {
447 		(void) sbp2_lun_logout(lp->l_lun, &lp->l_ses, &berr, B_FALSE);
448 	}
449 	sbp2_tgt_disconnect(sp->s_tgt);
450 }
451 
452 /*
453  * convert segment array into DMA-mapped SBP-2 page table
454  */
455 void
456 scsa1394_sbp2_seg2pt(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
457 {
458 	scsa1394_state_t	*sp = lp->l_sp;
459 
460 	ASSERT(cmd->sc_flags & SCSA1394_CMD_DMA_BUF_PT_VALID);
461 
462 	if (sp->s_symbios) {
463 		scsa1394_sbp2_seg2pt_symbios(lp, cmd);
464 	} else {
465 		scsa1394_sbp2_seg2pt_default(lp, cmd);
466 	}
467 }
468 
469 /*ARGSUSED*/
470 static void
471 scsa1394_sbp2_seg2pt_default(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
472 {
473 	sbp2_pt_unrestricted_t *pt;
474 	scsa1394_cmd_seg_t *seg;
475 	int		i;
476 
477 	pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr;
478 	seg = &cmd->sc_buf_seg[0];
479 	for (i = 0; i < cmd->sc_buf_nsegs; i++) {
480 		pt->pt_seg_len = SBP2_SWAP16(seg->ss_len);
481 		pt->pt_seg_base_hi = SBP2_SWAP16(seg->ss_baddr >> 32);
482 		pt->pt_seg_base_lo = SBP2_SWAP32(seg->ss_baddr & 0xFFFFFFFF);
483 
484 		pt++;
485 		seg++;
486 	}
487 	(void) ddi_dma_sync(cmd->sc_pt_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
488 
489 	cmd->sc_pt_cmd_size = cmd->sc_buf_nsegs;
490 }
491 
492 /*
493  * fill page table for Symbios workaround
494  */
495 /*ARGSUSED*/
496 static void
497 scsa1394_sbp2_seg2pt_symbios(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
498 {
499 	sbp2_pt_unrestricted_t *pt;
500 	scsa1394_cmd_seg_t *seg;
501 	int		nsegs;
502 	size_t		resid, skiplen, dataoff, segoff, seglen;
503 	uint64_t	baddr;
504 
505 	/* data offset within command */
506 	if (cmd->sc_flags & SCSA1394_CMD_SYMBIOS_BREAKUP) {
507 		dataoff = (cmd->sc_total_blks - cmd->sc_resid_blks) *
508 		    cmd->sc_blk_size;
509 	} else {
510 		dataoff = 0;
511 	}
512 
513 	/* skip dataoff bytes */
514 	seg = &cmd->sc_buf_seg[0];
515 	skiplen = 0;
516 	while (skiplen + seg->ss_len <= dataoff) {
517 		skiplen += seg->ss_len;
518 		seg++;
519 	}
520 	segoff = dataoff - skiplen; /* offset within segment */
521 
522 	pt = (sbp2_pt_unrestricted_t *)cmd->sc_pt_kaddr;
523 	resid = cmd->sc_xfer_bytes;
524 	nsegs = 0;
525 	while (resid > 0) {
526 		ASSERT(seg->ss_len <= scsa1394_symbios_page_size);
527 
528 		seglen = min(seg->ss_len, resid) - segoff;
529 		baddr = seg->ss_baddr + segoff;
530 
531 		pt->pt_seg_len = SBP2_SWAP16(seglen);
532 		pt->pt_seg_base_hi = SBP2_SWAP16(baddr >> 32);
533 		pt->pt_seg_base_lo = SBP2_SWAP32(baddr & 0xFFFFFFFF);
534 
535 		segoff = 0;
536 		resid -= seglen;
537 		nsegs++;
538 		pt++;
539 		seg++;
540 	}
541 	(void) ddi_dma_sync(cmd->sc_pt_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
542 
543 	cmd->sc_pt_cmd_size = nsegs;
544 }
545 
546 /*
547  * convert command into DMA-mapped SBP-2 ORB
548  */
549 void
550 scsa1394_sbp2_cmd2orb(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
551 {
552 	scsa1394_state_t *sp = lp->l_sp;
553 	scsa1394_cmd_orb_t *orb = sbp2_task_orb_kaddr(&cmd->sc_task);
554 
555 	mutex_enter(&lp->l_mutex);
556 
557 	lp->l_stat.stat_cmd_cnt++;
558 
559 	bzero(orb->co_cdb, sizeof (orb->co_cdb));
560 
561 	/* CDB */
562 	bcopy(cmd->sc_cdb, orb->co_cdb, cmd->sc_cdb_actual_len);
563 
564 	/*
565 	 * ORB parameters
566 	 *
567 	 * use max speed and max payload for this speed.
568 	 * max async data transfer for a given speed is 512<<speed
569 	 * SBP-2 defines (see 5.1.2) max data transfer as 2^(max_payload+2),
570 	 * hence max_payload = 7 + speed
571 	 */
572 	orb->co_params = SBP2_ORB_NOTIFY | SBP2_ORB_RQ_FMT_SBP2 |
573 	    (sp->s_targetinfo.current_max_speed << SBP2_ORB_CMD_SPD_SHIFT) |
574 	    ((7 + sp->s_targetinfo.current_max_speed -
575 	    scsa1394_sbp2_max_payload_sub) << SBP2_ORB_CMD_MAX_PAYLOAD_SHIFT);
576 
577 	/* direction: initiator's read is target's write (and vice versa) */
578 	if (cmd->sc_flags & SCSA1394_CMD_READ) {
579 		orb->co_params |= SBP2_ORB_CMD_DIR;
580 	}
581 
582 	/*
583 	 * data_size and data_descriptor
584 	 */
585 	if (cmd->sc_buf_nsegs == 0) {
586 		/* no data */
587 		orb->co_data_size = 0;
588 		SCSA1394_ADDR_SET(sp, orb->co_data_descr, 0);
589 	} else if (cmd->sc_buf_nsegs == 1) {
590 		/* contiguous buffer - use direct addressing */
591 		ASSERT(cmd->sc_buf_seg[0].ss_len != 0);
592 		orb->co_data_size = SBP2_SWAP16(cmd->sc_buf_seg[0].ss_len);
593 		SCSA1394_ADDR_SET(sp, orb->co_data_descr,
594 		    cmd->sc_buf_seg[0].ss_baddr);
595 	} else {
596 		/* non-contiguous s/g list - page table */
597 		ASSERT(cmd->sc_pt_cmd_size > 0);
598 		orb->co_params |= SBP2_ORB_CMD_PT;
599 		orb->co_data_size = SBP2_SWAP16(cmd->sc_pt_cmd_size);
600 		SCSA1394_ADDR_SET(sp, orb->co_data_descr, cmd->sc_pt_baddr);
601 	}
602 
603 	SBP2_SWAP16_1(orb->co_params);
604 
605 	SBP2_ORBP_SET(orb->co_next_orb, SBP2_ORBP_NULL);
606 
607 	mutex_exit(&lp->l_mutex);
608 
609 	sbp2_task_orb_sync(lp->l_lun, &cmd->sc_task, DDI_DMA_SYNC_FORDEV);
610 }
611 
612 
613 /*ARGSUSED*/
614 int
615 scsa1394_sbp2_start(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd)
616 {
617 	sbp2_task_t	*task = CMD2TASK(cmd);
618 	int		ret;
619 
620 	ASSERT(lp->l_ses != NULL);
621 
622 	task->ts_timeout = cmd->sc_timeout;
623 	task->ts_error = SBP2_TASK_ERR_NONE;
624 	task->ts_bus_error = 0;
625 	task->ts_state = SBP2_TASK_INIT;
626 
627 	ret = sbp2_ses_submit_task(lp->l_ses, task);
628 
629 	if (ret == SBP2_SUCCESS) {
630 		return (TRAN_ACCEPT);
631 	} if (task->ts_error == SBP2_TASK_ERR_BUS) {
632 		if (task->ts_bus_error == CMD1394_EDEVICE_BUSY) {
633 			return (TRAN_BUSY);
634 		} else {
635 			return (TRAN_FATAL_ERROR);
636 		}
637 	} else {
638 		return (TRAN_FATAL_ERROR);
639 	}
640 }
641 
642 /*
643  * This function is called by SBP-2 layer when task status is received,
644  * typically from interrupt handler. Just wake the thread to do the actual work.
645  */
646 /*ARGSUSED*/
647 static void
648 scsa1394_sbp2_status_cb(void *arg, sbp2_task_t *task)
649 {
650 	scsa1394_lun_t		*lp = (scsa1394_lun_t *)arg;
651 
652 	mutex_enter(&lp->l_mutex);
653 	scsa1394_thr_wake(&lp->l_worker_thread, SCSA1394_THREQ_TASK_STATUS);
654 	mutex_exit(&lp->l_mutex);
655 }
656 
657 void
658 scsa1394_sbp2_nudge(scsa1394_lun_t *lp)
659 {
660 	mutex_enter(&lp->l_mutex);
661 	scsa1394_thr_wake(&lp->l_worker_thread, SCSA1394_THREQ_NUDGE);
662 	mutex_exit(&lp->l_mutex);
663 }
664 
665 /*
666  * worker thread
667  */
668 static void
669 scsa1394_sbp2_worker_thread(void *arg)
670 {
671 	scsa1394_thread_t	*thr = (scsa1394_thread_t *)arg;
672 	scsa1394_lun_t		*lp = thr->thr_lun;
673 
674 	mutex_enter(&lp->l_mutex);
675 	for (;;) {
676 		while (thr->thr_req == 0) {
677 			cv_wait(&thr->thr_cv, &lp->l_mutex);
678 		}
679 		if (thr->thr_req & SCSA1394_THREQ_EXIT) {
680 			break;
681 		}
682 		if (thr->thr_req & SCSA1394_THREQ_BUS_RESET) {
683 			thr->thr_req &= ~SCSA1394_THREQ_BUS_RESET;
684 			mutex_exit(&lp->l_mutex);
685 			scsa1394_sbp2_req_bus_reset(lp);
686 			mutex_enter(&lp->l_mutex);
687 			continue;
688 		}
689 		if (thr->thr_req & SCSA1394_THREQ_RECONNECT) {
690 			thr->thr_req &= ~SCSA1394_THREQ_RECONNECT;
691 			mutex_exit(&lp->l_mutex);
692 			scsa1394_sbp2_req_reconnect(lp);
693 			mutex_enter(&lp->l_mutex);
694 			continue;
695 		}
696 		if (thr->thr_req & SCSA1394_THREQ_TASK_STATUS) {
697 			thr->thr_req &= ~SCSA1394_THREQ_TASK_STATUS;
698 			mutex_exit(&lp->l_mutex);
699 			scsa1394_sbp2_req_status(lp);
700 			mutex_enter(&lp->l_mutex);
701 			continue;
702 		}
703 		if (thr->thr_req & SCSA1394_THREQ_NUDGE) {
704 			thr->thr_req &= ~SCSA1394_THREQ_NUDGE;
705 			mutex_exit(&lp->l_mutex);
706 			if (scsa1394_sbp2_logged_in(lp)) {
707 				sbp2_ses_nudge(lp->l_ses);
708 			}
709 			mutex_enter(&lp->l_mutex);
710 			continue;
711 		}
712 	}
713 	thr->thr_state = SCSA1394_THR_EXIT;
714 	cv_signal(&thr->thr_cv);
715 	mutex_exit(&lp->l_mutex);
716 }
717 
718 /*
719  * task status handler
720  */
721 static void
722 scsa1394_sbp2_req_status(scsa1394_lun_t *lp)
723 {
724 	sbp2_ses_t		*sp = lp->l_ses;
725 	sbp2_task_t		*task;
726 
727 	if (sp == NULL) {
728 		return;
729 	}
730 
731 	/*
732 	 * Process all tasks that received status.
733 	 * This algorithm preserves callback order.
734 	 */
735 	while ((task = sbp2_ses_remove_first_task_state(sp, SBP2_TASK_COMP)) !=
736 	    NULL) {
737 		sbp2_ses_nudge(sp);
738 
739 		ASSERT(task->ts_state == SBP2_TASK_COMP);
740 		task->ts_state = SBP2_TASK_PROC;
741 		scsa1394_sbp2_status_proc(lp, TASK2CMD(task),
742 		    (scsa1394_status_t *)&task->ts_status);
743 	}
744 	sbp2_ses_nudge(sp);	/* submit next task */
745 }
746 
747 static void
748 scsa1394_sbp2_status_proc(scsa1394_lun_t *lp, scsa1394_cmd_t *cmd,
749     scsa1394_status_t *st)
750 {
751 	sbp2_task_t		*task = CMD2TASK(cmd);
752 	struct scsi_pkt		*pkt = CMD2PKT(cmd);
753 	uint64_t		*p;
754 
755 	if (cmd->sc_flags & SCSA1394_CMD_READ) {
756 		(void) ddi_dma_sync(cmd->sc_buf_dma_hdl, 0, 0,
757 		    DDI_DMA_SYNC_FORKERNEL);
758 	}
759 
760 	if (task->ts_error != SBP2_TASK_ERR_NONE) {
761 		pkt->pkt_state |= STATE_GOT_BUS;
762 		switch (task->ts_error) {
763 		case SBP2_TASK_ERR_ABORT:
764 			pkt->pkt_state |= STATE_GOT_TARGET;
765 			pkt->pkt_reason = CMD_ABORTED;
766 			break;
767 		case SBP2_TASK_ERR_LUN_RESET:
768 			pkt->pkt_state |= STATE_GOT_TARGET;
769 			pkt->pkt_reason = CMD_RESET;
770 			pkt->pkt_statistics |= STAT_DEV_RESET;
771 			break;
772 		case SBP2_TASK_ERR_TGT_RESET:
773 			pkt->pkt_state |= STATE_GOT_TARGET;
774 			pkt->pkt_reason = CMD_RESET;
775 			pkt->pkt_statistics |= STAT_DEV_RESET;
776 			break;
777 		case SBP2_TASK_ERR_TIMEOUT:
778 			(void) scsa1394_sbp2_reset(lp, RESET_TARGET, cmd);
779 			return;
780 		case SBP2_TASK_ERR_DEAD:
781 		case SBP2_TASK_ERR_BUS:
782 		default:
783 			pkt->pkt_reason = CMD_TRAN_ERR;
784 			break;
785 		}
786 	} else if ((st->st_param & SBP2_ST_RESP) == SBP2_ST_RESP_COMPLETE) {
787 		/*
788 		 * SBP-2 status block has been received, now look at sbp_status.
789 		 *
790 		 * Note: ANSI NCITS 325-1998 B.2 requires that when status is
791 		 * GOOD, length must be one, but some devices do not comply
792 		 */
793 		if (st->st_sbp_status == SBP2_ST_SBP_DUMMY_ORB) {
794 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
795 			pkt->pkt_reason = CMD_ABORTED;
796 			pkt->pkt_statistics |= STAT_DEV_RESET;
797 		} else if ((st->st_status & SCSA1394_ST_STATUS) ==
798 		    STATUS_GOOD) {
799 			/* request complete */
800 			*(pkt->pkt_scbp) = STATUS_GOOD;
801 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
802 			    STATE_SENT_CMD | STATE_XFERRED_DATA |
803 			    STATE_GOT_STATUS);
804 			pkt->pkt_reason = CMD_CMPLT;
805 		} else if (scsa1394_sbp2_conv_status(cmd, st) == DDI_SUCCESS) {
806 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
807 			    STATE_SENT_CMD | STATE_XFERRED_DATA |
808 			    STATE_GOT_STATUS | STATE_ARQ_DONE);
809 			pkt->pkt_reason = CMD_TRAN_ERR;
810 		} else {
811 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
812 			    STATE_SENT_CMD | STATE_XFERRED_DATA |
813 			    STATE_GOT_STATUS);
814 			pkt->pkt_reason = CMD_TRAN_ERR;
815 			lp->l_stat.stat_err_status_conv++;
816 		}
817 	} else {
818 		/* transport or serial bus failure */
819 		pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
820 		pkt->pkt_reason = CMD_TRAN_ERR;
821 		lp->l_stat.stat_err_status_resp++;
822 	}
823 
824 	if (pkt->pkt_reason == CMD_TRAN_ERR) {
825 		lp->l_stat.stat_err_status_tran_err++;
826 
827 		/* save the command */
828 		p = &lp->l_stat.stat_cmd_last_fail[
829 		    lp->l_stat.stat_cmd_last_fail_idx][0];
830 		bcopy(&pkt->pkt_cdbp[0], p, min(cmd->sc_cdb_len, 16));
831 		*(clock_t *)&p[2] = ddi_get_lbolt();
832 		lp->l_stat.stat_cmd_last_fail_idx =
833 		    (lp->l_stat.stat_cmd_last_fail_idx + 1) %
834 		    SCSA1394_STAT_NCMD_LAST;
835 	}
836 
837 	/* generic HBA status processing */
838 	scsa1394_cmd_status_proc(lp, cmd);
839 }
840 
841 
842 /*
843  * Convert SBP-2 status block into SCSA status.
844  *
845  * Note: (ref: B.2) "SBP-2 permits the return of a status block between two
846  *	and quadlets in length. When a truncated status block is stored, the
847  *	omitted quadlets shall be interpreted as if zero values were stored."
848  * 	We expect the sbp2 layer to do the zeroing for us.
849  */
850 static int
851 scsa1394_sbp2_conv_status(scsa1394_cmd_t *cmd, scsa1394_status_t *st)
852 {
853 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
854 	uint8_t		status = st->st_status;
855 	uint8_t		bits = st->st_sense_bits;
856 	struct scsi_arq_status *arqp = (struct scsi_arq_status *)pkt->pkt_scbp;
857 	struct scsi_extended_sense *esp = &arqp->sts_sensedata;
858 
859 	*(pkt->pkt_scbp) = (status & SCSA1394_ST_STATUS);
860 	*(uint8_t *)&arqp->sts_rqpkt_status = STATUS_GOOD;
861 	arqp->sts_rqpkt_reason = CMD_CMPLT;
862 	arqp->sts_rqpkt_resid = 0;
863 	arqp->sts_rqpkt_state |= STATE_XFERRED_DATA;
864 	arqp->sts_rqpkt_statistics = 0;
865 
866 	esp->es_valid = (bits & SCSA1394_ST_VALID) >> SCSA1394_ST_VALID_SHIFT;
867 	esp->es_class = CLASS_EXTENDED_SENSE;
868 	esp->es_code = (status & SCSA1394_ST_SFMT) >> SCSA1394_ST_SFMT_SHIFT;
869 
870 	esp->es_segnum = 0;
871 
872 	esp->es_filmk = (bits & SCSA1394_ST_MARK) >> SCSA1394_ST_MARK_SHIFT;
873 	esp->es_eom = (bits & SCSA1394_ST_EOM) >> SCSA1394_ST_EOM_SHIFT;
874 	esp->es_ili = (bits & SCSA1394_ST_ILI) >> SCSA1394_ST_ILI_SHIFT;
875 	esp->es_key = (bits & SCSA1394_ST_SENSE_KEY);
876 
877 	esp->es_info_1 = st->st_info[0];
878 	esp->es_info_2 = st->st_info[1];
879 	esp->es_info_3 = st->st_info[2];
880 	esp->es_info_4 = st->st_info[3];
881 	esp->es_add_len = 4;
882 
883 	esp->es_cmd_info[0] = st->st_cdb[0];
884 	esp->es_cmd_info[1] = st->st_cdb[1];
885 	esp->es_cmd_info[2] = st->st_cdb[2];
886 	esp->es_cmd_info[3] = st->st_cdb[3];
887 	esp->es_add_code = st->st_sense_code;
888 	esp->es_qual_code = st->st_sense_qual;
889 	esp->es_fru_code = st->st_fru;
890 	esp->es_skey_specific[0] = st->st_sks[0];
891 	esp->es_skey_specific[1] = st->st_sks[1];
892 	esp->es_skey_specific[2] = st->st_sks[2];
893 
894 	esp->es_add_info[0] = esp->es_add_info[1] = 0;
895 
896 	return (DDI_SUCCESS);
897 }
898 
899 /*
900  * Sends appropriate reset command to the target. LUN reset is optional, so it
901  * can fail, in which case the SCSA target driver will use RESET_TARGET/ALL.
902  * Target reset support is mandatory in SBP-2, if it fails, it means something's
903  * terribly wrong with the device - blow away outstanding tasks in that case.
904  */
905 int
906 scsa1394_sbp2_reset(scsa1394_lun_t *lp, int level, scsa1394_cmd_t *cmd)
907 {
908 	scsa1394_state_t	*sp = lp->l_sp;
909 	sbp2_task_t		*task;
910 	int			berr;
911 	int			ret = DDI_FAILURE;
912 
913 	if (scsa1394_dev_is_online(sp)) {
914 		switch (level) {
915 		case RESET_LUN:
916 			ret = sbp2_lun_reset(lp->l_lun, &berr);
917 			if (ret != SBP2_SUCCESS) {
918 				return (ret);
919 			}
920 			break;
921 		case RESET_TARGET:
922 		case RESET_ALL:
923 			ret = sbp2_tgt_reset(sp->s_tgt, &berr);
924 			break;
925 		}
926 	}
927 
928 	if (cmd != NULL) {
929 		scsa1394_sbp2_reset_proc(lp, level, cmd);
930 	}
931 	if (scsa1394_sbp2_logged_in(lp)) {
932 		while ((task = sbp2_ses_cancel_first_task(lp->l_ses)) != NULL) {
933 			ASSERT(task->ts_state < SBP2_TASK_PROC);
934 			scsa1394_sbp2_reset_proc(lp, level, TASK2CMD(task));
935 		}
936 	}
937 
938 	return (ret);
939 }
940 
941 static void
942 scsa1394_sbp2_reset_proc(scsa1394_lun_t *lp, int level, scsa1394_cmd_t *cmd)
943 {
944 	sbp2_task_t		*task = CMD2TASK(cmd);
945 	struct scsi_pkt		*pkt = CMD2PKT(cmd);
946 	int			ts_error;
947 
948 	pkt->pkt_reason = CMD_RESET;
949 	if (level == RESET_LUN) {
950 		if (task->ts_state == SBP2_TASK_PEND) {
951 			pkt->pkt_statistics |= STAT_DEV_RESET;
952 		} else {
953 			pkt->pkt_statistics |= STAT_ABORTED;
954 		}
955 		ts_error = SBP2_TASK_ERR_LUN_RESET;
956 	} else {
957 		pkt->pkt_statistics |= STAT_BUS_RESET;
958 		ts_error = SBP2_TASK_ERR_TGT_RESET;
959 	}
960 	task->ts_error = ts_error;
961 	task->ts_state = SBP2_TASK_PROC;
962 	scsa1394_cmd_status_proc(lp, cmd);
963 }
964 
965 /*
966  * Cancel commands immediately.
967  *
968  * Caller's responsibility to set device state such that no new tasks are added.
969  */
970 void
971 scsa1394_sbp2_flush_cmds(scsa1394_lun_t *lp, int reason, int state,
972     int statistics)
973 {
974 	scsa1394_cmd_t	*cmd;
975 	struct scsi_pkt	*pkt;
976 	sbp2_ses_t	*sp = lp->l_ses;
977 	sbp2_task_t	*task;
978 
979 	if (sp == NULL) {
980 		return;
981 	}
982 
983 	while ((task = sbp2_ses_cancel_first_task(sp)) != NULL) {
984 		ASSERT(task->ts_state < SBP2_TASK_PROC);
985 		cmd = TASK2CMD(task);
986 		pkt = CMD2PKT(cmd);
987 
988 		pkt->pkt_reason = reason;
989 		pkt->pkt_state |= state;
990 		pkt->pkt_statistics |= statistics;
991 		task->ts_state = SBP2_TASK_PROC;
992 		scsa1394_cmd_status_proc(lp, cmd);
993 	}
994 
995 	scsa1394_thr_clear_req(&lp->l_worker_thread,
996 	    SCSA1394_THREQ_TASK_STATUS | SCSA1394_THREQ_NUDGE);
997 }
998 
999 static boolean_t
1000 scsa1394_sbp2_logged_in(scsa1394_lun_t *lp)
1001 {
1002 	return (lp->l_ses != NULL);
1003 }
1004