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