sbp.c revision 106506
1139825Simp/*
2103620Sgrehan * Copyright (c) 1998,1999,2000,2001 Katsushi Kobayashi and Hidetosh Shimokawa
3103620Sgrehan * All rights reserved.
4103620Sgrehan *
5103620Sgrehan * Redistribution and use in source and binary forms, with or without
6103620Sgrehan * modification, are permitted provided that the following conditions
7103620Sgrehan * are met:
8103620Sgrehan * 1. Redistributions of source code must retain the above copyright
9103620Sgrehan *    notice, this list of conditions and the following disclaimer.
10103620Sgrehan * 2. Redistributions in binary form must reproduce the above copyright
11103620Sgrehan *    notice, this list of conditions and the following disclaimer in the
12103620Sgrehan *    documentation and/or other materials provided with the distribution.
13103620Sgrehan * 3. All advertising materials mentioning features or use of this software
14103620Sgrehan *    must display the acknowledgement as bellow:
15103620Sgrehan *
16103620Sgrehan *    This product includes software developed by K. Kobayashi and H. Shimokawa
17103620Sgrehan *
18103620Sgrehan * 4. The name of the author may not be used to endorse or promote products
19103620Sgrehan *    derived from this software without specific prior written permission.
20103620Sgrehan *
21103620Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22103620Sgrehan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23103620Sgrehan * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24103620Sgrehan * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25103620Sgrehan * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26103620Sgrehan * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27103620Sgrehan * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28103620Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29103620Sgrehan * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30103620Sgrehan * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31103620Sgrehan * POSSIBILITY OF SUCH DAMAGE.
32103620Sgrehan *
33103620Sgrehan * $FreeBSD: head/sys/dev/firewire/sbp.c 106506 2002-11-06 15:34:52Z simokawa $
34103620Sgrehan *
35103620Sgrehan */
36103620Sgrehan
37103620Sgrehan#include <sys/param.h>
38103620Sgrehan#include <sys/systm.h>
39103620Sgrehan#include <sys/module.h>
40103620Sgrehan#include <sys/bus.h>
41103620Sgrehan#include <sys/mbuf.h>
42103620Sgrehan#include <sys/sysctl.h>
43103620Sgrehan#include <machine/bus.h>
44103620Sgrehan#include <sys/malloc.h>
45103620Sgrehan#include <sys/devicestat.h>	/* for struct devstat */
46103620Sgrehan
47103620Sgrehan
48103620Sgrehan#include <cam/cam.h>
49103620Sgrehan#include <cam/cam_ccb.h>
50103620Sgrehan#include <cam/cam_sim.h>
51103620Sgrehan#include <cam/cam_xpt_sim.h>
52103620Sgrehan#include <cam/cam_debug.h>
53103620Sgrehan#include <cam/cam_periph.h>
54103620Sgrehan
55103620Sgrehan#include <cam/scsi/scsi_all.h>
56103620Sgrehan#include <cam/scsi/scsi_message.h>
57103620Sgrehan#include <cam/scsi/scsi_da.h>
58103620Sgrehan
59103620Sgrehan#include <sys/kernel.h>
60103620Sgrehan
61103620Sgrehan#include <vm/vm.h>
62103620Sgrehan#include <vm/pmap.h>
63103620Sgrehan
64103620Sgrehan#include <dev/firewire/firewire.h>
65103620Sgrehan#include <dev/firewire/firewirereg.h>
66103620Sgrehan#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_print_scsi_cmd(struct sbp_ocb *ocb)
1105{
1106	struct ccb_scsiio *csio;
1107
1108	csio = &ocb->ccb->csio;
1109	printf("%s:%d:%d XPT_SCSI_IO: "
1110		"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1111		", flags: 0x%02x, "
1112		"%db cmd/%db data/%db sense\n",
1113		device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
1114		ocb->ccb->ccb_h.target_id, ocb->ccb->ccb_h.target_lun,
1115		csio->cdb_io.cdb_bytes[0],
1116		csio->cdb_io.cdb_bytes[1],
1117		csio->cdb_io.cdb_bytes[2],
1118		csio->cdb_io.cdb_bytes[3],
1119		csio->cdb_io.cdb_bytes[4],
1120		csio->cdb_io.cdb_bytes[5],
1121		csio->cdb_io.cdb_bytes[6],
1122		csio->cdb_io.cdb_bytes[7],
1123		csio->cdb_io.cdb_bytes[8],
1124		csio->cdb_io.cdb_bytes[9],
1125		ocb->ccb->ccb_h.flags & CAM_DIR_MASK,
1126		csio->cdb_len, csio->dxfer_len,
1127		csio->sense_len);
1128}
1129
1130static void
1131sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
1132{
1133	struct sbp_cmd_status *sbp_cmd_status;
1134	struct scsi_sense_data *sense;
1135
1136	sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
1137	sense = &ocb->ccb->csio.sense_data;
1138
1139SBP_DEBUG(0)
1140	sbp_print_scsi_cmd(ocb);
1141	/* XXX need decode status */
1142	sbp_show_sdev_info(ocb->sdev, 2);
1143	printf("SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d",
1144		sbp_cmd_status->status,
1145		sbp_cmd_status->sfmt,
1146		sbp_cmd_status->valid,
1147		sbp_cmd_status->s_key,
1148		sbp_cmd_status->s_code,
1149		sbp_cmd_status->s_qlfr,
1150		sbp_status->len
1151	);
1152#if 0	 /* XXX */
1153	if (sbp_cmd_status->status == SCSI_STATUS_CHECK_COND) {
1154		printf(" %s\n", scsi_sense_key_text[sbp_cmd_status->s_key]);
1155			scsi_sense_desc(
1156				sbp_cmd_status->s_code,
1157				sbp_cmd_status->s_qlfr,
1158				ocb->ccb->ccb_h.path->device->inq_data
1159			)
1160	} else {
1161		printf("\n");
1162	}
1163#else
1164	printf("\n");
1165#endif
1166END_DEBUG
1167
1168
1169	if(sbp_cmd_status->status == SCSI_STATUS_CHECK_COND ||
1170			sbp_cmd_status->status == SCSI_STATUS_CMD_TERMINATED){
1171		if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
1172			sense->error_code = SSD_CURRENT_ERROR;
1173		}else{
1174			sense->error_code = SSD_DEFERRED_ERROR;
1175		}
1176		if(sbp_cmd_status->valid)
1177			sense->error_code |= SSD_ERRCODE_VALID;
1178		sense->flags = sbp_cmd_status->s_key;
1179		if(sbp_cmd_status->mark)
1180			sense->flags |= SSD_FILEMARK;
1181		if(sbp_cmd_status->eom)
1182			sense->flags |= SSD_EOM;
1183		if(sbp_cmd_status->ill_len)
1184			sense->flags |= SSD_ILI;
1185		sense->info[0] = ntohl(sbp_cmd_status->info) & 0xff;
1186		sense->info[1] =(ntohl(sbp_cmd_status->info) >> 8) & 0xff;
1187		sense->info[2] =(ntohl(sbp_cmd_status->info) >> 16) & 0xff;
1188		sense->info[3] =(ntohl(sbp_cmd_status->info) >> 24) & 0xff;
1189		if (sbp_status->len <= 1)
1190			/* XXX not scsi status. shouldn't be happened */
1191			sense->extra_len = 0;
1192		else if (sbp_status->len <= 4)
1193			/* add_sense_code(_qual), info, cmd_spec_info */
1194			sense->extra_len = 6;
1195		else
1196			/* fru, sense_key_spec */
1197			sense->extra_len = 10;
1198		sense->cmd_spec_info[0] = ntohl(sbp_cmd_status->cdb) & 0xff;
1199		sense->cmd_spec_info[1] = (ntohl(sbp_cmd_status->cdb) >> 8) & 0xff;
1200		sense->cmd_spec_info[2] = (ntohl(sbp_cmd_status->cdb) >> 16) & 0xff;
1201		sense->cmd_spec_info[3] = (ntohl(sbp_cmd_status->cdb) >> 24) & 0xff;
1202		sense->add_sense_code = sbp_cmd_status->s_code;
1203		sense->add_sense_code_qual = sbp_cmd_status->s_qlfr;
1204		sense->fru = sbp_cmd_status->fru;
1205		sense->sense_key_spec[0] = ntohl(sbp_cmd_status->s_keydep) & 0xff;
1206		sense->sense_key_spec[1] = (ntohl(sbp_cmd_status->s_keydep) >>8) & 0xff;
1207		sense->sense_key_spec[2] = (ntohl(sbp_cmd_status->s_keydep) >>16) & 0xff;
1208
1209		ocb->ccb->csio.scsi_status = sbp_cmd_status->status;;
1210		ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
1211							| CAM_AUTOSNS_VALID;
1212/*
1213{
1214		u_int8_t j, *tmp;
1215		tmp = sense;
1216		for( j = 0 ; j < 32 ; j+=8){
1217			printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
1218				tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
1219				tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
1220		}
1221
1222}
1223*/
1224	} else {
1225		printf("sbp_scsi_status: unknown scsi status\n");
1226	}
1227}
1228
1229static void
1230sbp_fix_inq_data(struct sbp_ocb *ocb)
1231{
1232	union ccb *ccb;
1233	struct sbp_dev *sdev;
1234	struct scsi_inquiry_data *inq;
1235
1236	ccb = ocb->ccb;
1237	sdev = ocb->sdev;
1238
1239	if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD)
1240		return;
1241SBP_DEBUG(1)
1242	sbp_show_sdev_info(sdev, 2);
1243	printf("sbp_fix_inq_data\n");
1244END_DEBUG
1245	inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr;
1246	switch (SID_TYPE(inq)) {
1247	case T_DIRECT:
1248		/*
1249		 * XXX Convert Direct Access device to RBC.
1250		 * I've never seen Firewire DA devices which support READ_6.
1251		 */
1252#if 1
1253		if (SID_TYPE(inq) == T_DIRECT)
1254			inq->device |= T_RBC; /*  T_DIRECT == 0 */
1255#endif
1256		/* fall through */
1257	case T_RBC:
1258		/* disable tag queuing */
1259		inq->flags &= ~SID_CmdQue;
1260		/*
1261		 * Override vendor/product/revision information.
1262		 * Some devices sometimes return strange strings.
1263		 */
1264		bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor));
1265		bcopy(sdev->product, inq->product, sizeof(inq->product));
1266		bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision));
1267		break;
1268	}
1269}
1270
1271static void
1272sbp_recv1(struct fw_xfer *xfer){
1273	struct fw_pkt *rfp;
1274#if NEED_RESPONSE
1275	struct fw_pkt *sfp;
1276#endif
1277	struct sbp_softc *sbp;
1278	struct sbp_dev *sdev;
1279	struct sbp_ocb *ocb;
1280	struct sbp_login_res *login_res = NULL;
1281	struct sbp_status *sbp_status;
1282	struct sbp_target *target;
1283	int	orb_fun, status_valid;
1284	u_int32_t addr;
1285/*
1286	u_int32_t *ld;
1287	ld = xfer->recv.buf;
1288printf("sbp %x %d %d %08x %08x %08x %08x\n",
1289			xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1290printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1291printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1292*/
1293	if(xfer->resp != 0){
1294		printf("sbp_recv: xfer->resp != 0\n");
1295		fw_xfer_free( xfer);
1296		return;
1297	}
1298	if(xfer->recv.buf == NULL){
1299		printf("sbp_recv: xfer->recv.buf == NULL\n");
1300		fw_xfer_free( xfer);
1301		return;
1302	}
1303	sbp = (struct sbp_softc *)xfer->sc;
1304	rfp = (struct fw_pkt *)xfer->recv.buf;
1305	if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
1306		printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
1307		fw_xfer_free( xfer);
1308		return;
1309	}
1310	sbp_status = (struct sbp_status *)rfp->mode.wreqb.payload;
1311	addr = ntohl(rfp->mode.wreqb.dest_lo);
1312SBP_DEBUG(2)
1313	printf("received address 0x%x\n", addr);
1314END_DEBUG
1315	target = &sbp->targets[SBP_ADDR2TRG(addr)];
1316	sdev = &target->luns[SBP_ADDR2LUN(addr)];
1317
1318	status_valid = (sbp_status->resp == ORB_RES_CMPL
1319			&& sbp_status->dead == 0
1320			&& sbp_status->status == 0);
1321
1322SBP_DEBUG(0)
1323	if (!status_valid || debug > 1){
1324		int status;
1325
1326		sbp_show_sdev_info(sdev, 2);
1327		printf("ORB status src:%x resp:%x dead:%x"
1328				" len:%x stat:%x orb:%x%08x\n",
1329			sbp_status->src, sbp_status->resp, sbp_status->dead,
1330			sbp_status->len, sbp_status->status,
1331			ntohl(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
1332		sbp_show_sdev_info(sdev, 2);
1333		status = sbp_status->status;
1334		switch(sbp_status->resp) {
1335		case 0:
1336			if (status > MAX_ORB_STATUS0)
1337				printf("%s\n", orb_status0[MAX_ORB_STATUS0]);
1338			else
1339				printf("%s\n", orb_status0[status]);
1340			break;
1341		case 1:
1342			printf("Object: %s, Serial Bus Error: %s\n",
1343				orb_status1_object[(status>>6) & 3],
1344				orb_status1_serial_bus_error[status & 0xf]);
1345			break;
1346		default:
1347			printf("unknown respose code\n");
1348		}
1349	}
1350END_DEBUG
1351	ocb = sbp_dequeue_ocb(sdev, ntohl(sbp_status->orb_lo));
1352
1353	/* we have to reset the fetch agent if it's dead */
1354	if (sbp_status->dead) {
1355		if (sdev->path)
1356			xpt_freeze_devq(sdev->path, 1);
1357		sbp_agent_reset(sdev, 0);
1358	}
1359
1360
1361	if (ocb == NULL) {
1362		printf("No ocb on the queue for target %d.\n", sdev->target->target_id);
1363		fw_xfer_free( xfer);
1364		return;
1365	}
1366
1367	switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
1368	case ORB_FMT_NOP:
1369		break;
1370	case ORB_FMT_VED:
1371		break;
1372	case ORB_FMT_STD:
1373		switch(ocb->flags & OCB_ACT_MASK){
1374		case OCB_ACT_MGM:
1375			orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK;
1376			switch(orb_fun) {
1377			case ORB_FUN_LGI:
1378				login_res = &sdev->login;
1379				login_res->len = ntohs(login_res->len);
1380				login_res->id = ntohs(login_res->id);
1381				login_res->cmd_hi = ntohs(login_res->cmd_hi);
1382				login_res->cmd_lo = ntohl(login_res->cmd_lo);
1383				if (status_valid) {
1384SBP_DEBUG(0)
1385sbp_show_sdev_info(sdev, 2);
1386printf("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));
1387END_DEBUG
1388#if 1
1389					sbp_busy_timeout(sdev);
1390#else
1391					sbp_mgm_orb(sdev, ORB_FUN_ATS);
1392#endif
1393				} else {
1394					/* forgot logout ? */
1395					printf("login failed\n");
1396					sdev->status = SBP_DEV_RESET;
1397				}
1398				break;
1399			case ORB_FUN_RCN:
1400				login_res = &sdev->login;
1401				if (status_valid) {
1402					sdev->status = SBP_DEV_ATTACHED;
1403SBP_DEBUG(0)
1404sbp_show_sdev_info(sdev, 2);
1405printf("reconnect: len %d, ID %d, cmd %08x%08x\n", login_res->len, login_res->id, login_res->cmd_hi, login_res->cmd_lo);
1406END_DEBUG
1407#if 1
1408					sbp_ping_unit(sdev);
1409					xpt_release_devq(sdev->path, 1, TRUE);
1410#else
1411					sbp_mgm_orb(sdev, ORB_FUN_ATS);
1412#endif
1413				} else {
1414					/* reconnection hold time exceed? */
1415					printf("reconnect failed\n");
1416					sbp_mgm_orb(sdev, ORB_FUN_LGI);
1417				}
1418				break;
1419			case ORB_FUN_LGO:
1420				sdev->status = SBP_DEV_RESET;
1421				break;
1422			case ORB_FUN_LUR:
1423			case ORB_FUN_RST:
1424			case ORB_FUN_ATA:
1425			case ORB_FUN_ATS:
1426				if (sdev->status == SBP_DEV_ATTACHED) {
1427					xpt_release_devq(sdev->path, 1, TRUE);
1428				} else {
1429					sbp_busy_timeout(sdev);
1430				}
1431				break;
1432			default:
1433				break;
1434			}
1435			break;
1436		case OCB_ACT_CMD:
1437			if(ocb->ccb != NULL){
1438				union ccb *ccb;
1439/*
1440				u_int32_t *ld;
1441				ld = ocb->ccb->csio.data_ptr;
1442				if(ld != NULL && ocb->ccb->csio.dxfer_len != 0)
1443					printf("ptr %08x %08x %08x %08x\n", ld[0], ld[1], ld[2], ld[3]);
1444				else
1445					printf("ptr NULL\n");
1446printf("len %d\n", sbp_status->len);
1447*/
1448				ccb = ocb->ccb;
1449				if(sbp_status->len > 1){
1450					sbp_scsi_status(sbp_status, ocb);
1451				}else{
1452					if(sbp_status->resp != ORB_RES_CMPL){
1453						ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1454					}else{
1455						ccb->ccb_h.status = CAM_REQ_CMP;
1456					}
1457				}
1458				/* fix up inq data */
1459				if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1460					sbp_fix_inq_data(ocb);
1461				xpt_done(ccb);
1462			}
1463			break;
1464		default:
1465			break;
1466		}
1467	}
1468
1469	if (!(ocb->flags & OCB_RESERVED))
1470		sbp_free_ocb(sbp, ocb);
1471
1472/* The received packet is usually small enough to be stored within
1473 * the buffer. In that case, the controller return ack_complete and
1474 * no respose is necessary.
1475 *
1476 * XXX fwohci.c and firewire.c should inform event_code such as
1477 * ack_complete or ack_pending to upper driver.
1478 */
1479#if NEED_RESPONSE
1480	xfer->send.buf = malloc(12, M_SBP, M_NOWAIT | M_ZERO);
1481	xfer->send.len = 12;
1482	xfer->send.off = 0;
1483	sfp = (struct fw_pkt *)xfer->send.buf;
1484	sfp->mode.wres.dst = rfp->mode.wreqb.src;
1485	xfer->dst = ntohs(sfp->mode.wres.dst);
1486	xfer->spd = min(sdev->target->fwdev->speed, max_speed);
1487	xfer->act.hand = sbp_loginres_callback;
1488	xfer->retry_req = fw_asybusy;
1489
1490	sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1491	sfp->mode.wres.tcode = FWTCODE_WRES;
1492	sfp->mode.wres.rtcode = 0;
1493	sfp->mode.wres.pri = 0;
1494
1495	fw_asyreq(xfer->fc, -1, xfer);
1496#else
1497	fw_xfer_free(xfer);
1498#endif
1499
1500	return;
1501
1502}
1503
1504static void
1505sbp_recv(struct fw_xfer *xfer)
1506{
1507	int s;
1508
1509	s = splcam();
1510	sbp_recv1(xfer);
1511	splx(s);
1512}
1513/*
1514 * sbp_attach()
1515 */
1516static int
1517sbp_attach(device_t dev)
1518{
1519	struct sbp_softc *sbp;
1520	struct cam_devq *devq;
1521	struct fw_xfer *xfer;
1522	int i, s, error;
1523
1524SBP_DEBUG(0)
1525	printf("sbp_attach\n");
1526END_DEBUG
1527
1528	sbp = ((struct sbp_softc *)device_get_softc(dev));
1529	bzero(sbp, sizeof(struct sbp_softc));
1530	sbp->fd.dev = dev;
1531	sbp->fd.fc = device_get_ivars(dev);
1532	error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
1533				/*boundary*/0,
1534				/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1535				/*highaddr*/BUS_SPACE_MAXADDR,
1536				/*filter*/NULL, /*filterarg*/NULL,
1537				/*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
1538				/*maxsegsz*/0x8000,
1539				/*flags*/BUS_DMA_ALLOCNOW,
1540				&sbp->dmat);
1541	if (error != 0) {
1542		printf("sbp_attach: Could not allocate DMA tag "
1543			"- error %d\n", error);
1544			return (ENOMEM);
1545	}
1546
1547	devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
1548	if (devq == NULL)
1549		return (ENXIO);
1550
1551	for( i = 0 ; i < SBP_NUM_TARGETS ; i++){
1552		sbp->targets[i].fwdev = NULL;
1553		sbp->targets[i].luns = NULL;
1554	}
1555
1556	sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp,
1557				 device_get_unit(dev),
1558				 /*untagged*/ SBP_QUEUE_LEN,
1559				 /*tagged*/0, devq);
1560
1561	if (sbp->sim == NULL) {
1562		cam_simq_free(devq);
1563		return (ENXIO);
1564	}
1565
1566	sbp->ocb = (struct sbp_ocb *) contigmalloc(
1567		sizeof (struct sbp_ocb) * SBP_NUM_OCB,
1568		M_SBP, M_DONTWAIT, 0x10000, 0xffffffff, PAGE_SIZE, 0ul);
1569	bzero(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB);
1570
1571	if (sbp->ocb == NULL) {
1572		printf("sbp0: ocb alloction failure\n");
1573		return (ENOMEM);
1574	}
1575
1576	STAILQ_INIT(&sbp->free_ocbs);
1577	for (i = 0; i < SBP_NUM_OCB; i++) {
1578		sbp_free_ocb(sbp, &sbp->ocb[i]);
1579	}
1580
1581	if (xpt_bus_register(sbp->sim, /*bus*/0) != CAM_SUCCESS) {
1582		cam_sim_free(sbp->sim, /*free_devq*/TRUE);
1583		contigfree(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB,
1584									M_SBP);
1585		return (ENXIO);
1586	}
1587
1588	xfer = fw_xfer_alloc();
1589	xfer->act.hand = sbp_recv;
1590	xfer->act_type = FWACT_XFER;
1591#if NEED_RESPONSE
1592	xfer->fc = sbp->fd.fc;
1593#endif
1594	xfer->sc = (caddr_t)sbp;
1595
1596	sbp->fwb.start_hi = SBP_BIND_HI;
1597	sbp->fwb.start_lo = SBP_DEV2ADDR(device_get_unit(sbp->fd.dev), 0, 0);
1598	/* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */
1599	sbp->fwb.addrlen = 0xffff;
1600	sbp->fwb.xfer = xfer;
1601	fw_bindadd(sbp->fd.fc, &sbp->fwb);
1602
1603	sbp->fd.post_explore = sbp_post_explore;
1604	s = splfw();
1605	sbp_post_explore((void *)sbp);
1606	splx(s);
1607
1608	return (0);
1609}
1610
1611static int
1612sbp_detach(device_t dev)
1613{
1614	struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
1615	struct firewire_comm *fc = sbp->fd.fc;
1616	int i;
1617
1618SBP_DEBUG(0)
1619	printf("sbp_detach\n");
1620END_DEBUG
1621
1622	/* bus reset for logout */
1623	sbp->fd.post_explore = NULL;
1624	fc->ibr(fc);
1625
1626	contigfree(sbp->ocb, sizeof (struct sbp_ocb) * SBP_NUM_OCB, M_SBP);
1627	fw_bindremove(fc, &sbp->fwb);
1628	for (i = 0; i < SBP_NUM_TARGETS; i ++)
1629		sbp_detach_target(&sbp->targets[i]);
1630	xpt_bus_deregister(cam_sim_path(sbp->sim));
1631	bus_dma_tag_destroy(sbp->dmat);
1632	return (0);
1633}
1634
1635static void
1636sbp_detach_target(struct sbp_target *target)
1637{
1638	int i;
1639	struct sbp_dev *sdev;
1640
1641	if (target->luns != NULL) {
1642		printf("sbp_detach_target %d\n", target->target_id);
1643		for (i=0; i < target->num_lun; i++) {
1644			sdev = &target->luns[i];
1645			if (sdev->status == SBP_DEV_RESET ||
1646					sdev->status == SBP_DEV_DEAD)
1647				continue;
1648			if (sdev->path)
1649				xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
1650			xpt_free_path(sdev->path);
1651			sdev->path = NULL;
1652			sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
1653		}
1654		free(target->luns, M_SBP);
1655		target->luns = NULL;
1656	}
1657	target->fwdev = NULL;
1658}
1659
1660static void
1661sbp_timeout(void *arg)
1662{
1663	struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
1664	struct sbp_dev *sdev = ocb->sdev;
1665	int s;
1666
1667	sbp_show_sdev_info(sdev, 2);
1668	printf("request timeout ... requeue\n");
1669
1670	/* XXX need reset? */
1671
1672	s = splfw();
1673	sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
1674	splx(s);
1675	return;
1676}
1677
1678static void
1679sbp_action1(struct cam_sim *sim, union ccb *ccb)
1680{
1681
1682	struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
1683	struct sbp_target *target = NULL;
1684	struct sbp_dev *sdev = NULL;
1685
1686	/* target:lun -> sdev mapping */
1687	if (sbp != NULL
1688			&& ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
1689			&& ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
1690		target = &sbp->targets[ccb->ccb_h.target_id];
1691		if (target->fwdev != NULL
1692				&& ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
1693				&& ccb->ccb_h.target_lun < target->num_lun) {
1694			sdev = &target->luns[ccb->ccb_h.target_lun];
1695			if (sdev->status != SBP_DEV_ATTACHED &&
1696				sdev->status != SBP_DEV_PROBE)
1697				sdev = NULL;
1698		}
1699	}
1700
1701SBP_DEBUG(1)
1702	if (sdev == NULL)
1703		printf("invalid target %d lun %d\n",
1704			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
1705END_DEBUG
1706
1707	switch (ccb->ccb_h.func_code) {
1708	case XPT_SCSI_IO:
1709	case XPT_RESET_DEV:
1710	case XPT_GET_TRAN_SETTINGS:
1711	case XPT_SET_TRAN_SETTINGS:
1712	case XPT_CALC_GEOMETRY:
1713		if (sdev == NULL) {
1714SBP_DEBUG(1)
1715			printf("%s:%d:%d:func_code 0x%04x: "
1716				"Invalid target (target needed)\n",
1717				device_get_nameunit(sbp->fd.dev),
1718				ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1719				ccb->ccb_h.func_code);
1720END_DEBUG
1721
1722			ccb->ccb_h.status = CAM_TID_INVALID;
1723			xpt_done(ccb);
1724			return;
1725		}
1726		break;
1727	case XPT_PATH_INQ:
1728	case XPT_NOOP:
1729		/* The opcodes sometimes aimed at a target (sc is valid),
1730		 * sometimes aimed at the SIM (sc is invalid and target is
1731		 * CAM_TARGET_WILDCARD)
1732		 */
1733		if (sbp == NULL &&
1734			ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
1735SBP_DEBUG(0)
1736			printf("%s:%d:%d func_code 0x%04x: "
1737				"Invalid target (no wildcard)\n",
1738				device_get_nameunit(sbp->fd.dev),
1739				ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1740				ccb->ccb_h.func_code);
1741END_DEBUG
1742			ccb->ccb_h.status = CAM_TID_INVALID;
1743			xpt_done(ccb);
1744			return;
1745		}
1746		break;
1747	default:
1748		/* XXX Hm, we should check the input parameters */
1749		break;
1750	}
1751
1752	switch (ccb->ccb_h.func_code) {
1753	case XPT_SCSI_IO:
1754	{
1755		struct ccb_scsiio *csio;
1756		struct sbp_ocb *ocb;
1757		int s, speed;
1758		void *cdb;
1759
1760		csio = &ccb->csio;
1761
1762SBP_DEBUG(1)
1763		printf("%s:%d:%d XPT_SCSI_IO: "
1764			"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1765			", flags: 0x%02x, "
1766			"%db cmd/%db data/%db sense\n",
1767			device_get_nameunit(sbp->fd.dev),
1768			ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1769			csio->cdb_io.cdb_bytes[0],
1770			csio->cdb_io.cdb_bytes[1],
1771			csio->cdb_io.cdb_bytes[2],
1772			csio->cdb_io.cdb_bytes[3],
1773			csio->cdb_io.cdb_bytes[4],
1774			csio->cdb_io.cdb_bytes[5],
1775			csio->cdb_io.cdb_bytes[6],
1776			csio->cdb_io.cdb_bytes[7],
1777			csio->cdb_io.cdb_bytes[8],
1778			csio->cdb_io.cdb_bytes[9],
1779			ccb->ccb_h.flags & CAM_DIR_MASK,
1780			csio->cdb_len, csio->dxfer_len,
1781			csio->sense_len);
1782END_DEBUG
1783		if(sdev == NULL){
1784			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
1785			xpt_done(ccb);
1786			return;
1787		}
1788#if 0
1789		/* if we are in probe stage, pass only probe commands */
1790		if (sdev->status == SBP_DEV_PROBE) {
1791			char *name;
1792			name = xpt_path_periph(ccb->ccb_h.path)->periph_name;
1793			printf("probe stage, periph name: %s\n", name);
1794			if (strcmp(name, "probe") != 0) {
1795				ccb->ccb_h.status = CAM_REQUEUE_REQ;
1796				xpt_done(ccb);
1797				return;
1798			}
1799		}
1800#endif
1801		if ((ocb = sbp_get_ocb(sbp)) == NULL) {
1802			s = splfw();
1803			sbp->flags |= SBP_RESOURCE_SHORTAGE;
1804			splx(s);
1805			return;
1806		}
1807		ocb->flags = OCB_ACT_CMD;
1808		ocb->sdev = sdev;
1809		ocb->ccb = ccb;
1810		ccb->ccb_h.ccb_sdev_ptr = sdev;
1811		ocb->orb[0] = htonl(1 << 31);
1812		ocb->orb[1] = 0;
1813		ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
1814		ocb->orb[3] = htonl(vtophys(ocb->ind_ptr));
1815		speed = min(target->fwdev->speed, max_speed);
1816		ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
1817						| ORB_CMD_MAXP(speed + 7));
1818		if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){
1819			ocb->orb[4] |= htonl(ORB_CMD_IN);
1820		}
1821
1822		if (csio->ccb_h.flags & CAM_SCATTER_VALID)
1823			printf("sbp: CAM_SCATTER_VALID\n");
1824		if (csio->ccb_h.flags & CAM_DATA_PHYS)
1825			printf("sbp: CAM_DATA_PHYS\n");
1826
1827		if (csio->ccb_h.flags & CAM_CDB_POINTER)
1828			cdb = (void *)csio->cdb_io.cdb_ptr;
1829		else
1830			cdb = (void *)&csio->cdb_io.cdb_bytes;
1831		bcopy(cdb,
1832			(void *)(uintptr_t)(volatile void *)&ocb->orb[5],
1833				csio->cdb_len);
1834/*
1835printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
1836printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
1837*/
1838		if (ccb->csio.dxfer_len > 0) {
1839			int s;
1840
1841			if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
1842				printf("sbp_action1: cannot create dmamap\n");
1843				break;
1844			}
1845
1846			s = splsoftvm();
1847			bus_dmamap_load(/*dma tag*/sbp->dmat,
1848					/*dma map*/ocb->dmamap,
1849					ccb->csio.data_ptr,
1850					ccb->csio.dxfer_len,
1851					sbp_execute_ocb,
1852					ocb,
1853					/*flags*/0);
1854			splx(s);
1855		} else
1856			sbp_execute_ocb(ocb, NULL, 0, 0);
1857		break;
1858	}
1859	case XPT_CALC_GEOMETRY:
1860	{
1861		struct ccb_calc_geometry *ccg;
1862		u_int32_t size_mb;
1863		u_int32_t secs_per_cylinder;
1864		int extended = 1;
1865		ccg = &ccb->ccg;
1866
1867		if (ccg->block_size == 0) {
1868			printf("sbp_action1: block_size is 0.\n");
1869			ccb->ccb_h.status = CAM_REQ_INVALID;
1870			xpt_done(ccb);
1871			break;
1872		}
1873SBP_DEBUG(1)
1874		printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: "
1875			"Volume size = %d\n",
1876			device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim),
1877			ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
1878			ccg->volume_size);
1879END_DEBUG
1880
1881		size_mb = ccg->volume_size
1882			/ ((1024L * 1024L) / ccg->block_size);
1883
1884		if (size_mb >= 1024 && extended) {
1885			ccg->heads = 255;
1886			ccg->secs_per_track = 63;
1887		} else {
1888			ccg->heads = 64;
1889			ccg->secs_per_track = 32;
1890		}
1891		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1892		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1893		ccb->ccb_h.status = CAM_REQ_CMP;
1894		xpt_done(ccb);
1895		break;
1896	}
1897	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
1898	{
1899
1900SBP_DEBUG(1)
1901		printf("%s:%d:XPT_RESET_BUS: \n",
1902			device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
1903END_DEBUG
1904
1905		ccb->ccb_h.status = CAM_REQ_INVALID;
1906		xpt_done(ccb);
1907		break;
1908	}
1909	case XPT_PATH_INQ:		/* Path routing inquiry */
1910	{
1911		struct ccb_pathinq *cpi = &ccb->cpi;
1912
1913SBP_DEBUG(1)
1914		printf("%s:%d:%d XPT_PATH_INQ:.\n",
1915			device_get_nameunit(sbp->fd.dev),
1916			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
1917END_DEBUG
1918		cpi->version_num = 1; /* XXX??? */
1919		cpi->hba_inquiry = 0;
1920		cpi->target_sprt = 0;
1921		cpi->hba_misc = 0;
1922		cpi->hba_eng_cnt = 0;
1923		cpi->max_target = SBP_NUM_TARGETS - 1;
1924		cpi->max_lun = SBP_NUM_LUNS - 1;
1925		cpi->initiator_id = SBP_INITIATOR;
1926		cpi->bus_id = sim->bus_id;
1927		cpi->base_transfer_speed = 400 * 1000 / 8;
1928		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1929		strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
1930		strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
1931		cpi->unit_number = sim->unit_number;
1932
1933		cpi->ccb_h.status = CAM_REQ_CMP;
1934		xpt_done(ccb);
1935		break;
1936	}
1937	case XPT_GET_TRAN_SETTINGS:
1938	{
1939		struct ccb_trans_settings *cts = &ccb->cts;
1940SBP_DEBUG(1)
1941		printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
1942			device_get_nameunit(sbp->fd.dev),
1943			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
1944END_DEBUG
1945		/* Disable disconnect and tagged queuing */
1946		cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
1947		cts->flags = 0;
1948
1949		cts->ccb_h.status = CAM_REQ_CMP;
1950		xpt_done(ccb);
1951		break;
1952	}
1953	case XPT_ABORT:
1954		ccb->ccb_h.status = CAM_UA_ABORT;
1955		xpt_done(ccb);
1956		break;
1957	default:
1958		ccb->ccb_h.status = CAM_REQ_INVALID;
1959		xpt_done(ccb);
1960		break;
1961	}
1962	return;
1963}
1964
1965static void
1966sbp_action(struct cam_sim *sim, union ccb *ccb)
1967{
1968	int s;
1969
1970	s = splfw();
1971	sbp_action1(sim, ccb);
1972	splx(s);
1973}
1974
1975static void
1976sbp_execute_ocb(void *arg,  bus_dma_segment_t *segments, int seg, int error)
1977{
1978	int i;
1979	struct sbp_ocb *ocb;
1980	struct sbp_ocb *prev;
1981	union ccb *ccb;
1982	bus_dma_segment_t *s;
1983
1984	if (error)
1985		printf("sbp_execute_ocb: error=%d\n", error);
1986
1987	ocb = (struct sbp_ocb *)arg;
1988	if (seg == 1) {
1989		/* direct pointer */
1990		ocb->orb[3] = htonl(segments[0].ds_addr);
1991		ocb->orb[4] |= htonl(segments[0].ds_len);
1992	} else if(seg > 1) {
1993		/* page table */
1994SBP_DEBUG(1)
1995		printf("sbp_execute_ocb: seg %d", seg);
1996		for (i = 0; i < seg; i++)
1997			printf(", %x:%d", segments[i].ds_addr,
1998						segments[i].ds_len);
1999		printf("\n");
2000END_DEBUG
2001		for (i = 0; i < seg; i++) {
2002			s = &segments[i];
2003#if 1			/* XXX LSI Logic "< 16 byte" bug might be hit */
2004			if (s->ds_len < 16)
2005				printf("sbp_execute_ocb: warning, "
2006					"segment length(%d) is less than 16."
2007					"(seg=%d/%d)\n", s->ds_len, i+1, seg);
2008#endif
2009			ocb->ind_ptr[i].hi = htonl(s->ds_len << 16);
2010			ocb->ind_ptr[i].lo = htonl(s->ds_addr);
2011		}
2012		ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
2013	}
2014
2015	ccb = ocb->ccb;
2016	prev = sbp_enqueue_ocb(ocb->sdev, ocb);
2017	if (prev)
2018		sbp_doorbell(ocb->sdev);
2019	else
2020		sbp_orb_pointer(ocb->sdev, ocb);
2021}
2022
2023static void
2024sbp_poll(struct cam_sim *sim)
2025{
2026	/* should call fwohci_intr? */
2027	return;
2028}
2029static struct sbp_ocb *
2030sbp_dequeue_ocb(struct sbp_dev *sdev, u_int32_t orb_lo)
2031{
2032	struct sbp_ocb *ocb;
2033	struct sbp_ocb *next;
2034	int s = splfw(), order = 0;
2035	int flags;
2036
2037	for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) {
2038		next = STAILQ_NEXT(ocb, ocb);
2039		flags = ocb->flags;
2040SBP_DEBUG(1)
2041		printf("orb: 0x%x next: 0x%x, flags %x\n",
2042			vtophys(&ocb->orb[0]), ntohl(ocb->orb[1]), flags);
2043END_DEBUG
2044		if (vtophys(&ocb->orb[0]) == orb_lo) {
2045			/* found */
2046			if (ocb->flags & OCB_RESERVED)
2047				ocb->flags |= OCB_DONE;
2048			else
2049				STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2050			if (ocb->ccb != NULL)
2051				untimeout(sbp_timeout, (caddr_t)ocb,
2052						ocb->ccb->ccb_h.timeout_ch);
2053			if (ocb->dmamap != NULL) {
2054				bus_dmamap_destroy(sdev->target->sbp->dmat,
2055							ocb->dmamap);
2056				ocb->dmamap = NULL;
2057			}
2058			break;
2059		} else {
2060			if ((ocb->flags & OCB_RESERVED) &&
2061					(ocb->flags & OCB_DONE)) {
2062				/* next orb must be fetched already */
2063				STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2064				sbp_free_ocb(sdev->target->sbp, ocb);
2065			} else
2066				order ++;
2067		}
2068	}
2069	splx(s);
2070SBP_DEBUG(0)
2071	if (ocb && order > 0) {
2072		sbp_show_sdev_info(sdev, 2);
2073		printf("unordered execution order:%d\n", order);
2074	}
2075END_DEBUG
2076	return (ocb);
2077}
2078
2079static struct sbp_ocb *
2080sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2081{
2082	int s = splfw();
2083	struct sbp_ocb *prev;
2084
2085SBP_DEBUG(2)
2086	sbp_show_sdev_info(sdev, 2);
2087	printf("sbp_enqueue_ocb orb=0x%x in physical memory\n", vtophys(&ocb->orb[0]));
2088END_DEBUG
2089	prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
2090	STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
2091
2092	if (ocb->ccb != NULL)
2093		ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb,
2094					(ocb->ccb->ccb_h.timeout * hz) / 1000);
2095
2096	if (prev != NULL
2097		&& ((prev->flags & OCB_ACT_MASK) == OCB_ACT_CMD)
2098		&& ((ocb->flags & OCB_ACT_MASK) == OCB_ACT_CMD)) {
2099SBP_DEBUG(1)
2100	printf("linking chain 0x%x -> 0x%x\n", vtophys(&prev->orb[0]),
2101			vtophys(&ocb->orb[0]));
2102END_DEBUG
2103		prev->flags |= OCB_RESERVED;
2104		prev->orb[1] = htonl(vtophys(&ocb->orb[0]));
2105		prev->orb[0] = 0;
2106	} else {
2107		prev = NULL;
2108	}
2109	splx(s);
2110
2111	return prev;
2112}
2113
2114static struct sbp_ocb *
2115sbp_get_ocb(struct sbp_softc *sbp)
2116{
2117	struct sbp_ocb *ocb;
2118	int s = splfw();
2119	ocb = STAILQ_FIRST(&sbp->free_ocbs);
2120	if (ocb == NULL) {
2121		printf("ocb shortage!!!\n");
2122		return NULL;
2123	}
2124	STAILQ_REMOVE(&sbp->free_ocbs, ocb, sbp_ocb, ocb);
2125	splx(s);
2126	ocb->ccb = NULL;
2127	return (ocb);
2128}
2129
2130static void
2131sbp_free_ocb(struct sbp_softc *sbp, struct sbp_ocb *ocb)
2132{
2133#if 0 /* XXX make sure that ocb has ccb */
2134	if ((sbp->flags & SBP_RESOURCE_SHORTAGE) != 0 &&
2135	    (ocb->ccb->ccb_h.status & CAM_RELEASE_SIMQ) == 0) {
2136		ocb->ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
2137		sbp->flags &= ~SBP_RESOURCE_SHORTAGE;
2138	}
2139#else
2140	if ((sbp->flags & SBP_RESOURCE_SHORTAGE) != 0)
2141		sbp->flags &= ~SBP_RESOURCE_SHORTAGE;
2142#endif
2143	ocb->flags = 0;
2144	ocb->ccb = NULL;
2145	STAILQ_INSERT_TAIL(&sbp->free_ocbs, ocb, ocb);
2146}
2147
2148static void
2149sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2150{
2151	struct sbp_dev *sdev;
2152
2153	sdev = ocb->sdev;
2154SBP_DEBUG(0)
2155	sbp_show_sdev_info(sdev, 2);
2156	printf("sbp_abort_ocb 0x%x\n", status);
2157	if (ocb->ccb != NULL)
2158		sbp_print_scsi_cmd(ocb);
2159END_DEBUG
2160	if (ocb->ccb != NULL && !(ocb->flags & OCB_DONE)) {
2161		if (status != CAM_CMD_TIMEOUT)
2162			untimeout(sbp_timeout, (caddr_t)ocb,
2163						ocb->ccb->ccb_h.timeout_ch);
2164		ocb->ccb->ccb_h.status = status;
2165		xpt_done(ocb->ccb);
2166	}
2167	if (ocb->dmamap != NULL) {
2168		bus_dmamap_destroy(sdev->target->sbp->dmat, ocb->dmamap);
2169		ocb->dmamap = NULL;
2170	}
2171	sbp_free_ocb(sdev->target->sbp, ocb);
2172}
2173
2174static void
2175sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
2176{
2177	int s;
2178	struct sbp_ocb *ocb, *next;
2179	STAILQ_HEAD(, sbp_ocb) temp;
2180
2181	s = splfw();
2182
2183	bcopy(&sdev->ocbs, &temp, sizeof(temp));
2184	STAILQ_INIT(&sdev->ocbs);
2185	for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) {
2186		next = STAILQ_NEXT(ocb, ocb);
2187		sbp_abort_ocb(ocb, status);
2188	}
2189
2190	splx(s);
2191}
2192
2193static devclass_t sbp_devclass;
2194
2195static device_method_t sbp_methods[] = {
2196	/* device interface */
2197	DEVMETHOD(device_identify,	sbp_identify),
2198	DEVMETHOD(device_probe,		sbp_probe),
2199	DEVMETHOD(device_attach,	sbp_attach),
2200	DEVMETHOD(device_detach,	sbp_detach),
2201
2202	{ 0, 0 }
2203};
2204
2205static driver_t sbp_driver = {
2206	"sbp",
2207	sbp_methods,
2208	sizeof(struct sbp_softc),
2209};
2210DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
2211MODULE_VERSION(sbp, 1);
2212MODULE_DEPEND(sbp, firewire, 1, 1, 1);
2213MODULE_DEPEND(sbp, cam, 1, 1, 1);
2214