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