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