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