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