sbp.c revision 111199
1/*
2 * Copyright (c) 1998,1999,2000,2001 Katsushi Kobayashi and Hidetosh Shimokawa
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the acknowledgement as bellow:
15 *
16 *    This product includes software developed by K. Kobayashi and H. Shimokawa
17 *
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $FreeBSD: head/sys/dev/firewire/sbp.c 111199 2003-02-21 02:09:04Z simokawa $
34 *
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/module.h>
40#include <sys/bus.h>
41#include <sys/mbuf.h>
42#include <sys/sysctl.h>
43#include <machine/bus.h>
44#include <sys/malloc.h>
45#include <sys/devicestat.h>	/* for struct devstat */
46
47
48#include <cam/cam.h>
49#include <cam/cam_ccb.h>
50#include <cam/cam_sim.h>
51#include <cam/cam_xpt_sim.h>
52#include <cam/cam_debug.h>
53#include <cam/cam_periph.h>
54
55#include <cam/scsi/scsi_all.h>
56#include <cam/scsi/scsi_message.h>
57#include <cam/scsi/scsi_da.h>
58
59#include <sys/kernel.h>
60
61#include <vm/vm.h>
62#include <vm/pmap.h>
63
64#include <dev/firewire/firewire.h>
65#include <dev/firewire/firewirereg.h>
66#include <dev/firewire/iec13213.h>
67
68#define ccb_sdev_ptr	spriv_ptr0
69#define ccb_sbp_ptr	spriv_ptr1
70
71#define SBP_NUM_TARGETS 8
72#define SBP_NUM_LUNS 8	/* limited by CAM_SCSI2_MAXLUN in cam_xpt.c */
73#define SBP_QUEUE_LEN 4
74#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
75#define SBP_INITIATOR 7
76#define SBP_ESELECT_TIMEOUT 1
77#define SBP_BIND_HI 0x1
78#define SBP_DEV2ADDR(u, t, l)	\
79	((((u) & 0xff) << 16) | (((l) & 0xff) << 8) | (((t) & 0x3f) << 2))
80#define SBP_ADDR2TRG(a)	(((a) >> 2) & 0x3f)
81#define SBP_ADDR2LUN(a)	(((a) >> 8) & 0xff)
82
83#define MAX_FREEZE	10
84
85#define ORB_NOTIFY	(1 << 31)
86#define	ORB_FMT_STD	(0 << 29)
87#define	ORB_FMT_VED	(2 << 29)
88#define	ORB_FMT_NOP	(3 << 29)
89#define	ORB_FMT_MSK	(3 << 29)
90#define	ORB_EXV		(1 << 28)
91/* */
92#define	ORB_CMD_IN	(1 << 27)
93/* */
94#define	ORB_CMD_SPD(x)	((x) << 24)
95#define	ORB_CMD_MAXP(x)	((x) << 20)
96#define	ORB_RCN_TMO(x)	((x) << 20)
97#define	ORB_CMD_PTBL	(1 << 19)
98#define	ORB_CMD_PSZ(x)	((x) << 16)
99
100#define	ORB_FUN_LGI	(0 << 16)
101#define	ORB_FUN_QLG	(1 << 16)
102#define	ORB_FUN_RCN	(3 << 16)
103#define	ORB_FUN_LGO	(7 << 16)
104#define	ORB_FUN_ATA	(0xb << 16)
105#define	ORB_FUN_ATS	(0xc << 16)
106#define	ORB_FUN_LUR	(0xe << 16)
107#define	ORB_FUN_RST	(0xf << 16)
108#define	ORB_FUN_MSK	(0xf << 16)
109
110static char *orb_fun_name[] = {
111	/* 0 */ "LOGIN",
112	/* 1 */ "QUERY LOGINS",
113	/* 2 */ "Reserved",
114	/* 3 */ "RECONNECT",
115	/* 4 */ "SET PASSWORD",
116	/* 5 */ "Reserved",
117	/* 6 */ "Reserved",
118	/* 7 */ "LOGOUT",
119	/* 8 */ "Reserved",
120	/* 9 */ "Reserved",
121	/* A */ "Reserved",
122	/* B */ "ABORT TASK",
123	/* C */ "ABORT TASK SET",
124	/* D */ "Reserved",
125	/* E */ "LOGICAL UNIT RESET",
126	/* F */ "TARGET RESET"
127};
128
129#define ORB_RES_CMPL 0
130#define ORB_RES_FAIL 1
131#define ORB_RES_ILLE 2
132#define ORB_RES_VEND 3
133
134static int debug = 1;
135static int auto_login = 1;
136static int max_speed = 2;
137static int sbp_cold = 1;
138
139SYSCTL_DECL(_hw_firewire);
140SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0, "SBP-II Subsystem");
141SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0,
142	"SBP debug flag");
143SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
144	"SBP perform login automatically");
145SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
146	"SBP transfer max speed");
147
148#define SBP_DEBUG(x)	if (debug > x) {
149#define END_DEBUG	}
150
151#define NEED_RESPONSE 0
152
153struct ind_ptr {
154	u_int32_t hi,lo;
155};
156#define SBP_IND_MAX 0x20
157struct sbp_ocb {
158	STAILQ_ENTRY(sbp_ocb)	ocb;
159	union ccb	*ccb;
160	volatile u_int32_t	orb[8];
161	volatile struct ind_ptr  ind_ptr[SBP_IND_MAX];
162	struct sbp_dev	*sdev;
163	int		flags;
164	bus_dmamap_t	dmamap;
165};
166#define OCB_ACT_MGM 0
167#define OCB_ACT_CMD 1
168#define OCB_ACT_MASK 3
169#define OCB_RESERVED 0x10
170#define OCB_DONE 0x20
171
172#define SBP_RESOURCE_SHORTAGE 0x10
173
174struct sbp_login_res{
175	u_int16_t	len;
176	u_int16_t	id;
177	u_int16_t	res0;
178	u_int16_t	cmd_hi;
179	u_int32_t	cmd_lo;
180	u_int16_t	res1;
181	u_int16_t	recon_hold;
182};
183struct sbp_status{
184	u_int8_t	len:3,
185			dead:1,
186			resp:2,
187			src:2;
188	u_int8_t	status:8;
189	u_int16_t	orb_hi;
190	u_int32_t	orb_lo;
191	u_int32_t	data[6];
192};
193struct sbp_cmd_status{
194#define SBP_SFMT_CURR 0
195#define SBP_SFMT_DEFER 1
196	u_int8_t	status:6,
197			sfmt:2;
198	u_int8_t	s_key:4,
199			ill_len:1,
200			eom:1,
201			mark:1,
202			valid:1;
203	u_int8_t	s_code;
204	u_int8_t	s_qlfr;
205	u_int32_t	info;
206	u_int32_t	cdb;
207	u_int32_t	fru:8,
208			s_keydep:24;
209	u_int32_t	vend[2];
210};
211
212struct sbp_dev{
213#define SBP_DEV_RESET		0	/* accept login */
214#if 0
215#define SBP_DEV_LOGIN		1	/* to login */
216#define SBP_DEV_RECONN		2	/* to reconnect */
217#endif
218#define SBP_DEV_TOATTACH	3	/* to attach */
219#define SBP_DEV_PROBE		4	/* scan lun */
220#define SBP_DEV_ATTACHED	5	/* in operation */
221#define SBP_DEV_DEAD		6	/* unavailable unit */
222#define SBP_DEV_RETRY		7	/* unavailable unit */
223	u_int8_t status:4,
224#define SBP_DEV_TIMEOUT		1
225		 flags:4;
226	u_int8_t type;
227	u_int16_t lun_id;
228	struct cam_path *path;
229	struct sbp_target *target;
230	struct sbp_login_res login;
231	STAILQ_HEAD(, sbp_ocb) ocbs;
232	char vendor[32];
233	char product[32];
234	char revision[10];
235};
236
237struct sbp_target {
238	int target_id;
239	int num_lun;
240	struct sbp_dev	*luns;
241	struct sbp_softc *sbp;
242	struct fw_device *fwdev;
243	u_int32_t mgm_hi, mgm_lo;
244};
245
246struct sbp_softc {
247	struct firewire_dev_comm fd;
248	unsigned char flags;
249	struct cam_sim  *sim;
250	struct sbp_target targets[SBP_NUM_TARGETS];
251	struct fw_bind fwb;
252	STAILQ_HEAD(, sbp_ocb) free_ocbs;
253	struct sbp_ocb *ocb;
254	bus_dma_tag_t	dmat;
255};
256static void sbp_post_explore __P((void *));
257static void sbp_recv __P((struct fw_xfer *));
258static void sbp_login_callback __P((struct fw_xfer *));
259static void sbp_cmd_callback __P((struct fw_xfer *));
260static void sbp_orb_pointer __P((struct sbp_dev *, struct sbp_ocb *));
261static void sbp_execute_ocb __P((void *,  bus_dma_segment_t *, int, int));
262static void sbp_free_ocb __P((struct sbp_softc *, struct sbp_ocb *));
263static void sbp_abort_ocb __P((struct sbp_ocb *, int));
264static void sbp_abort_all_ocbs __P((struct sbp_dev *, int));
265static struct fw_xfer * sbp_write_cmd __P((struct sbp_dev *, int, int));
266static struct sbp_ocb * sbp_get_ocb __P((struct sbp_softc *));
267static struct sbp_ocb * sbp_enqueue_ocb __P((struct sbp_dev *, struct sbp_ocb *));
268static struct sbp_ocb * sbp_dequeue_ocb __P((struct sbp_dev *, u_int32_t));
269static void sbp_cam_detach_target __P((struct sbp_target *));
270static void sbp_timeout __P((void *arg));
271static void sbp_mgm_orb __P((struct sbp_dev *, int, u_int16_t, u_int32_t));
272
273MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
274
275/* cam related functions */
276static void	sbp_action(struct cam_sim *sim, union ccb *ccb);
277static void	sbp_poll(struct cam_sim *sim);
278static void	sbp_cam_callback(struct cam_periph *periph,
279					union ccb *ccb);
280static void	sbp_cam_scan_lun(struct sbp_dev *sdev);
281
282static char *orb_status0[] = {
283	/* 0 */ "No additional information to report",
284	/* 1 */ "Request type not supported",
285	/* 2 */ "Speed not supported",
286	/* 3 */ "Page size not supported",
287	/* 4 */ "Access denied",
288	/* 5 */ "Logical unit not supported",
289	/* 6 */ "Maximum payload too small",
290	/* 7 */ "Reserved for future standardization",
291	/* 8 */ "Resources unavailable",
292	/* 9 */ "Function rejected",
293	/* A */ "Login ID not recognized",
294	/* B */ "Dummy ORB completed",
295	/* C */ "Request aborted",
296	/* FF */ "Unspecified error"
297#define MAX_ORB_STATUS0 0xd
298};
299
300static char *orb_status1_object[] = {
301	/* 0 */ "Operation request block (ORB)",
302	/* 1 */ "Data buffer",
303	/* 2 */ "Page table",
304	/* 3 */ "Unable to specify"
305};
306
307static char *orb_status1_serial_bus_error[] = {
308	/* 0 */ "Missing acknowledge",
309	/* 1 */ "Reserved; not to be used",
310	/* 2 */ "Time-out error",
311	/* 3 */ "Reserved; not to be used",
312	/* 4 */ "Busy retry limit exceeded(X)",
313	/* 5 */ "Busy retry limit exceeded(A)",
314	/* 6 */ "Busy retry limit exceeded(B)",
315	/* 7 */ "Reserved for future standardization",
316	/* 8 */ "Reserved for future standardization",
317	/* 9 */ "Reserved for future standardization",
318	/* A */ "Reserved for future standardization",
319	/* B */ "Tardy retry limit exceeded",
320	/* C */ "Conflict error",
321	/* D */ "Data error",
322	/* E */ "Type error",
323	/* F */ "Address error"
324};
325
326static void
327sbp_identify(driver_t *driver, device_t parent)
328{
329	device_t child;
330SBP_DEBUG(0)
331	printf("sbp_identify\n");
332END_DEBUG
333
334	child = BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent));
335}
336
337/*
338 * sbp_probe()
339 */
340static int
341sbp_probe(device_t dev)
342{
343	device_t pa;
344
345SBP_DEBUG(0)
346	printf("sbp_probe\n");
347END_DEBUG
348
349	pa = device_get_parent(dev);
350	if(device_get_unit(dev) != device_get_unit(pa)){
351		return(ENXIO);
352	}
353
354	device_set_desc(dev, "SBP2/SCSI over firewire");
355	return (0);
356}
357
358static void
359sbp_show_sdev_info(struct sbp_dev *sdev, int new)
360{
361	struct fw_device *fwdev;
362
363	printf("%s:%d:%d ",
364		device_get_nameunit(sdev->target->sbp->fd.dev),
365		sdev->target->target_id,
366		sdev->lun_id
367	);
368	if (new == 2) {
369		return;
370	}
371	fwdev = sdev->target->fwdev;
372	printf("ordered:%d type:%d EUI:%08x%08x node:%d "
373		"speed:%d maxrec:%d",
374		(sdev->type & 0x40) >> 6,
375		(sdev->type & 0x1f),
376		fwdev->eui.hi,
377		fwdev->eui.lo,
378		fwdev->dst,
379		fwdev->speed,
380		fwdev->maxrec
381	);
382	if (new)
383		printf(" new!\n");
384	else
385		printf("\n");
386	sbp_show_sdev_info(sdev, 2);
387	printf("'%s' '%s' '%s'\n", sdev->vendor, sdev->product, sdev->revision);
388}
389
390static struct {
391	int bus;
392	int target;
393	struct fw_eui64 eui;
394} wired[] = {
395	/* Bus	Target	EUI64 */
396#if 0
397	{0,	2,	{0x00018ea0, 0x01fd0154}},	/* Logitec HDD */
398	{0,	0,	{0x00018ea6, 0x00100682}},	/* Logitec DVD */
399	{0,	1,	{0x00d03200, 0xa412006a}},	/* Yano HDD */
400#endif
401	{-1,	-1,	{0,0}}
402};
403
404static int
405sbp_new_target(struct sbp_softc *sbp, struct fw_device *fwdev)
406{
407	int bus, i, target=-1;
408	char w[SBP_NUM_TARGETS];
409
410	bzero(w, sizeof(w));
411	bus = device_get_unit(sbp->fd.dev);
412
413	/* XXX wired-down configuration should be gotten from
414					tunable or device hint */
415	for (i = 0; wired[i].bus >= 0; i ++) {
416		if (wired[i].bus == bus) {
417			w[wired[i].target] = 1;
418			if (wired[i].eui.hi == fwdev->eui.hi &&
419					wired[i].eui.lo == fwdev->eui.lo)
420				target = wired[i].target;
421		}
422	}
423	if (target >= 0) {
424		if(target < SBP_NUM_TARGETS &&
425				sbp->targets[target].fwdev == NULL)
426			return(target);
427		device_printf(sbp->fd.dev,
428			"target %d is not free for %08x:%08x\n",
429			target, fwdev->eui.hi, fwdev->eui.lo);
430		target = -1;
431	}
432	/* non-wired target */
433	for (i = 0; i < SBP_NUM_TARGETS; i ++)
434		if (sbp->targets[i].fwdev == NULL && w[i] == 0) {
435			target = i;
436			break;
437		}
438
439	return target;
440}
441
442static struct sbp_target *
443sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
444{
445	int i, maxlun, lun;
446	struct sbp_target *target;
447	struct sbp_dev *sdev;
448	struct crom_context cc;
449	struct csrreg *reg;
450
451SBP_DEBUG(1)
452	printf("sbp_alloc_target\n");
453END_DEBUG
454	i = sbp_new_target(sbp, fwdev);
455	if (i < 0) {
456		device_printf(sbp->fd.dev, "increase SBP_NUM_TARGETS!\n");
457		return NULL;
458	}
459	/* new target */
460	target = &sbp->targets[i];
461	target->sbp = sbp;
462	target->fwdev = fwdev;
463	target->target_id = i;
464	if((target->mgm_lo = getcsrdata(fwdev, 0x54)) == 0 ){
465		/* bad target */
466		printf("NULL management address\n");
467		target->fwdev = NULL;
468		return NULL;
469	}
470	target->mgm_hi = 0xffff;
471	target->mgm_lo = 0xf0000000 | target->mgm_lo << 2;
472	/* XXX num_lun may be changed. realloc luns? */
473	crom_init_context(&cc, target->fwdev->csrrom);
474	/* XXX shoud parse appropriate unit directories only */
475	maxlun = -1;
476	while (cc.depth >= 0) {
477		reg = crom_search_key(&cc, CROM_LUN);
478		if (reg == NULL)
479			break;
480		lun = reg->val & 0xffff;
481SBP_DEBUG(0)
482		printf("target %d lun %d found\n", target->target_id, lun);
483END_DEBUG
484		if (maxlun < lun)
485			maxlun = lun;
486		crom_next(&cc);
487	}
488	if (maxlun < 0)
489		printf("no lun found!\n");
490	if (maxlun >= SBP_NUM_LUNS)
491		maxlun = SBP_NUM_LUNS;
492	target->num_lun = maxlun + 1;
493	target->luns = (struct sbp_dev *) malloc(
494				sizeof(struct sbp_dev) * target->num_lun,
495				M_SBP, M_NOWAIT | M_ZERO);
496	for (i = 0; i < target->num_lun; i++) {
497		sdev = &target->luns[i];
498		sdev->lun_id = i;
499		sdev->target = target;
500		STAILQ_INIT(&sdev->ocbs);
501		sdev->status = SBP_DEV_DEAD;
502	}
503	crom_init_context(&cc, target->fwdev->csrrom);
504	while (cc.depth >= 0) {
505		reg = crom_search_key(&cc, CROM_LUN);
506		if (reg == NULL)
507			break;
508		lun = reg->val & 0xffff;
509		if (lun >= SBP_NUM_LUNS) {
510			printf("too large lun %d\n", lun);
511			continue;
512		}
513		target->luns[lun].status = SBP_DEV_RESET;
514		target->luns[lun].type = (reg->val & 0xf0000) >> 16;
515		crom_next(&cc);
516	    }
517	    return target;
518    }
519
520static void
521sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len)
522{
523	static char *nullstr = "(null)";
524	int i, clen, found=0;
525	struct csrhdr *chdr;
526	struct csrreg *creg;
527	u_int32_t *src, *dst;
528
529	chdr = (struct csrhdr *)&fwdev->csrrom[0];
530	/* skip crom header, bus info and root directory */
531	creg = (struct csrreg *)chdr + chdr->info_len + 2;
532	/* search unitl the one before the last. */
533	for (i = chdr->info_len + 2; i < fwdev->rommax / 4; i++) {
534		if((creg++)->key == key){
535			found = 1;
536			break;
537		}
538	}
539	if (!found || creg->key != CROM_TEXTLEAF) {
540		strncpy(buf, nullstr, len);
541		return;
542	}
543	src = (u_int32_t *) creg + creg->val;
544	clen = ((*src >> 16) - 2) * 4;
545	src += 3;
546	dst = (u_int32_t *) buf;
547	if (len < clen)
548		clen = len;
549	for (i = 0; i < clen/4; i++)
550		*dst++ = htonl(*src++);
551	buf[clen] = 0;
552}
553
554static void
555sbp_probe_lun(struct sbp_dev *sdev)
556{
557	struct fw_device *fwdev;
558	int rev;
559
560	fwdev = sdev->target->fwdev;
561	bzero(sdev->vendor, sizeof(sdev->vendor));
562	bzero(sdev->product, sizeof(sdev->product));
563	sbp_get_text_leaf(fwdev, 0x03, sdev->vendor, sizeof(sdev->vendor));
564	sbp_get_text_leaf(fwdev, 0x17, sdev->product, sizeof(sdev->product));
565	rev = getcsrdata(sdev->target->fwdev, 0x3c);
566	snprintf(sdev->revision, sizeof(sdev->revision), "%06x", rev);
567}
568static void
569sbp_probe_target(struct sbp_target *target, int alive)
570{
571	struct sbp_softc *sbp;
572	struct sbp_dev *sdev;
573	struct firewire_comm *fc;
574	int i;
575
576SBP_DEBUG(1)
577	printf("sbp_probe_target %d\n", target->target_id);
578	if (!alive)
579		printf("not alive\n");
580END_DEBUG
581
582	sbp = target->sbp;
583	fc = target->sbp->fd.fc;
584	for (i=0; i < target->num_lun; i++) {
585		sdev = &target->luns[i];
586		if (alive && (sdev->status != SBP_DEV_DEAD)) {
587			if (sdev->path != NULL) {
588				xpt_freeze_devq(sdev->path, 1);
589			}
590			sbp_abort_all_ocbs(sdev, CAM_REQUEUE_REQ);
591			switch (sdev->status) {
592			case SBP_DEV_RESET:
593				/* new or revived target */
594				sbp_probe_lun(sdev);
595				if (auto_login) {
596					sdev->status = SBP_DEV_TOATTACH;
597					sbp_mgm_orb(sdev, ORB_FUN_LGI, 0, 0);
598				}
599				break;
600			case SBP_DEV_RETRY:
601				sbp_probe_lun(sdev);
602			default:
603				sbp_mgm_orb(sdev, ORB_FUN_RCN, 0, 0);
604				break;
605			}
606SBP_DEBUG(0)
607			sbp_show_sdev_info(sdev,
608					(sdev->status == SBP_DEV_TOATTACH));
609END_DEBUG
610		} else {
611			switch (sdev->status) {
612			case SBP_DEV_ATTACHED:
613SBP_DEBUG(0)
614				/* the device has gone */
615				sbp_show_sdev_info(sdev, 2);
616				printf("lost target\n");
617END_DEBUG
618				if (sdev->path)
619					xpt_freeze_devq(sdev->path, 1);
620				sdev->status = SBP_DEV_RETRY;
621				sbp_abort_all_ocbs(sdev, CAM_REQUEUE_REQ);
622				break;
623			case SBP_DEV_PROBE:
624			case SBP_DEV_TOATTACH:
625				sdev->status = SBP_DEV_RESET;
626				break;
627			case SBP_DEV_RETRY:
628			case SBP_DEV_RESET:
629			case SBP_DEV_DEAD:
630				break;
631			}
632		}
633	}
634}
635
636static void
637sbp_post_explore(void *arg)
638{
639	struct sbp_softc *sbp = (struct sbp_softc *)arg;
640	struct sbp_target *target;
641	struct fw_device *fwdev;
642	int i, alive;
643
644SBP_DEBUG(0)
645	printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold);
646END_DEBUG
647#if 0
648	xpt_freeze_simq(sbp->sim, /*count*/ 1);
649#endif
650	if (sbp_cold > 0)
651		sbp_cold --;
652	/* Gabage Collection */
653	for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
654		target = &sbp->targets[i];
655		STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link)
656			if (target->fwdev == NULL || target->fwdev == fwdev)
657				break;
658		if(fwdev == NULL){
659			/* device has removed in lower driver */
660			sbp_cam_detach_target(target);
661			if (target->luns != NULL)
662				free(target->luns, M_SBP);
663			target->num_lun = 0;;
664			target->luns = NULL;
665			target->fwdev = NULL;
666		}
667	}
668	/* traverse device list */
669	STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) {
670SBP_DEBUG(0)
671		printf("sbp_post_explore: EUI:%08x%08x ",
672				fwdev->eui.hi, fwdev->eui.lo);
673		if (fwdev->status == FWDEVATTACHED) {
674			printf("spec=%d key=%d.\n",
675			getcsrdata(fwdev, CSRKEY_SPEC) == CSRVAL_ANSIT10,
676			getcsrdata(fwdev, CSRKEY_VER) == CSRVAL_T10SBP2);
677		} else {
678			printf("not attached, state=%d.\n", fwdev->status);
679		}
680END_DEBUG
681		alive = (fwdev->status == FWDEVATTACHED)
682			&& (getcsrdata(fwdev, CSRKEY_SPEC) == CSRVAL_ANSIT10)
683			&& (getcsrdata(fwdev, CSRKEY_VER) == CSRVAL_T10SBP2);
684		for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
685			target = &sbp->targets[i];
686			if(target->fwdev == fwdev ) {
687				/* known target */
688				break;
689			}
690		}
691		if(i == SBP_NUM_TARGETS){
692			if (alive) {
693				/* new target */
694				target = sbp_alloc_target(sbp, fwdev);
695				if (target == NULL)
696					continue;
697			} else {
698				continue;
699			}
700		}
701		sbp_probe_target(target, alive);
702	}
703#if 0
704	timeout(sbp_release_queue, (caddr_t)sbp, bus_reset_rest * hz / 1000);
705#endif
706}
707
708#if NEED_RESPONSE
709static void
710sbp_loginres_callback(struct fw_xfer *xfer){
711SBP_DEBUG(1)
712	struct sbp_dev *sdev;
713	sdev = (struct sbp_dev *)xfer->sc;
714	sbp_show_sdev_info(sdev, 2);
715	printf("sbp_loginres_callback\n");
716END_DEBUG
717	fw_xfer_free(xfer);
718	return;
719}
720#endif
721
722static void
723sbp_login_callback(struct fw_xfer *xfer)
724{
725SBP_DEBUG(1)
726	struct sbp_dev *sdev;
727	sdev = (struct sbp_dev *)xfer->sc;
728	sbp_show_sdev_info(sdev, 2);
729	printf("sbp_login_callback\n");
730END_DEBUG
731	fw_xfer_free(xfer);
732	return;
733}
734
735static void
736sbp_cmd_callback(struct fw_xfer *xfer)
737{
738SBP_DEBUG(2)
739	struct sbp_dev *sdev;
740	sdev = (struct sbp_dev *)xfer->sc;
741	sbp_show_sdev_info(sdev, 2);
742	printf("sbp_cmd_callback\n");
743END_DEBUG
744	fw_xfer_free(xfer);
745	return;
746}
747
748static void
749sbp_cam_callback(struct cam_periph *periph, union ccb *ccb)
750{
751	struct sbp_dev *sdev;
752	sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
753SBP_DEBUG(0)
754	sbp_show_sdev_info(sdev, 2);
755	printf("sbp_cam_callback\n");
756END_DEBUG
757	sdev->status = SBP_DEV_ATTACHED;
758	free(ccb, M_SBP);
759}
760
761static void
762sbp_cam_scan_lun(struct sbp_dev *sdev)
763{
764	union ccb *ccb;
765
766	ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
767	if (ccb == NULL) {
768		printf("sbp_cam_scan_lun: malloc failed\n");
769		return;
770	}
771
772SBP_DEBUG(0)
773	sbp_show_sdev_info(sdev, 2);
774	printf("sbp_cam_scan_lun\n");
775END_DEBUG
776	xpt_setup_ccb(&ccb->ccb_h, sdev->path, 5/*priority (low)*/);
777	ccb->ccb_h.func_code = XPT_SCAN_LUN;
778	ccb->ccb_h.cbfcnp = sbp_cam_callback;
779	ccb->crcn.flags = CAM_FLAG_NONE;
780	ccb->ccb_h.ccb_sdev_ptr = sdev;
781
782	/* The scan is in progress now. */
783	sdev->status = SBP_DEV_PROBE;
784	xpt_action(ccb);
785}
786
787
788static void
789sbp_ping_unit_callback(struct cam_periph *periph, union ccb *ccb)
790{
791	struct sbp_dev *sdev;
792	sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
793SBP_DEBUG(0)
794	sbp_show_sdev_info(sdev, 2);
795	printf("sbp_ping_unit_callback\n");
796END_DEBUG
797	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
798		if (--ccb->ccb_h.retry_count == 0) {
799			sbp_show_sdev_info(sdev, 2);
800			printf("sbp_ping_unit_callback: "
801				"retry count exceeded\n");
802			sdev->status = SBP_DEV_RETRY;
803			free(ccb, M_SBP);
804		} else {
805			/* requeue */
806			xpt_action(ccb);
807			xpt_release_devq(sdev->path, MAX_FREEZE, TRUE);
808		}
809	} else {
810		free(ccb->csio.data_ptr, M_SBP);
811		free(ccb, M_SBP);
812		sdev->status = SBP_DEV_ATTACHED;
813		xpt_release_devq(sdev->path, MAX_FREEZE, TRUE);
814	}
815}
816
817/*
818 * XXX Some devices need to execute inquiry or read_capacity
819 * after bus_rest during busy transfer.
820 * Otherwise they return incorrect result for READ(and WRITE?)
821 * command without any SBP-II/SCSI error.
822 *
823 * e.g. Maxtor 3000XT, Yano A-dish.
824 */
825static void
826sbp_ping_unit(struct sbp_dev *sdev)
827{
828	union ccb *ccb;
829	struct scsi_inquiry_data *inq_buf;
830
831
832	ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
833	if (ccb == NULL) {
834		printf("sbp_ping_unit: malloc failed\n");
835		return;
836	}
837
838	inq_buf = (struct scsi_inquiry_data *)
839			malloc(sizeof(*inq_buf), M_SBP, M_NOWAIT);
840	if (inq_buf == NULL) {
841		free(ccb, M_SBP);
842		printf("sbp_ping_unit: malloc failed\n");
843		return;
844	}
845
846SBP_DEBUG(0)
847	sbp_show_sdev_info(sdev, 2);
848	printf("sbp_ping_unit\n");
849END_DEBUG
850
851	/*
852	 * We need to execute this command before any other queued command.
853	 * Make priority 0 and freeze queue after execution for retry.
854	 * cam's scan_lun command doesn't provide this feature.
855	 */
856	xpt_setup_ccb(&ccb->ccb_h, sdev->path, 0/*priority (high)*/);
857	scsi_inquiry(
858		&ccb->csio,
859		/*retries*/ 5,
860		sbp_ping_unit_callback,
861		MSG_SIMPLE_Q_TAG,
862		(u_int8_t *)inq_buf,
863		SHORT_INQUIRY_LENGTH,
864		/*evpd*/FALSE,
865		/*page_code*/0,
866		SSD_MIN_SIZE,
867		/*timeout*/60000
868	);
869	ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
870	xpt_action(ccb);
871	sdev->status = SBP_DEV_PROBE;
872}
873
874static void
875sbp_do_attach(struct fw_xfer *xfer)
876{
877	struct sbp_dev *sdev;
878
879	sdev = (struct sbp_dev *)xfer->sc;
880SBP_DEBUG(0)
881	sbp_show_sdev_info(sdev, 2);
882	printf("sbp_do_attach\n");
883END_DEBUG
884	fw_xfer_free(xfer);
885
886	if (sdev->path == NULL)
887		xpt_create_path(&sdev->path, xpt_periph,
888			cam_sim_path(sdev->target->sbp->sim),
889			sdev->target->target_id, sdev->lun_id);
890
891	/*
892	 * Let CAM scan the bus if we are in the boot process.
893	 * XXX xpt_scan_bus cannot detect LUN larger than 0
894	 * if LUN 0 doesn't exists.
895	 */
896	if (sbp_cold > 0) {
897		sdev->status = SBP_DEV_PROBE;
898		return;
899	}
900
901	if (sdev->status == SBP_DEV_RETRY)
902		sbp_ping_unit(sdev);
903	else
904		sbp_cam_scan_lun(sdev);
905	xpt_release_devq(sdev->path, MAX_FREEZE, TRUE);
906	return;
907}
908
909static void
910sbp_agent_reset_callback(struct fw_xfer *xfer)
911{
912	struct sbp_dev *sdev;
913
914	sdev = (struct sbp_dev *)xfer->sc;
915SBP_DEBUG(1)
916	sbp_show_sdev_info(sdev, 2);
917	printf("sbp_cmd_callback\n");
918END_DEBUG
919	fw_xfer_free(xfer);
920	sbp_abort_all_ocbs(sdev, CAM_REQUEUE_REQ);
921	if (sdev->path)
922		xpt_release_devq(sdev->path, MAX_FREEZE, TRUE);
923}
924
925static void
926sbp_agent_reset(struct sbp_dev *sdev)
927{
928	struct fw_xfer *xfer;
929	struct fw_pkt *fp;
930
931SBP_DEBUG(0)
932	sbp_show_sdev_info(sdev, 2);
933	printf("sbp_agent_reset\n");
934END_DEBUG
935	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
936	if (xfer == NULL)
937		return;
938	if (sdev->status == SBP_DEV_ATTACHED)
939		xfer->act.hand = sbp_agent_reset_callback;
940	else
941		xfer->act.hand = sbp_do_attach;
942	fp = (struct fw_pkt *)xfer->send.buf;
943	fp->mode.wreqq.data = htonl(0xf);
944	fw_asyreq(xfer->fc, -1, xfer);
945}
946
947static void
948sbp_busy_timeout_callback(struct fw_xfer *xfer)
949{
950	struct sbp_dev *sdev;
951
952	sdev = (struct sbp_dev *)xfer->sc;
953SBP_DEBUG(1)
954	sbp_show_sdev_info(sdev, 2);
955	printf("sbp_busy_timeout_callback\n");
956END_DEBUG
957	fw_xfer_free(xfer);
958	sbp_agent_reset(sdev);
959}
960
961static void
962sbp_busy_timeout(struct sbp_dev *sdev)
963{
964	struct fw_pkt *fp;
965	struct fw_xfer *xfer;
966SBP_DEBUG(0)
967	sbp_show_sdev_info(sdev, 2);
968	printf("sbp_busy_timeout\n");
969END_DEBUG
970	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
971
972	xfer->act.hand = sbp_busy_timeout_callback;
973	fp = (struct fw_pkt *)xfer->send.buf;
974	fp->mode.wreqq.dest_hi = htons(0xffff);
975	fp->mode.wreqq.dest_lo = htonl(0xf0000000 | BUSY_TIMEOUT);
976	fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf);
977	fw_asyreq(xfer->fc, -1, xfer);
978}
979
980#if 0
981static void
982sbp_reset_start(struct sbp_dev *sdev)
983{
984	struct fw_xfer *xfer;
985	struct fw_pkt *fp;
986
987SBP_DEBUG(0)
988	sbp_show_sdev_info(sdev, 2);
989	printf("sbp_reset_start\n");
990END_DEBUG
991	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
992
993	xfer->act.hand = sbp_busy_timeout;
994	fp = (struct fw_pkt *)xfer->send.buf;
995	fp->mode.wreqq.dest_hi = htons(0xffff);
996	fp->mode.wreqq.dest_lo = htonl(0xf0000000 | RESET_START);
997	fp->mode.wreqq.data = htonl(0xf);
998	fw_asyreq(xfer->fc, -1, xfer);
999}
1000#endif
1001
1002static void
1003sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb)
1004{
1005	struct fw_xfer *xfer;
1006	struct fw_pkt *fp;
1007SBP_DEBUG(2)
1008	sbp_show_sdev_info(sdev, 2);
1009	printf("sbp_orb_pointer\n");
1010END_DEBUG
1011
1012	xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0x08);
1013	if (xfer == NULL)
1014		return;
1015	xfer->act.hand = sbp_cmd_callback;
1016
1017	fp = (struct fw_pkt *)xfer->send.buf;
1018	fp->mode.wreqb.len = htons(8);
1019	fp->mode.wreqb.extcode = 0;
1020	fp->mode.wreqb.payload[0] =
1021		htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
1022	fp->mode.wreqb.payload[1] = htonl(vtophys(&ocb->orb[0]));
1023
1024	if(fw_asyreq(xfer->fc, -1, xfer) != 0){
1025			fw_xfer_free(xfer);
1026			ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
1027			xpt_done(ocb->ccb);
1028	}
1029}
1030
1031static void
1032sbp_doorbell(struct sbp_dev *sdev)
1033{
1034	struct fw_xfer *xfer;
1035	struct fw_pkt *fp;
1036SBP_DEBUG(1)
1037	sbp_show_sdev_info(sdev, 2);
1038	printf("sbp_doorbell\n");
1039END_DEBUG
1040
1041	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x10);
1042	if (xfer == NULL)
1043		return;
1044	xfer->act.hand = sbp_cmd_callback;
1045	fp = (struct fw_pkt *)xfer->send.buf;
1046	fp->mode.wreqq.data = htonl(0xf);
1047	fw_asyreq(xfer->fc, -1, xfer);
1048}
1049
1050static struct fw_xfer *
1051sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
1052{
1053	struct fw_xfer *xfer;
1054	struct fw_pkt *fp;
1055
1056	xfer = fw_xfer_alloc(M_SBP);
1057	if(xfer == NULL){
1058		return NULL;
1059	}
1060	if (tcode == FWTCODE_WREQQ)
1061		xfer->send.len = 16;
1062	else
1063		xfer->send.len = 24;
1064
1065	xfer->send.buf = malloc(xfer->send.len, M_FW, M_NOWAIT);
1066	if(xfer->send.buf == NULL){
1067		fw_xfer_free(xfer);
1068		return NULL;
1069	}
1070
1071	xfer->send.off = 0;
1072	xfer->spd = min(sdev->target->fwdev->speed, max_speed);
1073	xfer->sc = (caddr_t)sdev;
1074	xfer->fc = sdev->target->sbp->fd.fc;
1075	xfer->retry_req = fw_asybusy;
1076
1077	fp = (struct fw_pkt *)xfer->send.buf;
1078	fp->mode.wreqq.dest_hi = htons(sdev->login.cmd_hi);
1079	fp->mode.wreqq.dest_lo = htonl(sdev->login.cmd_lo + offset);
1080	fp->mode.wreqq.tlrt = 0;
1081	fp->mode.wreqq.tcode = tcode;
1082	fp->mode.wreqq.pri = 0;
1083	xfer->dst = FWLOCALBUS | sdev->target->fwdev->dst;
1084	fp->mode.wreqq.dst = htons(xfer->dst);
1085
1086	return xfer;
1087
1088}
1089
1090static void
1091sbp_mgm_orb(struct sbp_dev *sdev, int func, u_int16_t orb_hi, u_int32_t orb_lo)
1092{
1093	struct fw_xfer *xfer;
1094	struct fw_pkt *fp;
1095	struct sbp_ocb *ocb;
1096	int s, nid;
1097
1098	if ((ocb = sbp_get_ocb(sdev->target->sbp)) == NULL) {
1099		s = splfw();
1100		sdev->target->sbp->flags |= SBP_RESOURCE_SHORTAGE;
1101		splx(s);
1102		return;
1103	}
1104	ocb->flags = OCB_ACT_MGM;
1105	ocb->sdev = sdev;
1106	ocb->ccb = NULL;
1107
1108	nid = sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS;
1109	bzero((void *)(uintptr_t)(volatile void *)ocb->orb, sizeof(ocb->orb));
1110	ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
1111	ocb->orb[7] = htonl(SBP_DEV2ADDR(
1112		device_get_unit(sdev->target->sbp->fd.dev),
1113		sdev->target->target_id,
1114		sdev->lun_id));
1115
1116SBP_DEBUG(0)
1117	sbp_show_sdev_info(sdev, 2);
1118	printf("%s\n", orb_fun_name[(func>>16)&0xf]);
1119END_DEBUG
1120	switch (func) {
1121	case ORB_FUN_LGI:
1122		ocb->orb[2] = htonl(nid << 16);
1123		ocb->orb[3] = htonl(vtophys(&sdev->login));
1124		ocb->orb[4] = htonl(ORB_NOTIFY | ORB_EXV | sdev->lun_id);
1125		ocb->orb[5] = htonl(sizeof(struct sbp_login_res));
1126		break;
1127	case ORB_FUN_ATA:
1128		ocb->orb[0] = htonl((0 << 16) | orb_hi);
1129		ocb->orb[1] = htonl(orb_lo);
1130		/* fall through */
1131	case ORB_FUN_RCN:
1132	case ORB_FUN_LGO:
1133	case ORB_FUN_LUR:
1134	case ORB_FUN_RST:
1135	case ORB_FUN_ATS:
1136		ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login.id);
1137		break;
1138	}
1139
1140	xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
1141	if(xfer == NULL){
1142		return;
1143	}
1144	xfer->act.hand = sbp_login_callback;
1145
1146	fp = (struct fw_pkt *)xfer->send.buf;
1147	fp->mode.wreqb.dest_hi = htons(sdev->target->mgm_hi);
1148	fp->mode.wreqb.dest_lo = htonl(sdev->target->mgm_lo);
1149	fp->mode.wreqb.len = htons(8);
1150	fp->mode.wreqb.extcode = 0;
1151	fp->mode.wreqb.payload[0] = htonl(nid << 16);
1152	fp->mode.wreqb.payload[1] = htonl(vtophys(&ocb->orb[0]));
1153	sbp_enqueue_ocb(sdev, ocb);
1154
1155	fw_asyreq(xfer->fc, -1, xfer);
1156}
1157
1158static void
1159sbp_print_scsi_cmd(struct sbp_ocb *ocb)
1160{
1161	struct ccb_scsiio *csio;
1162
1163	csio = &ocb->ccb->csio;
1164	printf("%s:%d:%d XPT_SCSI_IO: "
1165		"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1166		", flags: 0x%02x, "
1167		"%db cmd/%db data/%db sense\n",
1168		device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
1169		ocb->ccb->ccb_h.target_id, ocb->ccb->ccb_h.target_lun,
1170		csio->cdb_io.cdb_bytes[0],
1171		csio->cdb_io.cdb_bytes[1],
1172		csio->cdb_io.cdb_bytes[2],
1173		csio->cdb_io.cdb_bytes[3],
1174		csio->cdb_io.cdb_bytes[4],
1175		csio->cdb_io.cdb_bytes[5],
1176		csio->cdb_io.cdb_bytes[6],
1177		csio->cdb_io.cdb_bytes[7],
1178		csio->cdb_io.cdb_bytes[8],
1179		csio->cdb_io.cdb_bytes[9],
1180		ocb->ccb->ccb_h.flags & CAM_DIR_MASK,
1181		csio->cdb_len, csio->dxfer_len,
1182		csio->sense_len);
1183}
1184
1185static void
1186sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
1187{
1188	struct sbp_cmd_status *sbp_cmd_status;
1189	struct scsi_sense_data *sense;
1190
1191	sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
1192	sense = &ocb->ccb->csio.sense_data;
1193
1194SBP_DEBUG(0)
1195	sbp_print_scsi_cmd(ocb);
1196	/* XXX need decode status */
1197	sbp_show_sdev_info(ocb->sdev, 2);
1198	printf("SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d",
1199		sbp_cmd_status->status,
1200		sbp_cmd_status->sfmt,
1201		sbp_cmd_status->valid,
1202		sbp_cmd_status->s_key,
1203		sbp_cmd_status->s_code,
1204		sbp_cmd_status->s_qlfr,
1205		sbp_status->len
1206	);
1207#if 0	 /* XXX */
1208	if (sbp_cmd_status->status == SCSI_STATUS_CHECK_COND) {
1209		printf(" %s\n", scsi_sense_key_text[sbp_cmd_status->s_key]);
1210			scsi_sense_desc(
1211				sbp_cmd_status->s_code,
1212				sbp_cmd_status->s_qlfr,
1213				ocb->ccb->ccb_h.path->device->inq_data
1214			)
1215	} else {
1216		printf("\n");
1217	}
1218#else
1219	printf("\n");
1220#endif
1221END_DEBUG
1222
1223	switch (sbp_cmd_status->status) {
1224	case SCSI_STATUS_CHECK_COND:
1225	case SCSI_STATUS_BUSY:
1226	case SCSI_STATUS_CMD_TERMINATED:
1227		if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
1228			sense->error_code = SSD_CURRENT_ERROR;
1229		}else{
1230			sense->error_code = SSD_DEFERRED_ERROR;
1231		}
1232		if(sbp_cmd_status->valid)
1233			sense->error_code |= SSD_ERRCODE_VALID;
1234		sense->flags = sbp_cmd_status->s_key;
1235		if(sbp_cmd_status->mark)
1236			sense->flags |= SSD_FILEMARK;
1237		if(sbp_cmd_status->eom)
1238			sense->flags |= SSD_EOM;
1239		if(sbp_cmd_status->ill_len)
1240			sense->flags |= SSD_ILI;
1241		sense->info[0] = ntohl(sbp_cmd_status->info) & 0xff;
1242		sense->info[1] =(ntohl(sbp_cmd_status->info) >> 8) & 0xff;
1243		sense->info[2] =(ntohl(sbp_cmd_status->info) >> 16) & 0xff;
1244		sense->info[3] =(ntohl(sbp_cmd_status->info) >> 24) & 0xff;
1245		if (sbp_status->len <= 1)
1246			/* XXX not scsi status. shouldn't be happened */
1247			sense->extra_len = 0;
1248		else if (sbp_status->len <= 4)
1249			/* add_sense_code(_qual), info, cmd_spec_info */
1250			sense->extra_len = 6;
1251		else
1252			/* fru, sense_key_spec */
1253			sense->extra_len = 10;
1254		sense->cmd_spec_info[0] = ntohl(sbp_cmd_status->cdb) & 0xff;
1255		sense->cmd_spec_info[1] = (ntohl(sbp_cmd_status->cdb) >> 8) & 0xff;
1256		sense->cmd_spec_info[2] = (ntohl(sbp_cmd_status->cdb) >> 16) & 0xff;
1257		sense->cmd_spec_info[3] = (ntohl(sbp_cmd_status->cdb) >> 24) & 0xff;
1258		sense->add_sense_code = sbp_cmd_status->s_code;
1259		sense->add_sense_code_qual = sbp_cmd_status->s_qlfr;
1260		sense->fru = sbp_cmd_status->fru;
1261		sense->sense_key_spec[0] = ntohl(sbp_cmd_status->s_keydep) & 0xff;
1262		sense->sense_key_spec[1] = (ntohl(sbp_cmd_status->s_keydep) >>8) & 0xff;
1263		sense->sense_key_spec[2] = (ntohl(sbp_cmd_status->s_keydep) >>16) & 0xff;
1264
1265		ocb->ccb->csio.scsi_status = sbp_cmd_status->status;;
1266		ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
1267							| CAM_AUTOSNS_VALID;
1268/*
1269{
1270		u_int8_t j, *tmp;
1271		tmp = sense;
1272		for( j = 0 ; j < 32 ; j+=8){
1273			printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
1274				tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
1275				tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
1276		}
1277
1278}
1279*/
1280		break;
1281	default:
1282		sbp_show_sdev_info(ocb->sdev, 2);
1283		printf("sbp_scsi_status: unknown scsi status 0x%x\n",
1284						sbp_cmd_status->status);
1285	}
1286}
1287
1288static void
1289sbp_fix_inq_data(struct sbp_ocb *ocb)
1290{
1291	union ccb *ccb;
1292	struct sbp_dev *sdev;
1293	struct scsi_inquiry_data *inq;
1294
1295	ccb = ocb->ccb;
1296	sdev = ocb->sdev;
1297
1298	if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD)
1299		return;
1300SBP_DEBUG(1)
1301	sbp_show_sdev_info(sdev, 2);
1302	printf("sbp_fix_inq_data\n");
1303END_DEBUG
1304	inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr;
1305	switch (SID_TYPE(inq)) {
1306	case T_DIRECT:
1307		/*
1308		 * XXX Convert Direct Access device to RBC.
1309		 * I've never seen FireWire DA devices which support READ_6.
1310		 */
1311#if 1
1312		if (SID_TYPE(inq) == T_DIRECT)
1313			inq->device |= T_RBC; /*  T_DIRECT == 0 */
1314#endif
1315		/* fall through */
1316	case T_RBC:
1317		/* disable tag queuing */
1318		inq->flags &= ~SID_CmdQue;
1319		/*
1320		 * Override vendor/product/revision information.
1321		 * Some devices sometimes return strange strings.
1322		 */
1323		bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor));
1324		bcopy(sdev->product, inq->product, sizeof(inq->product));
1325		bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision));
1326		break;
1327	}
1328}
1329
1330static void
1331sbp_recv1(struct fw_xfer *xfer){
1332	struct fw_pkt *rfp;
1333#if NEED_RESPONSE
1334	struct fw_pkt *sfp;
1335#endif
1336	struct sbp_softc *sbp;
1337	struct sbp_dev *sdev;
1338	struct sbp_ocb *ocb;
1339	struct sbp_login_res *login_res = NULL;
1340	struct sbp_status *sbp_status;
1341	struct sbp_target *target;
1342	int	orb_fun, status_valid, t, l;
1343	u_int32_t addr;
1344/*
1345	u_int32_t *ld;
1346	ld = xfer->recv.buf;
1347printf("sbp %x %d %d %08x %08x %08x %08x\n",
1348			xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1349printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1350printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1351*/
1352	if(xfer->resp != 0){
1353		printf("sbp_recv: xfer->resp != 0\n");
1354		fw_xfer_free( xfer);
1355		return;
1356	}
1357	if(xfer->recv.buf == NULL){
1358		printf("sbp_recv: xfer->recv.buf == NULL\n");
1359		fw_xfer_free( xfer);
1360		return;
1361	}
1362	sbp = (struct sbp_softc *)xfer->sc;
1363	rfp = (struct fw_pkt *)xfer->recv.buf;
1364	if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
1365		printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
1366		fw_xfer_free( xfer);
1367		return;
1368	}
1369	sbp_status = (struct sbp_status *)rfp->mode.wreqb.payload;
1370	addr = ntohl(rfp->mode.wreqb.dest_lo);
1371SBP_DEBUG(2)
1372	printf("received address 0x%x\n", addr);
1373END_DEBUG
1374	t = SBP_ADDR2TRG(addr);
1375	if (t >= SBP_NUM_TARGETS) {
1376		device_printf(sbp->fd.dev,
1377			"sbp_recv1: invalid target %d\n", t);
1378		fw_xfer_free(xfer);
1379		return;
1380	}
1381	target = &sbp->targets[t];
1382	l = SBP_ADDR2LUN(addr);
1383	if (l >= target->num_lun) {
1384		device_printf(sbp->fd.dev,
1385			"sbp_recv1: invalid lun %d (target=%d)\n", l, t);
1386		fw_xfer_free(xfer);
1387		return;
1388	}
1389	sdev = &target->luns[l];
1390
1391	ocb = NULL;
1392	switch (sbp_status->src) {
1393	case 0:
1394	case 1:
1395		ocb = sbp_dequeue_ocb(sdev, ntohl(sbp_status->orb_lo));
1396		if (ocb == NULL) {
1397			sbp_show_sdev_info(sdev, 2);
1398			printf("No ocb on the queue\n");
1399		}
1400		break;
1401	case 2:
1402		/* unsolicit */
1403		sbp_show_sdev_info(sdev, 2);
1404		printf("unsolicit status received\n");
1405		break;
1406	default:
1407		sbp_show_sdev_info(sdev, 2);
1408		printf("unknown sbp_status->src\n");
1409	}
1410
1411	status_valid = (sbp_status->src < 2
1412			&& sbp_status->resp == ORB_RES_CMPL
1413			&& sbp_status->dead == 0
1414			&& sbp_status->status == 0);
1415
1416	if (!status_valid || debug > 1){
1417		int status;
1418SBP_DEBUG(0)
1419		sbp_show_sdev_info(sdev, 2);
1420		printf("ORB status src:%x resp:%x dead:%x"
1421#if __FreeBSD_version >= 500000
1422				" len:%x stat:%x orb:%x%08x\n",
1423#else
1424				" len:%x stat:%x orb:%x%08lx\n",
1425#endif
1426			sbp_status->src, sbp_status->resp, sbp_status->dead,
1427			sbp_status->len, sbp_status->status,
1428			ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
1429END_DEBUG
1430		sbp_show_sdev_info(sdev, 2);
1431		status = sbp_status->status;
1432		switch(sbp_status->resp) {
1433		case 0:
1434			if (status > MAX_ORB_STATUS0)
1435				printf("%s\n", orb_status0[MAX_ORB_STATUS0]);
1436			else
1437				printf("%s\n", orb_status0[status]);
1438			break;
1439		case 1:
1440			printf("Obj: %s, Error: %s\n",
1441				orb_status1_object[(status>>6) & 3],
1442				orb_status1_serial_bus_error[status & 0xf]);
1443			break;
1444		case 2:
1445			printf("Illegal request\n");
1446			break;
1447		case 3:
1448			printf("Vendor dependent\n");
1449			break;
1450		default:
1451			printf("unknown respose code %d\n", sbp_status->resp);
1452		}
1453	}
1454
1455	/* we have to reset the fetch agent if it's dead */
1456	if (sbp_status->dead) {
1457		if (sdev->path)
1458			xpt_freeze_devq(sdev->path, 1);
1459		sbp_agent_reset(sdev);
1460	}
1461
1462	if (ocb == NULL) {
1463		fw_xfer_free(xfer);
1464		return;
1465	}
1466
1467	sdev->flags &= ~SBP_DEV_TIMEOUT;
1468
1469	switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
1470	case ORB_FMT_NOP:
1471		break;
1472	case ORB_FMT_VED:
1473		break;
1474	case ORB_FMT_STD:
1475		switch(ocb->flags & OCB_ACT_MASK){
1476		case OCB_ACT_MGM:
1477			orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK;
1478			switch(orb_fun) {
1479			case ORB_FUN_LGI:
1480				login_res = &sdev->login;
1481				login_res->len = ntohs(login_res->len);
1482				login_res->id = ntohs(login_res->id);
1483				login_res->cmd_hi = ntohs(login_res->cmd_hi);
1484				login_res->cmd_lo = ntohl(login_res->cmd_lo);
1485				if (status_valid) {
1486SBP_DEBUG(0)
1487sbp_show_sdev_info(sdev, 2);
1488printf("login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo, ntohs(login_res->recon_hold));
1489END_DEBUG
1490#if 1
1491					sbp_busy_timeout(sdev);
1492#else
1493					sbp_mgm_orb(sdev, ORB_FUN_ATS, 0, 0);
1494#endif
1495				} else {
1496					/* forgot logout? */
1497					sbp_show_sdev_info(sdev, 2);
1498					printf("login failed\n");
1499					sdev->status = SBP_DEV_RESET;
1500				}
1501				break;
1502			case ORB_FUN_RCN:
1503				login_res = &sdev->login;
1504				if (status_valid) {
1505SBP_DEBUG(0)
1506sbp_show_sdev_info(sdev, 2);
1507printf("reconnect: len %d, ID %d, cmd %08x%08x\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo);
1508END_DEBUG
1509#if 1
1510					sbp_ping_unit(sdev);
1511					xpt_release_devq(sdev->path,
1512							MAX_FREEZE, TRUE);
1513#else
1514					sdev->status = SBP_DEV_ATTACHED;
1515					sbp_mgm_orb(sdev, ORB_FUN_ATS, 0, 0);
1516#endif
1517				} else {
1518					/* reconnection hold time exceed? */
1519SBP_DEBUG(0)
1520					sbp_show_sdev_info(sdev, 2);
1521					printf("reconnect failed\n");
1522END_DEBUG
1523					sbp_mgm_orb(sdev, ORB_FUN_LGI, 0, 0);
1524				}
1525				break;
1526			case ORB_FUN_LGO:
1527				sdev->status = SBP_DEV_RESET;
1528				break;
1529			case ORB_FUN_RST:
1530				sbp_busy_timeout(sdev);
1531				break;
1532			case ORB_FUN_LUR:
1533			case ORB_FUN_ATA:
1534			case ORB_FUN_ATS:
1535				sbp_agent_reset(sdev);
1536				break;
1537			default:
1538				sbp_show_sdev_info(sdev, 2);
1539				printf("unknown function %d\n", orb_fun);
1540				break;
1541			}
1542			break;
1543		case OCB_ACT_CMD:
1544			if(ocb->ccb != NULL){
1545				union ccb *ccb;
1546/*
1547				u_int32_t *ld;
1548				ld = ocb->ccb->csio.data_ptr;
1549				if(ld != NULL && ocb->ccb->csio.dxfer_len != 0)
1550					printf("ptr %08x %08x %08x %08x\n", ld[0], ld[1], ld[2], ld[3]);
1551				else
1552					printf("ptr NULL\n");
1553printf("len %d\n", sbp_status->len);
1554*/
1555				ccb = ocb->ccb;
1556				if(sbp_status->len > 1){
1557					sbp_scsi_status(sbp_status, ocb);
1558				}else{
1559					if(sbp_status->resp != ORB_RES_CMPL){
1560						ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1561					}else{
1562						ccb->ccb_h.status = CAM_REQ_CMP;
1563					}
1564				}
1565				/* fix up inq data */
1566				if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1567					sbp_fix_inq_data(ocb);
1568				xpt_done(ccb);
1569			}
1570			break;
1571		default:
1572			break;
1573		}
1574	}
1575
1576	if (!(ocb->flags & OCB_RESERVED))
1577		sbp_free_ocb(sbp, ocb);
1578
1579/* The received packet is usually small enough to be stored within
1580 * the buffer. In that case, the controller return ack_complete and
1581 * no respose is necessary.
1582 *
1583 * XXX fwohci.c and firewire.c should inform event_code such as
1584 * ack_complete or ack_pending to upper driver.
1585 */
1586#if NEED_RESPONSE
1587	xfer->send.buf = malloc(12, M_SBP, M_NOWAIT | M_ZERO);
1588	xfer->send.len = 12;
1589	xfer->send.off = 0;
1590	sfp = (struct fw_pkt *)xfer->send.buf;
1591	sfp->mode.wres.dst = rfp->mode.wreqb.src;
1592	xfer->dst = ntohs(sfp->mode.wres.dst);
1593	xfer->spd = min(sdev->target->fwdev->speed, max_speed);
1594	xfer->act.hand = sbp_loginres_callback;
1595	xfer->retry_req = fw_asybusy;
1596
1597	sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1598	sfp->mode.wres.tcode = FWTCODE_WRES;
1599	sfp->mode.wres.rtcode = 0;
1600	sfp->mode.wres.pri = 0;
1601
1602	fw_asyreq(xfer->fc, -1, xfer);
1603#else
1604	fw_xfer_free(xfer);
1605#endif
1606
1607	return;
1608
1609}
1610
1611static void
1612sbp_recv(struct fw_xfer *xfer)
1613{
1614	int s;
1615
1616	s = splcam();
1617	sbp_recv1(xfer);
1618	splx(s);
1619}
1620/*
1621 * sbp_attach()
1622 */
1623static int
1624sbp_attach(device_t dev)
1625{
1626	struct sbp_softc *sbp;
1627	struct cam_devq *devq;
1628	struct fw_xfer *xfer;
1629	int i, s, error;
1630
1631SBP_DEBUG(0)
1632	printf("sbp_attach (cold=%d)\n", cold);
1633END_DEBUG
1634
1635	if (cold)
1636		sbp_cold ++;
1637	sbp = ((struct sbp_softc *)device_get_softc(dev));
1638	bzero(sbp, sizeof(struct sbp_softc));
1639	sbp->fd.dev = dev;
1640	sbp->fd.fc = device_get_ivars(dev);
1641	error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
1642				/*boundary*/0,
1643				/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1644				/*highaddr*/BUS_SPACE_MAXADDR,
1645				/*filter*/NULL, /*filterarg*/NULL,
1646				/*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
1647				/*maxsegsz*/0x8000,
1648				/*flags*/BUS_DMA_ALLOCNOW,
1649				&sbp->dmat);
1650	if (error != 0) {
1651		printf("sbp_attach: Could not allocate DMA tag "
1652			"- error %d\n", error);
1653			return (ENOMEM);
1654	}
1655
1656	devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
1657	if (devq == NULL)
1658		return (ENXIO);
1659
1660	for( i = 0 ; i < SBP_NUM_TARGETS ; i++){
1661		sbp->targets[i].fwdev = NULL;
1662		sbp->targets[i].luns = NULL;
1663	}
1664
1665	sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp,
1666				 device_get_unit(dev),
1667				 /*untagged*/ SBP_QUEUE_LEN,
1668				 /*tagged*/0, devq);
1669
1670	if (sbp->sim == NULL) {
1671		cam_simq_free(devq);
1672		return (ENXIO);
1673	}
1674
1675	sbp->ocb = (struct sbp_ocb *) contigmalloc(
1676		sizeof (struct sbp_ocb) * SBP_NUM_OCB,
1677		M_SBP, M_NOWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
1678	bzero(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB);
1679
1680	if (sbp->ocb == NULL) {
1681		printf("sbp0: ocb alloction failure\n");
1682		return (ENOMEM);
1683	}
1684
1685	STAILQ_INIT(&sbp->free_ocbs);
1686	for (i = 0; i < SBP_NUM_OCB; i++) {
1687		sbp_free_ocb(sbp, &sbp->ocb[i]);
1688	}
1689
1690	if (xpt_bus_register(sbp->sim, /*bus*/0) != CAM_SUCCESS) {
1691		cam_sim_free(sbp->sim, /*free_devq*/TRUE);
1692		contigfree(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB,
1693									M_SBP);
1694		return (ENXIO);
1695	}
1696
1697	xfer = fw_xfer_alloc(M_SBP);
1698	xfer->act.hand = sbp_recv;
1699	xfer->act_type = FWACT_XFER;
1700#if NEED_RESPONSE
1701	xfer->fc = sbp->fd.fc;
1702#endif
1703	xfer->sc = (caddr_t)sbp;
1704
1705	sbp->fwb.start_hi = SBP_BIND_HI;
1706	sbp->fwb.start_lo = SBP_DEV2ADDR(device_get_unit(sbp->fd.dev), 0, 0);
1707	/* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */
1708	sbp->fwb.addrlen = 0xffff;
1709	sbp->fwb.xfer = xfer;
1710	fw_bindadd(sbp->fd.fc, &sbp->fwb);
1711
1712	sbp->fd.post_explore = sbp_post_explore;
1713
1714	if (sbp->fd.fc->status != -1) {
1715		s = splfw();
1716		sbp_post_explore((void *)sbp);
1717		splx(s);
1718	}
1719
1720	return (0);
1721}
1722
1723static int
1724sbp_logout_all(struct sbp_softc *sbp)
1725{
1726	struct sbp_target *target;
1727	struct sbp_dev *sdev;
1728	int i, j;
1729
1730SBP_DEBUG(0)
1731	printf("sbp_logout_all\n");
1732END_DEBUG
1733	for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) {
1734		target = &sbp->targets[i];
1735		if (target->luns == NULL)
1736			continue;
1737		for (j = 0; j < target->num_lun; j++) {
1738			sdev = &target->luns[j];
1739			if (sdev->status >= SBP_DEV_TOATTACH &&
1740					sdev->status <= SBP_DEV_ATTACHED)
1741				sbp_mgm_orb(sdev, ORB_FUN_LGO, 0, 0);
1742		}
1743	}
1744	return 0;
1745}
1746
1747static int
1748sbp_shutdown(device_t dev)
1749{
1750	struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
1751
1752	sbp_logout_all(sbp);
1753	return (0);
1754}
1755
1756static int
1757sbp_detach(device_t dev)
1758{
1759	struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
1760	struct firewire_comm *fc = sbp->fd.fc;
1761	int i;
1762
1763SBP_DEBUG(0)
1764	printf("sbp_detach\n");
1765END_DEBUG
1766#if 0
1767	/* bus reset for logout */
1768	sbp->fd.post_explore = NULL;
1769	fc->ibr(fc);
1770#endif
1771
1772	for (i = 0; i < SBP_NUM_TARGETS; i ++)
1773		sbp_cam_detach_target(&sbp->targets[i]);
1774	xpt_bus_deregister(cam_sim_path(sbp->sim));
1775
1776	sbp_logout_all(sbp);
1777	/* XXX wait for logout completion */
1778	tsleep(&i, FWPRI, "sbpdtc", hz/2);
1779
1780	fw_bindremove(fc, &sbp->fwb);
1781	contigfree(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB, M_SBP);
1782	bus_dma_tag_destroy(sbp->dmat);
1783
1784	for (i = 0; i < SBP_NUM_TARGETS; i ++)
1785		if (sbp->targets[i].luns != NULL)
1786			free(sbp->targets[i].luns, M_SBP);
1787
1788	return (0);
1789}
1790
1791static void
1792sbp_cam_detach_target(struct sbp_target *target)
1793{
1794	int i;
1795	struct sbp_dev *sdev;
1796
1797	if (target->luns != NULL) {
1798SBP_DEBUG(0)
1799		printf("sbp_detach_target %d\n", target->target_id);
1800END_DEBUG
1801		for (i = 0; i < target->num_lun; i++) {
1802			sdev = &target->luns[i];
1803			if (sdev->status == SBP_DEV_RESET ||
1804					sdev->status == SBP_DEV_DEAD)
1805				continue;
1806			if (sdev->path) {
1807				xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
1808				xpt_free_path(sdev->path);
1809				sdev->path = NULL;
1810			}
1811			sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
1812		}
1813	}
1814}
1815
1816static void
1817sbp_timeout(void *arg)
1818{
1819	struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
1820	struct sbp_dev *sdev = ocb->sdev;
1821
1822	sbp_show_sdev_info(sdev, 2);
1823	printf("request timeout ... ");
1824
1825	xpt_freeze_devq(sdev->path, 1);
1826	sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
1827	if (sdev->flags & SBP_DEV_TIMEOUT) {
1828#if 0
1829		struct firewire_comm *fc;
1830
1831		printf("bus reset\n");
1832		fc = sdev->target->sbp->fd.fc;
1833		fc->ibr(fc);
1834		sdev->status == SBP_DEV_RETRY;
1835#else
1836		printf("target reset\n");
1837		sbp_mgm_orb(sdev, ORB_FUN_RST, 0, 0);
1838#endif
1839		sdev->flags &= ~SBP_DEV_TIMEOUT;
1840	} else {
1841		printf("agent reset\n");
1842		sdev->flags |= SBP_DEV_TIMEOUT;
1843		sbp_agent_reset(sdev);
1844	}
1845	return;
1846}
1847
1848static void
1849sbp_action1(struct cam_sim *sim, union ccb *ccb)
1850{
1851
1852	struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
1853	struct sbp_target *target = NULL;
1854	struct sbp_dev *sdev = NULL;
1855
1856	/* target:lun -> sdev mapping */
1857	if (sbp != NULL
1858			&& ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
1859			&& ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
1860		target = &sbp->targets[ccb->ccb_h.target_id];
1861		if (target->fwdev != NULL
1862				&& ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
1863				&& ccb->ccb_h.target_lun < target->num_lun) {
1864			sdev = &target->luns[ccb->ccb_h.target_lun];
1865			if (sdev->status != SBP_DEV_ATTACHED &&
1866				sdev->status != SBP_DEV_PROBE)
1867				sdev = NULL;
1868		}
1869	}
1870
1871SBP_DEBUG(1)
1872	if (sdev == NULL)
1873		printf("invalid target %d lun %d\n",
1874			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
1875END_DEBUG
1876
1877	switch (ccb->ccb_h.func_code) {
1878	case XPT_SCSI_IO:
1879	case XPT_RESET_DEV:
1880	case XPT_GET_TRAN_SETTINGS:
1881	case XPT_SET_TRAN_SETTINGS:
1882	case XPT_CALC_GEOMETRY:
1883		if (sdev == NULL) {
1884SBP_DEBUG(1)
1885			printf("%s:%d:%d:func_code 0x%04x: "
1886				"Invalid target (target needed)\n",
1887				device_get_nameunit(sbp->fd.dev),
1888				ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1889				ccb->ccb_h.func_code);
1890END_DEBUG
1891
1892			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1893			xpt_done(ccb);
1894			return;
1895		}
1896		break;
1897	case XPT_PATH_INQ:
1898	case XPT_NOOP:
1899		/* The opcodes sometimes aimed at a target (sc is valid),
1900		 * sometimes aimed at the SIM (sc is invalid and target is
1901		 * CAM_TARGET_WILDCARD)
1902		 */
1903		if (sbp == NULL &&
1904			ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
1905SBP_DEBUG(0)
1906			printf("%s:%d:%d func_code 0x%04x: "
1907				"Invalid target (no wildcard)\n",
1908				device_get_nameunit(sbp->fd.dev),
1909				ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1910				ccb->ccb_h.func_code);
1911END_DEBUG
1912			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1913			xpt_done(ccb);
1914			return;
1915		}
1916		break;
1917	default:
1918		/* XXX Hm, we should check the input parameters */
1919		break;
1920	}
1921
1922	switch (ccb->ccb_h.func_code) {
1923	case XPT_SCSI_IO:
1924	{
1925		struct ccb_scsiio *csio;
1926		struct sbp_ocb *ocb;
1927		int s, speed;
1928		void *cdb;
1929
1930		csio = &ccb->csio;
1931
1932SBP_DEBUG(1)
1933		printf("%s:%d:%d XPT_SCSI_IO: "
1934			"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1935			", flags: 0x%02x, "
1936			"%db cmd/%db data/%db sense\n",
1937			device_get_nameunit(sbp->fd.dev),
1938			ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1939			csio->cdb_io.cdb_bytes[0],
1940			csio->cdb_io.cdb_bytes[1],
1941			csio->cdb_io.cdb_bytes[2],
1942			csio->cdb_io.cdb_bytes[3],
1943			csio->cdb_io.cdb_bytes[4],
1944			csio->cdb_io.cdb_bytes[5],
1945			csio->cdb_io.cdb_bytes[6],
1946			csio->cdb_io.cdb_bytes[7],
1947			csio->cdb_io.cdb_bytes[8],
1948			csio->cdb_io.cdb_bytes[9],
1949			ccb->ccb_h.flags & CAM_DIR_MASK,
1950			csio->cdb_len, csio->dxfer_len,
1951			csio->sense_len);
1952END_DEBUG
1953		if(sdev == NULL){
1954			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1955			xpt_done(ccb);
1956			return;
1957		}
1958#if 0
1959		/* if we are in probe stage, pass only probe commands */
1960		if (sdev->status == SBP_DEV_PROBE) {
1961			char *name;
1962			name = xpt_path_periph(ccb->ccb_h.path)->periph_name;
1963			printf("probe stage, periph name: %s\n", name);
1964			if (strcmp(name, "probe") != 0) {
1965				ccb->ccb_h.status = CAM_REQUEUE_REQ;
1966				xpt_done(ccb);
1967				return;
1968			}
1969		}
1970#endif
1971		if ((ocb = sbp_get_ocb(sbp)) == NULL) {
1972			s = splfw();
1973			sbp->flags |= SBP_RESOURCE_SHORTAGE;
1974			splx(s);
1975			return;
1976		}
1977		ocb->flags = OCB_ACT_CMD;
1978		ocb->sdev = sdev;
1979		ocb->ccb = ccb;
1980		ccb->ccb_h.ccb_sdev_ptr = sdev;
1981		ocb->orb[0] = htonl(1 << 31);
1982		ocb->orb[1] = 0;
1983		ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
1984		ocb->orb[3] = htonl(vtophys(ocb->ind_ptr));
1985		speed = min(target->fwdev->speed, max_speed);
1986		ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
1987						| ORB_CMD_MAXP(speed + 7));
1988		if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){
1989			ocb->orb[4] |= htonl(ORB_CMD_IN);
1990		}
1991
1992		if (csio->ccb_h.flags & CAM_SCATTER_VALID)
1993			printf("sbp: CAM_SCATTER_VALID\n");
1994		if (csio->ccb_h.flags & CAM_DATA_PHYS)
1995			printf("sbp: CAM_DATA_PHYS\n");
1996
1997		if (csio->ccb_h.flags & CAM_CDB_POINTER)
1998			cdb = (void *)csio->cdb_io.cdb_ptr;
1999		else
2000			cdb = (void *)&csio->cdb_io.cdb_bytes;
2001		bcopy(cdb,
2002			(void *)(uintptr_t)(volatile void *)&ocb->orb[5],
2003				csio->cdb_len);
2004/*
2005printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
2006printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
2007*/
2008		if (ccb->csio.dxfer_len > 0) {
2009			int s;
2010
2011			if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
2012				printf("sbp_action1: cannot create dmamap\n");
2013				break;
2014			}
2015
2016			s = splsoftvm();
2017			bus_dmamap_load(/*dma tag*/sbp->dmat,
2018					/*dma map*/ocb->dmamap,
2019					ccb->csio.data_ptr,
2020					ccb->csio.dxfer_len,
2021					sbp_execute_ocb,
2022					ocb,
2023					/*flags*/0);
2024			splx(s);
2025		} else
2026			sbp_execute_ocb(ocb, NULL, 0, 0);
2027		break;
2028	}
2029	case XPT_CALC_GEOMETRY:
2030	{
2031		struct ccb_calc_geometry *ccg;
2032		u_int32_t size_mb;
2033		u_int32_t secs_per_cylinder;
2034		int extended = 1;
2035		ccg = &ccb->ccg;
2036
2037		if (ccg->block_size == 0) {
2038			printf("sbp_action1: block_size is 0.\n");
2039			ccb->ccb_h.status = CAM_REQ_INVALID;
2040			xpt_done(ccb);
2041			break;
2042		}
2043SBP_DEBUG(1)
2044		printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: "
2045			"Volume size = %d\n",
2046			device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim),
2047			ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
2048			ccg->volume_size);
2049END_DEBUG
2050
2051		size_mb = ccg->volume_size
2052			/ ((1024L * 1024L) / ccg->block_size);
2053
2054		if (size_mb >= 1024 && extended) {
2055			ccg->heads = 255;
2056			ccg->secs_per_track = 63;
2057		} else {
2058			ccg->heads = 64;
2059			ccg->secs_per_track = 32;
2060		}
2061		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2062		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2063		ccb->ccb_h.status = CAM_REQ_CMP;
2064		xpt_done(ccb);
2065		break;
2066	}
2067	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
2068	{
2069
2070SBP_DEBUG(1)
2071		printf("%s:%d:XPT_RESET_BUS: \n",
2072			device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
2073END_DEBUG
2074
2075		ccb->ccb_h.status = CAM_REQ_INVALID;
2076		xpt_done(ccb);
2077		break;
2078	}
2079	case XPT_PATH_INQ:		/* Path routing inquiry */
2080	{
2081		struct ccb_pathinq *cpi = &ccb->cpi;
2082
2083SBP_DEBUG(1)
2084		printf("%s:%d:%d XPT_PATH_INQ:.\n",
2085			device_get_nameunit(sbp->fd.dev),
2086			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2087END_DEBUG
2088		cpi->version_num = 1; /* XXX??? */
2089		cpi->hba_inquiry = 0;
2090		cpi->target_sprt = 0;
2091		cpi->hba_misc = PIM_NOBUSRESET;
2092		cpi->hba_eng_cnt = 0;
2093		cpi->max_target = SBP_NUM_TARGETS - 1;
2094		cpi->max_lun = SBP_NUM_LUNS - 1;
2095		cpi->initiator_id = SBP_INITIATOR;
2096		cpi->bus_id = sim->bus_id;
2097		cpi->base_transfer_speed = 400 * 1000 / 8;
2098		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2099		strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
2100		strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
2101		cpi->unit_number = sim->unit_number;
2102
2103		cpi->ccb_h.status = CAM_REQ_CMP;
2104		xpt_done(ccb);
2105		break;
2106	}
2107	case XPT_GET_TRAN_SETTINGS:
2108	{
2109		struct ccb_trans_settings *cts = &ccb->cts;
2110SBP_DEBUG(1)
2111		printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
2112			device_get_nameunit(sbp->fd.dev),
2113			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2114END_DEBUG
2115		/* Disable disconnect and tagged queuing */
2116		cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
2117		cts->flags = 0;
2118
2119		cts->ccb_h.status = CAM_REQ_CMP;
2120		xpt_done(ccb);
2121		break;
2122	}
2123	case XPT_ABORT:
2124		ccb->ccb_h.status = CAM_UA_ABORT;
2125		xpt_done(ccb);
2126		break;
2127	default:
2128		ccb->ccb_h.status = CAM_REQ_INVALID;
2129		xpt_done(ccb);
2130		break;
2131	}
2132	return;
2133}
2134
2135static void
2136sbp_action(struct cam_sim *sim, union ccb *ccb)
2137{
2138	int s;
2139
2140	s = splfw();
2141	sbp_action1(sim, ccb);
2142	splx(s);
2143}
2144
2145static void
2146sbp_execute_ocb(void *arg,  bus_dma_segment_t *segments, int seg, int error)
2147{
2148	int i;
2149	struct sbp_ocb *ocb;
2150	struct sbp_ocb *prev;
2151	union ccb *ccb;
2152	bus_dma_segment_t *s;
2153
2154	if (error)
2155		printf("sbp_execute_ocb: error=%d\n", error);
2156
2157	ocb = (struct sbp_ocb *)arg;
2158	if (seg == 1) {
2159		/* direct pointer */
2160		ocb->orb[3] = htonl(segments[0].ds_addr);
2161		ocb->orb[4] |= htonl(segments[0].ds_len);
2162	} else if(seg > 1) {
2163		/* page table */
2164SBP_DEBUG(1)
2165		printf("sbp_execute_ocb: seg %d", seg);
2166		for (i = 0; i < seg; i++)
2167#if __FreeBSD_version >= 500000
2168			printf(", %tx:%zd", segments[i].ds_addr,
2169#else
2170			printf(", %x:%d", segments[i].ds_addr,
2171#endif
2172						segments[i].ds_len);
2173		printf("\n");
2174END_DEBUG
2175		for (i = 0; i < seg; i++) {
2176			s = &segments[i];
2177SBP_DEBUG(0)
2178			/* XXX LSI Logic "< 16 byte" bug might be hit */
2179			if (s->ds_len < 16)
2180				printf("sbp_execute_ocb: warning, "
2181#if __FreeBSD_version >= 500000
2182					"segment length(%zd) is less than 16."
2183#else
2184					"segment length(%d) is less than 16."
2185#endif
2186					"(seg=%d/%d)\n", s->ds_len, i+1, seg);
2187END_DEBUG
2188			ocb->ind_ptr[i].hi = htonl(s->ds_len << 16);
2189			ocb->ind_ptr[i].lo = htonl(s->ds_addr);
2190		}
2191		ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
2192	}
2193
2194	ccb = ocb->ccb;
2195	prev = sbp_enqueue_ocb(ocb->sdev, ocb);
2196	if (prev)
2197		sbp_doorbell(ocb->sdev);
2198	else
2199		sbp_orb_pointer(ocb->sdev, ocb);
2200}
2201
2202static void
2203sbp_poll(struct cam_sim *sim)
2204{
2205	/* should call fwohci_intr? */
2206	return;
2207}
2208static struct sbp_ocb *
2209sbp_dequeue_ocb(struct sbp_dev *sdev, u_int32_t orb_lo)
2210{
2211	struct sbp_ocb *ocb;
2212	struct sbp_ocb *next;
2213	int s = splfw(), order = 0;
2214	int flags;
2215
2216	for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) {
2217		next = STAILQ_NEXT(ocb, ocb);
2218		flags = ocb->flags;
2219SBP_DEBUG(1)
2220		sbp_show_sdev_info(sdev, 2);
2221#if __FreeBSD_version >= 500000
2222		printf("orb: 0x%tx next: 0x%x, flags %x\n",
2223#else
2224		printf("orb: 0x%x next: 0x%lx, flags %x\n",
2225#endif
2226			vtophys(&ocb->orb[0]), ntohl(ocb->orb[1]), flags);
2227END_DEBUG
2228		if (vtophys(&ocb->orb[0]) == orb_lo) {
2229			/* found */
2230			if (ocb->flags & OCB_RESERVED)
2231				ocb->flags |= OCB_DONE;
2232			else
2233				STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2234			if (ocb->ccb != NULL)
2235				untimeout(sbp_timeout, (caddr_t)ocb,
2236						ocb->ccb->ccb_h.timeout_ch);
2237			if (ocb->dmamap != NULL) {
2238				bus_dmamap_destroy(sdev->target->sbp->dmat,
2239							ocb->dmamap);
2240				ocb->dmamap = NULL;
2241			}
2242			break;
2243		} else {
2244			if ((ocb->flags & OCB_RESERVED) &&
2245					(ocb->flags & OCB_DONE)) {
2246				/* next orb must be fetched already */
2247				STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2248				sbp_free_ocb(sdev->target->sbp, ocb);
2249			} else
2250				order ++;
2251		}
2252	}
2253	splx(s);
2254SBP_DEBUG(0)
2255	if (ocb && order > 0) {
2256		sbp_show_sdev_info(sdev, 2);
2257		printf("unordered execution order:%d\n", order);
2258	}
2259END_DEBUG
2260	return (ocb);
2261}
2262
2263static struct sbp_ocb *
2264sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2265{
2266	int s = splfw();
2267	struct sbp_ocb *prev;
2268
2269SBP_DEBUG(2)
2270	sbp_show_sdev_info(sdev, 2);
2271#if __FreeBSD_version >= 500000
2272	printf("sbp_enqueue_ocb orb=0x%tx in physical memory\n", vtophys(&ocb->orb[0]));
2273#else
2274	printf("sbp_enqueue_ocb orb=0x%x in physical memory\n", vtophys(&ocb->orb[0]));
2275#endif
2276END_DEBUG
2277	prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
2278	STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
2279
2280	if (ocb->ccb != NULL)
2281		ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb,
2282					(ocb->ccb->ccb_h.timeout * hz) / 1000);
2283
2284	if (prev != NULL ) {
2285SBP_DEBUG(1)
2286#if __FreeBSD_version >= 500000
2287	printf("linking chain 0x%tx -> 0x%tx\n", vtophys(&prev->orb[0]),
2288#else
2289	printf("linking chain 0x%x -> 0x%x\n", vtophys(&prev->orb[0]),
2290#endif
2291			vtophys(&ocb->orb[0]));
2292END_DEBUG
2293		prev->flags |= OCB_RESERVED;
2294		prev->orb[1] = htonl(vtophys(&ocb->orb[0]));
2295		prev->orb[0] = 0;
2296	}
2297	splx(s);
2298
2299	return prev;
2300}
2301
2302static struct sbp_ocb *
2303sbp_get_ocb(struct sbp_softc *sbp)
2304{
2305	struct sbp_ocb *ocb;
2306	int s = splfw();
2307	ocb = STAILQ_FIRST(&sbp->free_ocbs);
2308	if (ocb == NULL) {
2309		printf("ocb shortage!!!\n");
2310		return NULL;
2311	}
2312	STAILQ_REMOVE(&sbp->free_ocbs, ocb, sbp_ocb, ocb);
2313	splx(s);
2314	ocb->ccb = NULL;
2315	return (ocb);
2316}
2317
2318static void
2319sbp_free_ocb(struct sbp_softc *sbp, struct sbp_ocb *ocb)
2320{
2321#if 0 /* XXX make sure that ocb has ccb */
2322	if ((sbp->flags & SBP_RESOURCE_SHORTAGE) != 0 &&
2323	    (ocb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
2324		ocb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
2325		sbp->flags &= ~SBP_RESOURCE_SHORTAGE;
2326	}
2327#else
2328	if ((sbp->flags & SBP_RESOURCE_SHORTAGE) != 0)
2329		sbp->flags &= ~SBP_RESOURCE_SHORTAGE;
2330#endif
2331	ocb->flags = 0;
2332	ocb->ccb = NULL;
2333	STAILQ_INSERT_TAIL(&sbp->free_ocbs, ocb, ocb);
2334}
2335
2336static void
2337sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2338{
2339	struct sbp_dev *sdev;
2340
2341	sdev = ocb->sdev;
2342SBP_DEBUG(1)
2343	sbp_show_sdev_info(sdev, 2);
2344	printf("sbp_abort_ocb 0x%x\n", status);
2345	if (ocb->ccb != NULL)
2346		sbp_print_scsi_cmd(ocb);
2347END_DEBUG
2348	if (ocb->ccb != NULL && !(ocb->flags & OCB_DONE)) {
2349		untimeout(sbp_timeout, (caddr_t)ocb,
2350					ocb->ccb->ccb_h.timeout_ch);
2351		ocb->ccb->ccb_h.status = status;
2352		xpt_done(ocb->ccb);
2353	}
2354	if (ocb->dmamap != NULL) {
2355		bus_dmamap_destroy(sdev->target->sbp->dmat, ocb->dmamap);
2356		ocb->dmamap = NULL;
2357	}
2358	sbp_free_ocb(sdev->target->sbp, ocb);
2359}
2360
2361static void
2362sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
2363{
2364	int s;
2365	struct sbp_ocb *ocb, *next;
2366	STAILQ_HEAD(, sbp_ocb) temp;
2367
2368	s = splfw();
2369
2370	bcopy(&sdev->ocbs, &temp, sizeof(temp));
2371	STAILQ_INIT(&sdev->ocbs);
2372	for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) {
2373		next = STAILQ_NEXT(ocb, ocb);
2374		sbp_abort_ocb(ocb, status);
2375	}
2376
2377	splx(s);
2378}
2379
2380static devclass_t sbp_devclass;
2381
2382static device_method_t sbp_methods[] = {
2383	/* device interface */
2384	DEVMETHOD(device_identify,	sbp_identify),
2385	DEVMETHOD(device_probe,		sbp_probe),
2386	DEVMETHOD(device_attach,	sbp_attach),
2387	DEVMETHOD(device_detach,	sbp_detach),
2388	DEVMETHOD(device_shutdown,	sbp_shutdown),
2389
2390	{ 0, 0 }
2391};
2392
2393static driver_t sbp_driver = {
2394	"sbp",
2395	sbp_methods,
2396	sizeof(struct sbp_softc),
2397};
2398DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
2399MODULE_VERSION(sbp, 1);
2400MODULE_DEPEND(sbp, firewire, 1, 1, 1);
2401MODULE_DEPEND(sbp, cam, 1, 1, 1);
2402