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