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