sbp.c revision 227293
1/*-
2 * Copyright (c) 2003 Hidetoshi Shimokawa
3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 *    must display the acknowledgement as bellow:
16 *
17 *    This product includes software developed by K. Kobayashi and H. Shimokawa
18 *
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 * $FreeBSD: head/sys/dev/firewire/sbp.c 227293 2011-11-07 06:44:47Z ed $
35 *
36 */
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/module.h>
41#include <sys/bus.h>
42#include <sys/kernel.h>
43#include <sys/sysctl.h>
44#include <machine/bus.h>
45#include <sys/malloc.h>
46#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
47#include <sys/lock.h>
48#include <sys/mutex.h>
49#endif
50
51#if defined(__DragonFly__) || __FreeBSD_version < 500106
52#include <sys/devicestat.h>	/* for struct devstat */
53#endif
54
55#ifdef __DragonFly__
56#include <bus/cam/cam.h>
57#include <bus/cam/cam_ccb.h>
58#include <bus/cam/cam_sim.h>
59#include <bus/cam/cam_xpt_sim.h>
60#include <bus/cam/cam_debug.h>
61#include <bus/cam/cam_periph.h>
62#include <bus/cam/scsi/scsi_all.h>
63
64#include <bus/firewire/firewire.h>
65#include <bus/firewire/firewirereg.h>
66#include <bus/firewire/fwdma.h>
67#include <bus/firewire/iec13213.h>
68#include "sbp.h"
69#else
70#include <cam/cam.h>
71#include <cam/cam_ccb.h>
72#include <cam/cam_sim.h>
73#include <cam/cam_xpt_sim.h>
74#include <cam/cam_debug.h>
75#include <cam/cam_periph.h>
76#include <cam/scsi/scsi_all.h>
77
78#include <dev/firewire/firewire.h>
79#include <dev/firewire/firewirereg.h>
80#include <dev/firewire/fwdma.h>
81#include <dev/firewire/iec13213.h>
82#include <dev/firewire/sbp.h>
83#endif
84
85#define ccb_sdev_ptr	spriv_ptr0
86#define ccb_sbp_ptr	spriv_ptr1
87
88#define SBP_NUM_TARGETS 8 /* MAX 64 */
89/*
90 * Scan_bus doesn't work for more than 8 LUNs
91 * because of CAM_SCSI2_MAXLUN in cam_xpt.c
92 */
93#define SBP_NUM_LUNS 64
94#define SBP_MAXPHYS  MIN(MAXPHYS, (512*1024) /* 512KB */)
95#define SBP_DMA_SIZE PAGE_SIZE
96#define SBP_LOGIN_SIZE sizeof(struct sbp_login_res)
97#define SBP_QUEUE_LEN ((SBP_DMA_SIZE - SBP_LOGIN_SIZE) / sizeof(struct sbp_ocb))
98#define SBP_NUM_OCB (SBP_QUEUE_LEN * SBP_NUM_TARGETS)
99
100/*
101 * STATUS FIFO addressing
102 *   bit
103 * -----------------------
104 *  0- 1( 2): 0 (alignment)
105 *  2- 7( 6): target
106 *  8-15( 8): lun
107 * 16-31( 8): reserved
108 * 32-47(16): SBP_BIND_HI
109 * 48-64(16): bus_id, node_id
110 */
111#define SBP_BIND_HI 0x1
112#define SBP_DEV2ADDR(t, l) \
113	(((u_int64_t)SBP_BIND_HI << 32) \
114	| (((l) & 0xff) << 8) \
115	| (((t) & 0x3f) << 2))
116#define SBP_ADDR2TRG(a)	(((a) >> 2) & 0x3f)
117#define SBP_ADDR2LUN(a)	(((a) >> 8) & 0xff)
118#define SBP_INITIATOR 7
119
120static char *orb_fun_name[] = {
121	ORB_FUN_NAMES
122};
123
124static int debug = 0;
125static int auto_login = 1;
126static int max_speed = -1;
127static int sbp_cold = 1;
128static int ex_login = 1;
129static int login_delay = 1000;	/* msec */
130static int scan_delay = 500;	/* msec */
131static int use_doorbell = 0;
132static int sbp_tags = 0;
133
134SYSCTL_DECL(_hw_firewire);
135SYSCTL_NODE(_hw_firewire, OID_AUTO, sbp, CTLFLAG_RD, 0, "SBP-II Subsystem");
136SYSCTL_INT(_debug, OID_AUTO, sbp_debug, CTLFLAG_RW, &debug, 0,
137	"SBP debug flag");
138SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, auto_login, CTLFLAG_RW, &auto_login, 0,
139	"SBP perform login automatically");
140SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, max_speed, CTLFLAG_RW, &max_speed, 0,
141	"SBP transfer max speed");
142SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, exclusive_login, CTLFLAG_RW,
143	&ex_login, 0, "SBP enable exclusive login");
144SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, login_delay, CTLFLAG_RW,
145	&login_delay, 0, "SBP login delay in msec");
146SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, scan_delay, CTLFLAG_RW,
147	&scan_delay, 0, "SBP scan delay in msec");
148SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, use_doorbell, CTLFLAG_RW,
149	&use_doorbell, 0, "SBP use doorbell request");
150SYSCTL_INT(_hw_firewire_sbp, OID_AUTO, tags, CTLFLAG_RW, &sbp_tags, 0,
151	"SBP tagged queuing support");
152
153TUNABLE_INT("hw.firewire.sbp.auto_login", &auto_login);
154TUNABLE_INT("hw.firewire.sbp.max_speed", &max_speed);
155TUNABLE_INT("hw.firewire.sbp.exclusive_login", &ex_login);
156TUNABLE_INT("hw.firewire.sbp.login_delay", &login_delay);
157TUNABLE_INT("hw.firewire.sbp.scan_delay", &scan_delay);
158TUNABLE_INT("hw.firewire.sbp.use_doorbell", &use_doorbell);
159TUNABLE_INT("hw.firewire.sbp.tags", &sbp_tags);
160
161#define NEED_RESPONSE 0
162
163#define SBP_SEG_MAX rounddown(0xffff, PAGE_SIZE)
164#ifdef __sparc64__ /* iommu */
165#define SBP_IND_MAX howmany(SBP_MAXPHYS, SBP_SEG_MAX)
166#else
167#define SBP_IND_MAX howmany(SBP_MAXPHYS, PAGE_SIZE)
168#endif
169struct sbp_ocb {
170	STAILQ_ENTRY(sbp_ocb)	ocb;
171	union ccb	*ccb;
172	bus_addr_t	bus_addr;
173	uint32_t	orb[8];
174#define IND_PTR_OFFSET	(8*sizeof(uint32_t))
175	struct ind_ptr  ind_ptr[SBP_IND_MAX];
176	struct sbp_dev	*sdev;
177	int		flags; /* XXX should be removed */
178	bus_dmamap_t	dmamap;
179};
180
181#define OCB_ACT_MGM 0
182#define OCB_ACT_CMD 1
183#define OCB_MATCH(o,s)	((o)->bus_addr == ntohl((s)->orb_lo))
184
185struct sbp_dev{
186#define SBP_DEV_RESET		0	/* accept login */
187#define SBP_DEV_LOGIN		1	/* to login */
188#if 0
189#define SBP_DEV_RECONN		2	/* to reconnect */
190#endif
191#define SBP_DEV_TOATTACH	3	/* to attach */
192#define SBP_DEV_PROBE		4	/* scan lun */
193#define SBP_DEV_ATTACHED	5	/* in operation */
194#define SBP_DEV_DEAD		6	/* unavailable unit */
195#define SBP_DEV_RETRY		7	/* unavailable unit */
196	uint8_t status:4,
197		 timeout:4;
198	uint8_t type;
199	uint16_t lun_id;
200	uint16_t freeze;
201#define	ORB_LINK_DEAD		(1 << 0)
202#define	VALID_LUN		(1 << 1)
203#define	ORB_POINTER_ACTIVE	(1 << 2)
204#define	ORB_POINTER_NEED	(1 << 3)
205#define	ORB_DOORBELL_ACTIVE	(1 << 4)
206#define	ORB_DOORBELL_NEED	(1 << 5)
207#define	ORB_SHORTAGE		(1 << 6)
208	uint16_t flags;
209	struct cam_path *path;
210	struct sbp_target *target;
211	struct fwdma_alloc dma;
212	struct sbp_login_res *login;
213	struct callout login_callout;
214	struct sbp_ocb *ocb;
215	STAILQ_HEAD(, sbp_ocb) ocbs;
216	STAILQ_HEAD(, sbp_ocb) free_ocbs;
217	struct sbp_ocb *last_ocb;
218	char vendor[32];
219	char product[32];
220	char revision[10];
221	char bustgtlun[32];
222};
223
224struct sbp_target {
225	int target_id;
226	int num_lun;
227	struct sbp_dev	**luns;
228	struct sbp_softc *sbp;
229	struct fw_device *fwdev;
230	uint32_t mgm_hi, mgm_lo;
231	struct sbp_ocb *mgm_ocb_cur;
232	STAILQ_HEAD(, sbp_ocb) mgm_ocb_queue;
233	struct callout mgm_ocb_timeout;
234	struct callout scan_callout;
235	STAILQ_HEAD(, fw_xfer) xferlist;
236	int n_xfer;
237};
238
239struct sbp_softc {
240	struct firewire_dev_comm fd;
241	struct cam_sim  *sim;
242	struct cam_path  *path;
243	struct sbp_target targets[SBP_NUM_TARGETS];
244	struct fw_bind fwb;
245	bus_dma_tag_t	dmat;
246	struct timeval last_busreset;
247#define SIMQ_FREEZED 1
248	int flags;
249	struct mtx mtx;
250};
251#define SBP_LOCK(sbp) mtx_lock(&(sbp)->mtx)
252#define SBP_UNLOCK(sbp) mtx_unlock(&(sbp)->mtx)
253
254static void sbp_post_explore (void *);
255static void sbp_recv (struct fw_xfer *);
256static void sbp_mgm_callback (struct fw_xfer *);
257#if 0
258static void sbp_cmd_callback (struct fw_xfer *);
259#endif
260static void sbp_orb_pointer (struct sbp_dev *, struct sbp_ocb *);
261static void sbp_doorbell(struct sbp_dev *);
262static void sbp_execute_ocb (void *,  bus_dma_segment_t *, int, int);
263static void sbp_free_ocb (struct sbp_dev *, struct sbp_ocb *);
264static void sbp_abort_ocb (struct sbp_ocb *, int);
265static void sbp_abort_all_ocbs (struct sbp_dev *, int);
266static struct fw_xfer * sbp_write_cmd_locked (struct sbp_dev *, int, int);
267static struct fw_xfer * sbp_write_cmd (struct sbp_dev *, int, int);
268static struct sbp_ocb * sbp_get_ocb (struct sbp_dev *);
269static struct sbp_ocb * sbp_enqueue_ocb (struct sbp_dev *, struct sbp_ocb *);
270static struct sbp_ocb * sbp_dequeue_ocb (struct sbp_dev *, struct sbp_status *);
271static void sbp_cam_detach_sdev(struct sbp_dev *);
272static void sbp_free_sdev(struct sbp_dev *);
273static void sbp_cam_detach_target (struct sbp_target *);
274static void sbp_free_target (struct sbp_target *);
275static void sbp_mgm_timeout (void *arg);
276static void sbp_timeout (void *arg);
277static void sbp_mgm_orb (struct sbp_dev *, int, struct sbp_ocb *);
278
279static MALLOC_DEFINE(M_SBP, "sbp", "SBP-II/FireWire");
280
281/* cam related functions */
282static void	sbp_action(struct cam_sim *sim, union ccb *ccb);
283static void	sbp_poll(struct cam_sim *sim);
284static void	sbp_cam_scan_lun(struct cam_periph *, union ccb *);
285static void	sbp_cam_scan_target(void *arg);
286
287static char *orb_status0[] = {
288	/* 0 */ "No additional information to report",
289	/* 1 */ "Request type not supported",
290	/* 2 */ "Speed not supported",
291	/* 3 */ "Page size not supported",
292	/* 4 */ "Access denied",
293	/* 5 */ "Logical unit not supported",
294	/* 6 */ "Maximum payload too small",
295	/* 7 */ "Reserved for future standardization",
296	/* 8 */ "Resources unavailable",
297	/* 9 */ "Function rejected",
298	/* A */ "Login ID not recognized",
299	/* B */ "Dummy ORB completed",
300	/* C */ "Request aborted",
301	/* FF */ "Unspecified error"
302#define MAX_ORB_STATUS0 0xd
303};
304
305static char *orb_status1_object[] = {
306	/* 0 */ "Operation request block (ORB)",
307	/* 1 */ "Data buffer",
308	/* 2 */ "Page table",
309	/* 3 */ "Unable to specify"
310};
311
312static char *orb_status1_serial_bus_error[] = {
313	/* 0 */ "Missing acknowledge",
314	/* 1 */ "Reserved; not to be used",
315	/* 2 */ "Time-out error",
316	/* 3 */ "Reserved; not to be used",
317	/* 4 */ "Busy retry limit exceeded(X)",
318	/* 5 */ "Busy retry limit exceeded(A)",
319	/* 6 */ "Busy retry limit exceeded(B)",
320	/* 7 */ "Reserved for future standardization",
321	/* 8 */ "Reserved for future standardization",
322	/* 9 */ "Reserved for future standardization",
323	/* A */ "Reserved for future standardization",
324	/* B */ "Tardy retry limit exceeded",
325	/* C */ "Conflict error",
326	/* D */ "Data error",
327	/* E */ "Type error",
328	/* F */ "Address error"
329};
330
331static void
332sbp_identify(driver_t *driver, device_t parent)
333{
334SBP_DEBUG(0)
335	printf("sbp_identify\n");
336END_DEBUG
337
338	BUS_ADD_CHILD(parent, 0, "sbp", device_get_unit(parent));
339}
340
341/*
342 * sbp_probe()
343 */
344static int
345sbp_probe(device_t dev)
346{
347	device_t pa;
348
349SBP_DEBUG(0)
350	printf("sbp_probe\n");
351END_DEBUG
352
353	pa = device_get_parent(dev);
354	if(device_get_unit(dev) != device_get_unit(pa)){
355		return(ENXIO);
356	}
357
358	device_set_desc(dev, "SBP-2/SCSI over FireWire");
359
360#if 0
361	if (bootverbose)
362		debug = bootverbose;
363#endif
364
365	return (0);
366}
367
368/*
369 * Display device characteristics on the console
370 */
371static void
372sbp_show_sdev_info(struct sbp_dev *sdev)
373{
374	struct fw_device *fwdev;
375
376	fwdev = sdev->target->fwdev;
377	device_printf(sdev->target->sbp->fd.dev,
378		"%s: %s: ordered:%d type:%d EUI:%08x%08x node:%d "
379		"speed:%d maxrec:%d\n",
380		__func__,
381		sdev->bustgtlun,
382		(sdev->type & 0x40) >> 6,
383		(sdev->type & 0x1f),
384		fwdev->eui.hi,
385		fwdev->eui.lo,
386		fwdev->dst,
387		fwdev->speed,
388		fwdev->maxrec);
389
390	device_printf(sdev->target->sbp->fd.dev,
391			"%s: %s '%s' '%s' '%s'\n",
392			__func__,
393			sdev->bustgtlun,
394			sdev->vendor,
395			sdev->product,
396			sdev->revision);
397}
398
399static struct {
400	int bus;
401	int target;
402	struct fw_eui64 eui;
403} wired[] = {
404	/* Bus	Target	EUI64 */
405#if 0
406	{0,	2,	{0x00018ea0, 0x01fd0154}},	/* Logitec HDD */
407	{0,	0,	{0x00018ea6, 0x00100682}},	/* Logitec DVD */
408	{0,	1,	{0x00d03200, 0xa412006a}},	/* Yano HDD */
409#endif
410	{-1,	-1,	{0,0}}
411};
412
413static int
414sbp_new_target(struct sbp_softc *sbp, struct fw_device *fwdev)
415{
416	int bus, i, target=-1;
417	char w[SBP_NUM_TARGETS];
418
419	bzero(w, sizeof(w));
420	bus = device_get_unit(sbp->fd.dev);
421
422	/* XXX wired-down configuration should be gotten from
423					tunable or device hint */
424	for (i = 0; wired[i].bus >= 0; i ++) {
425		if (wired[i].bus == bus) {
426			w[wired[i].target] = 1;
427			if (wired[i].eui.hi == fwdev->eui.hi &&
428					wired[i].eui.lo == fwdev->eui.lo)
429				target = wired[i].target;
430		}
431	}
432	if (target >= 0) {
433		if(target < SBP_NUM_TARGETS &&
434				sbp->targets[target].fwdev == NULL)
435			return(target);
436		device_printf(sbp->fd.dev,
437			"target %d is not free for %08x:%08x\n",
438			target, fwdev->eui.hi, fwdev->eui.lo);
439		target = -1;
440	}
441	/* non-wired target */
442	for (i = 0; i < SBP_NUM_TARGETS; i ++)
443		if (sbp->targets[i].fwdev == NULL && w[i] == 0) {
444			target = i;
445			break;
446		}
447
448	return target;
449}
450
451static void
452sbp_alloc_lun(struct sbp_target *target)
453{
454	struct crom_context cc;
455	struct csrreg *reg;
456	struct sbp_dev *sdev, **newluns;
457	struct sbp_softc *sbp;
458	int maxlun, lun, i;
459
460	sbp = target->sbp;
461	crom_init_context(&cc, target->fwdev->csrrom);
462	/* XXX shoud parse appropriate unit directories only */
463	maxlun = -1;
464	while (cc.depth >= 0) {
465		reg = crom_search_key(&cc, CROM_LUN);
466		if (reg == NULL)
467			break;
468		lun = reg->val & 0xffff;
469SBP_DEBUG(0)
470		printf("target %d lun %d found\n", target->target_id, lun);
471END_DEBUG
472		if (maxlun < lun)
473			maxlun = lun;
474		crom_next(&cc);
475	}
476	if (maxlun < 0)
477		printf("%s:%d no LUN found\n",
478		    device_get_nameunit(target->sbp->fd.dev),
479		    target->target_id);
480
481	maxlun ++;
482	if (maxlun >= SBP_NUM_LUNS)
483		maxlun = SBP_NUM_LUNS;
484
485	/* Invalidiate stale devices */
486	for (lun = 0; lun < target->num_lun; lun ++) {
487		sdev = target->luns[lun];
488		if (sdev == NULL)
489			continue;
490		sdev->flags &= ~VALID_LUN;
491		if (lun >= maxlun) {
492			/* lost device */
493			sbp_cam_detach_sdev(sdev);
494			sbp_free_sdev(sdev);
495			target->luns[lun] = NULL;
496		}
497	}
498
499	/* Reallocate */
500	if (maxlun != target->num_lun) {
501		newluns = (struct sbp_dev **) realloc(target->luns,
502		    sizeof(struct sbp_dev *) * maxlun,
503		    M_SBP, M_NOWAIT | M_ZERO);
504
505		if (newluns == NULL) {
506			printf("%s: realloc failed\n", __func__);
507			newluns = target->luns;
508			maxlun = target->num_lun;
509		}
510
511		/*
512		 * We must zero the extended region for the case
513		 * realloc() doesn't allocate new buffer.
514		 */
515		if (maxlun > target->num_lun)
516			bzero(&newluns[target->num_lun],
517			    sizeof(struct sbp_dev *) *
518			    (maxlun - target->num_lun));
519
520		target->luns = newluns;
521		target->num_lun = maxlun;
522	}
523
524	crom_init_context(&cc, target->fwdev->csrrom);
525	while (cc.depth >= 0) {
526		int new = 0;
527
528		reg = crom_search_key(&cc, CROM_LUN);
529		if (reg == NULL)
530			break;
531		lun = reg->val & 0xffff;
532		if (lun >= SBP_NUM_LUNS) {
533			printf("too large lun %d\n", lun);
534			goto next;
535		}
536
537		sdev = target->luns[lun];
538		if (sdev == NULL) {
539			sdev = malloc(sizeof(struct sbp_dev),
540			    M_SBP, M_NOWAIT | M_ZERO);
541			if (sdev == NULL) {
542				printf("%s: malloc failed\n", __func__);
543				goto next;
544			}
545			target->luns[lun] = sdev;
546			sdev->lun_id = lun;
547			sdev->target = target;
548			STAILQ_INIT(&sdev->ocbs);
549			CALLOUT_INIT(&sdev->login_callout);
550			sdev->status = SBP_DEV_RESET;
551			new = 1;
552			snprintf(sdev->bustgtlun, 32, "%s:%d:%d",
553					device_get_nameunit(sdev->target->sbp->fd.dev),
554					sdev->target->target_id,
555					sdev->lun_id);
556		}
557		sdev->flags |= VALID_LUN;
558		sdev->type = (reg->val & 0xff0000) >> 16;
559
560		if (new == 0)
561			goto next;
562
563		fwdma_malloc(sbp->fd.fc,
564			/* alignment */ sizeof(uint32_t),
565			SBP_DMA_SIZE, &sdev->dma, BUS_DMA_NOWAIT |
566			BUS_DMA_COHERENT);
567		if (sdev->dma.v_addr == NULL) {
568			printf("%s: dma space allocation failed\n",
569							__func__);
570			free(sdev, M_SBP);
571			target->luns[lun] = NULL;
572			goto next;
573		}
574		sdev->login = (struct sbp_login_res *) sdev->dma.v_addr;
575		sdev->ocb = (struct sbp_ocb *)
576				((char *)sdev->dma.v_addr + SBP_LOGIN_SIZE);
577		bzero((char *)sdev->ocb,
578			sizeof (struct sbp_ocb) * SBP_QUEUE_LEN);
579
580		STAILQ_INIT(&sdev->free_ocbs);
581		for (i = 0; i < SBP_QUEUE_LEN; i++) {
582			struct sbp_ocb *ocb;
583			ocb = &sdev->ocb[i];
584			ocb->bus_addr = sdev->dma.bus_addr
585				+ SBP_LOGIN_SIZE
586				+ sizeof(struct sbp_ocb) * i
587				+ offsetof(struct sbp_ocb, orb[0]);
588			if (bus_dmamap_create(sbp->dmat, 0, &ocb->dmamap)) {
589				printf("sbp_attach: cannot create dmamap\n");
590				/* XXX */
591				goto next;
592			}
593			sbp_free_ocb(sdev, ocb);
594		}
595next:
596		crom_next(&cc);
597	}
598
599	for (lun = 0; lun < target->num_lun; lun ++) {
600		sdev = target->luns[lun];
601		if (sdev != NULL && (sdev->flags & VALID_LUN) == 0) {
602			sbp_cam_detach_sdev(sdev);
603			sbp_free_sdev(sdev);
604			target->luns[lun] = NULL;
605		}
606	}
607}
608
609static struct sbp_target *
610sbp_alloc_target(struct sbp_softc *sbp, struct fw_device *fwdev)
611{
612	int i;
613	struct sbp_target *target;
614	struct crom_context cc;
615	struct csrreg *reg;
616
617SBP_DEBUG(1)
618	printf("sbp_alloc_target\n");
619END_DEBUG
620	i = sbp_new_target(sbp, fwdev);
621	if (i < 0) {
622		device_printf(sbp->fd.dev, "increase SBP_NUM_TARGETS!\n");
623		return NULL;
624	}
625	/* new target */
626	target = &sbp->targets[i];
627	target->sbp = sbp;
628	target->fwdev = fwdev;
629	target->target_id = i;
630	/* XXX we may want to reload mgm port after each bus reset */
631	/* XXX there might be multiple management agents */
632	crom_init_context(&cc, target->fwdev->csrrom);
633	reg = crom_search_key(&cc, CROM_MGM);
634	if (reg == NULL || reg->val == 0) {
635		printf("NULL management address\n");
636		target->fwdev = NULL;
637		return NULL;
638	}
639	target->mgm_hi = 0xffff;
640	target->mgm_lo = 0xf0000000 | (reg->val << 2);
641	target->mgm_ocb_cur = NULL;
642SBP_DEBUG(1)
643	printf("target:%d mgm_port: %x\n", i, target->mgm_lo);
644END_DEBUG
645	STAILQ_INIT(&target->xferlist);
646	target->n_xfer = 0;
647	STAILQ_INIT(&target->mgm_ocb_queue);
648	CALLOUT_INIT(&target->mgm_ocb_timeout);
649	CALLOUT_INIT(&target->scan_callout);
650
651	target->luns = NULL;
652	target->num_lun = 0;
653	return target;
654}
655
656static void
657sbp_probe_lun(struct sbp_dev *sdev)
658{
659	struct fw_device *fwdev;
660	struct crom_context c, *cc = &c;
661	struct csrreg *reg;
662
663	bzero(sdev->vendor, sizeof(sdev->vendor));
664	bzero(sdev->product, sizeof(sdev->product));
665
666	fwdev = sdev->target->fwdev;
667	crom_init_context(cc, fwdev->csrrom);
668	/* get vendor string */
669	crom_search_key(cc, CSRKEY_VENDOR);
670	crom_next(cc);
671	crom_parse_text(cc, sdev->vendor, sizeof(sdev->vendor));
672	/* skip to the unit directory for SBP-2 */
673	while ((reg = crom_search_key(cc, CSRKEY_VER)) != NULL) {
674		if (reg->val == CSRVAL_T10SBP2)
675			break;
676		crom_next(cc);
677	}
678	/* get firmware revision */
679	reg = crom_search_key(cc, CSRKEY_FIRM_VER);
680	if (reg != NULL)
681		snprintf(sdev->revision, sizeof(sdev->revision),
682						"%06x", reg->val);
683	/* get product string */
684	crom_search_key(cc, CSRKEY_MODEL);
685	crom_next(cc);
686	crom_parse_text(cc, sdev->product, sizeof(sdev->product));
687}
688
689static void
690sbp_login_callout(void *arg)
691{
692	struct sbp_dev *sdev = (struct sbp_dev *)arg;
693	sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
694}
695
696static void
697sbp_login(struct sbp_dev *sdev)
698{
699	struct timeval delta;
700	struct timeval t;
701	int ticks = 0;
702
703	microtime(&delta);
704	timevalsub(&delta, &sdev->target->sbp->last_busreset);
705	t.tv_sec = login_delay / 1000;
706	t.tv_usec = (login_delay % 1000) * 1000;
707	timevalsub(&t, &delta);
708	if (t.tv_sec >= 0 && t.tv_usec > 0)
709		ticks = (t.tv_sec * 1000 + t.tv_usec / 1000) * hz / 1000;
710SBP_DEBUG(0)
711	printf("%s: sec = %jd usec = %ld ticks = %d\n", __func__,
712	    (intmax_t)t.tv_sec, t.tv_usec, ticks);
713END_DEBUG
714	callout_reset(&sdev->login_callout, ticks,
715			sbp_login_callout, (void *)(sdev));
716}
717
718#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
719	&& crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
720
721static void
722sbp_probe_target(void *arg)
723{
724	struct sbp_target *target = (struct sbp_target *)arg;
725	struct sbp_softc *sbp = target->sbp;
726	struct sbp_dev *sdev;
727	int i, alive;
728
729	alive = SBP_FWDEV_ALIVE(target->fwdev);
730SBP_DEBUG(1)
731	device_printf(sbp->fd.dev, "%s %d%salive\n",
732		 __func__, target->target_id,
733		(!alive) ? " not " : "");
734END_DEBUG
735
736	sbp = target->sbp;
737	sbp_alloc_lun(target);
738
739	/* XXX untimeout mgm_ocb and dequeue */
740	for (i=0; i < target->num_lun; i++) {
741		sdev = target->luns[i];
742		if (sdev == NULL)
743			continue;
744		if (alive && (sdev->status != SBP_DEV_DEAD)) {
745			if (sdev->path != NULL) {
746				SBP_LOCK(sbp);
747				xpt_freeze_devq(sdev->path, 1);
748				sdev->freeze ++;
749				SBP_UNLOCK(sbp);
750			}
751			sbp_probe_lun(sdev);
752			sbp_show_sdev_info(sdev);
753
754			sbp_abort_all_ocbs(sdev, CAM_SCSI_BUS_RESET);
755			switch (sdev->status) {
756			case SBP_DEV_RESET:
757				/* new or revived target */
758				if (auto_login)
759					sbp_login(sdev);
760				break;
761			case SBP_DEV_TOATTACH:
762			case SBP_DEV_PROBE:
763			case SBP_DEV_ATTACHED:
764			case SBP_DEV_RETRY:
765			default:
766				sbp_mgm_orb(sdev, ORB_FUN_RCN, NULL);
767				break;
768			}
769		} else {
770			switch (sdev->status) {
771			case SBP_DEV_ATTACHED:
772SBP_DEBUG(0)
773				/* the device has gone */
774				device_printf(sbp->fd.dev, "%s: lost target\n",
775					__func__);
776END_DEBUG
777				if (sdev->path) {
778					SBP_LOCK(sbp);
779					xpt_freeze_devq(sdev->path, 1);
780					sdev->freeze ++;
781					SBP_UNLOCK(sbp);
782				}
783				sdev->status = SBP_DEV_RETRY;
784				sbp_cam_detach_sdev(sdev);
785				sbp_free_sdev(sdev);
786				target->luns[i] = NULL;
787				break;
788			case SBP_DEV_PROBE:
789			case SBP_DEV_TOATTACH:
790				sdev->status = SBP_DEV_RESET;
791				break;
792			case SBP_DEV_RETRY:
793			case SBP_DEV_RESET:
794			case SBP_DEV_DEAD:
795				break;
796			}
797		}
798	}
799}
800
801static void
802sbp_post_busreset(void *arg)
803{
804	struct sbp_softc *sbp;
805
806	sbp = (struct sbp_softc *)arg;
807SBP_DEBUG(0)
808	printf("sbp_post_busreset\n");
809END_DEBUG
810	if ((sbp->sim->flags & SIMQ_FREEZED) == 0) {
811		SBP_LOCK(sbp);
812		xpt_freeze_simq(sbp->sim, /*count*/1);
813		sbp->sim->flags |= SIMQ_FREEZED;
814		SBP_UNLOCK(sbp);
815	}
816	microtime(&sbp->last_busreset);
817}
818
819static void
820sbp_post_explore(void *arg)
821{
822	struct sbp_softc *sbp = (struct sbp_softc *)arg;
823	struct sbp_target *target;
824	struct fw_device *fwdev;
825	int i, alive;
826
827SBP_DEBUG(0)
828	printf("sbp_post_explore (sbp_cold=%d)\n", sbp_cold);
829END_DEBUG
830	/* We need physical access */
831	if (!firewire_phydma_enable)
832		return;
833
834	if (sbp_cold > 0)
835		sbp_cold --;
836
837#if 0
838	/*
839	 * XXX don't let CAM the bus rest.
840	 * CAM tries to do something with freezed (DEV_RETRY) devices.
841	 */
842	xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
843#endif
844
845	/* Garbage Collection */
846	for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
847		target = &sbp->targets[i];
848		STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link)
849			if (target->fwdev == NULL || target->fwdev == fwdev)
850				break;
851		if (fwdev == NULL) {
852			/* device has removed in lower driver */
853			sbp_cam_detach_target(target);
854			sbp_free_target(target);
855		}
856	}
857	/* traverse device list */
858	STAILQ_FOREACH(fwdev, &sbp->fd.fc->devices, link) {
859SBP_DEBUG(0)
860		device_printf(sbp->fd.dev,"%s:: EUI:%08x%08x %s attached, state=%d\n",
861				__func__, fwdev->eui.hi, fwdev->eui.lo,
862				(fwdev->status != FWDEVATTACHED) ? "not" : "",
863				fwdev->status);
864END_DEBUG
865		alive = SBP_FWDEV_ALIVE(fwdev);
866		for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){
867			target = &sbp->targets[i];
868			if(target->fwdev == fwdev ) {
869				/* known target */
870				break;
871			}
872		}
873		if(i == SBP_NUM_TARGETS){
874			if (alive) {
875				/* new target */
876				target = sbp_alloc_target(sbp, fwdev);
877				if (target == NULL)
878					continue;
879			} else {
880				continue;
881			}
882		}
883		sbp_probe_target((void *)target);
884		if (target->num_lun == 0)
885			sbp_free_target(target);
886	}
887	SBP_LOCK(sbp);
888	xpt_release_simq(sbp->sim, /*run queue*/TRUE);
889	sbp->sim->flags &= ~SIMQ_FREEZED;
890	SBP_UNLOCK(sbp);
891}
892
893#if NEED_RESPONSE
894static void
895sbp_loginres_callback(struct fw_xfer *xfer){
896	int s;
897	struct sbp_dev *sdev;
898	sdev = (struct sbp_dev *)xfer->sc;
899SBP_DEBUG(1)
900	device_printf(sdev->target->sbp->fd.dev,"%s\n", __func__);
901END_DEBUG
902	/* recycle */
903	s = splfw();
904	STAILQ_INSERT_TAIL(&sdev->target->sbp->fwb.xferlist, xfer, link);
905	splx(s);
906	return;
907}
908#endif
909
910static __inline void
911sbp_xfer_free(struct fw_xfer *xfer)
912{
913	struct sbp_dev *sdev;
914	int s;
915
916	sdev = (struct sbp_dev *)xfer->sc;
917	fw_xfer_unload(xfer);
918	s = splfw();
919	SBP_LOCK(sdev->target->sbp);
920	STAILQ_INSERT_TAIL(&sdev->target->xferlist, xfer, link);
921	SBP_UNLOCK(sdev->target->sbp);
922	splx(s);
923}
924
925static void
926sbp_reset_start_callback(struct fw_xfer *xfer)
927{
928	struct sbp_dev *tsdev, *sdev = (struct sbp_dev *)xfer->sc;
929	struct sbp_target *target = sdev->target;
930	int i;
931
932	if (xfer->resp != 0) {
933		device_printf(sdev->target->sbp->fd.dev,
934			"%s: %s failed: resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
935	}
936
937	for (i = 0; i < target->num_lun; i++) {
938		tsdev = target->luns[i];
939		if (tsdev != NULL && tsdev->status == SBP_DEV_LOGIN)
940			sbp_login(tsdev);
941	}
942}
943
944static void
945sbp_reset_start(struct sbp_dev *sdev)
946{
947	struct fw_xfer *xfer;
948	struct fw_pkt *fp;
949
950SBP_DEBUG(0)
951	device_printf(sdev->target->sbp->fd.dev,
952			"%s:%s\n", __func__,sdev->bustgtlun);
953END_DEBUG
954
955	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
956	xfer->hand = sbp_reset_start_callback;
957	fp = &xfer->send.hdr;
958	fp->mode.wreqq.dest_hi = 0xffff;
959	fp->mode.wreqq.dest_lo = 0xf0000000 | RESET_START;
960	fp->mode.wreqq.data = htonl(0xf);
961	fw_asyreq(xfer->fc, -1, xfer);
962}
963
964static void
965sbp_mgm_callback(struct fw_xfer *xfer)
966{
967	struct sbp_dev *sdev;
968	int resp;
969
970	sdev = (struct sbp_dev *)xfer->sc;
971
972SBP_DEBUG(1)
973	device_printf(sdev->target->sbp->fd.dev,
974		"%s:%s\n", __func__, sdev->bustgtlun);
975END_DEBUG
976	resp = xfer->resp;
977	sbp_xfer_free(xfer);
978	return;
979}
980
981static struct sbp_dev *
982sbp_next_dev(struct sbp_target *target, int lun)
983{
984	struct sbp_dev **sdevp;
985	int i;
986
987	for (i = lun, sdevp = &target->luns[lun]; i < target->num_lun;
988	    i++, sdevp++)
989		if (*sdevp != NULL && (*sdevp)->status == SBP_DEV_PROBE)
990			return(*sdevp);
991	return(NULL);
992}
993
994#define SCAN_PRI 1
995static void
996sbp_cam_scan_lun(struct cam_periph *periph, union ccb *ccb)
997{
998	struct sbp_target *target;
999	struct sbp_dev *sdev;
1000
1001	sdev = (struct sbp_dev *) ccb->ccb_h.ccb_sdev_ptr;
1002	target = sdev->target;
1003SBP_DEBUG(0)
1004	device_printf(sdev->target->sbp->fd.dev,
1005		"%s:%s\n", __func__, sdev->bustgtlun);
1006END_DEBUG
1007	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1008		sdev->status = SBP_DEV_ATTACHED;
1009	} else {
1010		device_printf(sdev->target->sbp->fd.dev,
1011			"%s:%s failed\n", __func__, sdev->bustgtlun);
1012	}
1013	sdev = sbp_next_dev(target, sdev->lun_id + 1);
1014	if (sdev == NULL) {
1015		free(ccb, M_SBP);
1016		return;
1017	}
1018	/* reuse ccb */
1019	xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1020	ccb->ccb_h.ccb_sdev_ptr = sdev;
1021	xpt_action(ccb);
1022	xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1023	sdev->freeze = 1;
1024}
1025
1026static void
1027sbp_cam_scan_target(void *arg)
1028{
1029	struct sbp_target *target = (struct sbp_target *)arg;
1030	struct sbp_dev *sdev;
1031	union ccb *ccb;
1032
1033	sdev = sbp_next_dev(target, 0);
1034	if (sdev == NULL) {
1035		printf("sbp_cam_scan_target: nothing to do for target%d\n",
1036							target->target_id);
1037		return;
1038	}
1039SBP_DEBUG(0)
1040	device_printf(sdev->target->sbp->fd.dev,
1041		"%s:%s\n", __func__, sdev->bustgtlun);
1042END_DEBUG
1043	ccb = malloc(sizeof(union ccb), M_SBP, M_NOWAIT | M_ZERO);
1044	if (ccb == NULL) {
1045		printf("sbp_cam_scan_target: malloc failed\n");
1046		return;
1047	}
1048	xpt_setup_ccb(&ccb->ccb_h, sdev->path, SCAN_PRI);
1049	ccb->ccb_h.func_code = XPT_SCAN_LUN;
1050	ccb->ccb_h.cbfcnp = sbp_cam_scan_lun;
1051	ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1052	ccb->crcn.flags = CAM_FLAG_NONE;
1053	ccb->ccb_h.ccb_sdev_ptr = sdev;
1054
1055	/* The scan is in progress now. */
1056	SBP_LOCK(target->sbp);
1057	xpt_action(ccb);
1058	xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1059	sdev->freeze = 1;
1060	SBP_UNLOCK(target->sbp);
1061}
1062
1063static __inline void
1064sbp_scan_dev(struct sbp_dev *sdev)
1065{
1066	sdev->status = SBP_DEV_PROBE;
1067	callout_reset(&sdev->target->scan_callout, scan_delay * hz / 1000,
1068			sbp_cam_scan_target, (void *)sdev->target);
1069}
1070
1071static void
1072sbp_do_attach(struct fw_xfer *xfer)
1073{
1074	struct sbp_dev *sdev;
1075	struct sbp_target *target;
1076	struct sbp_softc *sbp;
1077
1078	sdev = (struct sbp_dev *)xfer->sc;
1079	target = sdev->target;
1080	sbp = target->sbp;
1081SBP_DEBUG(0)
1082	device_printf(sdev->target->sbp->fd.dev,
1083		"%s:%s\n", __func__, sdev->bustgtlun);
1084END_DEBUG
1085	sbp_xfer_free(xfer);
1086
1087	if (sdev->path == NULL)
1088		xpt_create_path(&sdev->path, xpt_periph,
1089			cam_sim_path(target->sbp->sim),
1090			target->target_id, sdev->lun_id);
1091
1092	/*
1093	 * Let CAM scan the bus if we are in the boot process.
1094	 * XXX xpt_scan_bus cannot detect LUN larger than 0
1095	 * if LUN 0 doesn't exists.
1096	 */
1097	if (sbp_cold > 0) {
1098		sdev->status = SBP_DEV_ATTACHED;
1099		return;
1100	}
1101
1102	sbp_scan_dev(sdev);
1103	return;
1104}
1105
1106static void
1107sbp_agent_reset_callback(struct fw_xfer *xfer)
1108{
1109	struct sbp_dev *sdev;
1110
1111	sdev = (struct sbp_dev *)xfer->sc;
1112SBP_DEBUG(1)
1113	device_printf(sdev->target->sbp->fd.dev,
1114			"%s:%s\n", __func__, sdev->bustgtlun);
1115END_DEBUG
1116	if (xfer->resp != 0) {
1117		device_printf(sdev->target->sbp->fd.dev,
1118			"%s:%s resp=%d\n", __func__, sdev->bustgtlun, xfer->resp);
1119	}
1120
1121	sbp_xfer_free(xfer);
1122	if (sdev->path) {
1123		SBP_LOCK(sdev->target->sbp);
1124		xpt_release_devq(sdev->path, sdev->freeze, TRUE);
1125		sdev->freeze = 0;
1126		SBP_UNLOCK(sdev->target->sbp);
1127	}
1128}
1129
1130static void
1131sbp_agent_reset(struct sbp_dev *sdev)
1132{
1133	struct fw_xfer *xfer;
1134	struct fw_pkt *fp;
1135
1136SBP_DEBUG(0)
1137	device_printf(sdev->target->sbp->fd.dev,
1138		"%s:%s\n", __func__, sdev->bustgtlun);
1139END_DEBUG
1140	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0x04);
1141	if (xfer == NULL)
1142		return;
1143	if (sdev->status == SBP_DEV_ATTACHED || sdev->status == SBP_DEV_PROBE)
1144		xfer->hand = sbp_agent_reset_callback;
1145	else
1146		xfer->hand = sbp_do_attach;
1147	fp = &xfer->send.hdr;
1148	fp->mode.wreqq.data = htonl(0xf);
1149	fw_asyreq(xfer->fc, -1, xfer);
1150	sbp_abort_all_ocbs(sdev, CAM_BDR_SENT);
1151}
1152
1153static void
1154sbp_busy_timeout_callback(struct fw_xfer *xfer)
1155{
1156	struct sbp_dev *sdev;
1157
1158	sdev = (struct sbp_dev *)xfer->sc;
1159SBP_DEBUG(1)
1160	device_printf(sdev->target->sbp->fd.dev,
1161		"%s:%s\n", __func__, sdev->bustgtlun);
1162END_DEBUG
1163	sbp_xfer_free(xfer);
1164	sbp_agent_reset(sdev);
1165}
1166
1167static void
1168sbp_busy_timeout(struct sbp_dev *sdev)
1169{
1170	struct fw_pkt *fp;
1171	struct fw_xfer *xfer;
1172SBP_DEBUG(0)
1173	device_printf(sdev->target->sbp->fd.dev,
1174		"%s:%s\n", __func__, sdev->bustgtlun);
1175END_DEBUG
1176	xfer = sbp_write_cmd(sdev, FWTCODE_WREQQ, 0);
1177
1178	xfer->hand = sbp_busy_timeout_callback;
1179	fp = &xfer->send.hdr;
1180	fp->mode.wreqq.dest_hi = 0xffff;
1181	fp->mode.wreqq.dest_lo = 0xf0000000 | BUSY_TIMEOUT;
1182	fp->mode.wreqq.data = htonl((1 << (13+12)) | 0xf);
1183	fw_asyreq(xfer->fc, -1, xfer);
1184}
1185
1186static void
1187sbp_orb_pointer_callback(struct fw_xfer *xfer)
1188{
1189	struct sbp_dev *sdev;
1190	sdev = (struct sbp_dev *)xfer->sc;
1191
1192SBP_DEBUG(2)
1193	device_printf(sdev->target->sbp->fd.dev,
1194		"%s:%s\n", __func__, sdev->bustgtlun);
1195END_DEBUG
1196	if (xfer->resp != 0) {
1197		/* XXX */
1198		printf("%s: xfer->resp = %d\n", __func__, xfer->resp);
1199	}
1200	sbp_xfer_free(xfer);
1201
1202	SBP_LOCK(sdev->target->sbp);
1203	sdev->flags &= ~ORB_POINTER_ACTIVE;
1204
1205	if ((sdev->flags & ORB_POINTER_NEED) != 0) {
1206		struct sbp_ocb *ocb;
1207
1208		sdev->flags &= ~ORB_POINTER_NEED;
1209		ocb = STAILQ_FIRST(&sdev->ocbs);
1210		if (ocb != NULL)
1211			sbp_orb_pointer(sdev, ocb);
1212	}
1213	SBP_UNLOCK(sdev->target->sbp);
1214	return;
1215}
1216
1217static void
1218sbp_orb_pointer(struct sbp_dev *sdev, struct sbp_ocb *ocb)
1219{
1220	struct fw_xfer *xfer;
1221	struct fw_pkt *fp;
1222SBP_DEBUG(1)
1223	device_printf(sdev->target->sbp->fd.dev,
1224		"%s:%s 0x%08x\n",
1225		__func__, sdev->bustgtlun,
1226		(uint32_t)ocb->bus_addr);
1227END_DEBUG
1228
1229	mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
1230
1231	if ((sdev->flags & ORB_POINTER_ACTIVE) != 0) {
1232SBP_DEBUG(0)
1233		printf("%s: orb pointer active\n", __func__);
1234END_DEBUG
1235		sdev->flags |= ORB_POINTER_NEED;
1236		return;
1237	}
1238
1239	sdev->flags |= ORB_POINTER_ACTIVE;
1240	xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQB, 0x08);
1241	if (xfer == NULL)
1242		return;
1243	xfer->hand = sbp_orb_pointer_callback;
1244
1245	fp = &xfer->send.hdr;
1246	fp->mode.wreqb.len = 8;
1247	fp->mode.wreqb.extcode = 0;
1248	xfer->send.payload[0] =
1249		htonl(((sdev->target->sbp->fd.fc->nodeid | FWLOCALBUS )<< 16));
1250	xfer->send.payload[1] = htonl((uint32_t)ocb->bus_addr);
1251
1252	/*
1253	 * sbp_xfer_free() will attempt to acquire
1254	 * the SBP lock on entrance.  Also, this removes
1255	 * a LOR between the firewire layer and sbp
1256	 */
1257	SBP_UNLOCK(sdev->target->sbp);
1258	if(fw_asyreq(xfer->fc, -1, xfer) != 0){
1259			sbp_xfer_free(xfer);
1260			ocb->ccb->ccb_h.status = CAM_REQ_INVALID;
1261			xpt_done(ocb->ccb);
1262	}
1263	SBP_LOCK(sdev->target->sbp);
1264}
1265
1266static void
1267sbp_doorbell_callback(struct fw_xfer *xfer)
1268{
1269	struct sbp_dev *sdev;
1270	sdev = (struct sbp_dev *)xfer->sc;
1271
1272SBP_DEBUG(1)
1273	device_printf(sdev->target->sbp->fd.dev,
1274		"%s:%s\n", __func__, sdev->bustgtlun);
1275END_DEBUG
1276	if (xfer->resp != 0) {
1277		/* XXX */
1278		device_printf(sdev->target->sbp->fd.dev,
1279			"%s: xfer->resp = %d\n", __func__, xfer->resp);
1280	}
1281	sbp_xfer_free(xfer);
1282	sdev->flags &= ~ORB_DOORBELL_ACTIVE;
1283	if ((sdev->flags & ORB_DOORBELL_NEED) != 0) {
1284		sdev->flags &= ~ORB_DOORBELL_NEED;
1285		SBP_LOCK(sdev->target->sbp);
1286		sbp_doorbell(sdev);
1287		SBP_UNLOCK(sdev->target->sbp);
1288	}
1289	return;
1290}
1291
1292static void
1293sbp_doorbell(struct sbp_dev *sdev)
1294{
1295	struct fw_xfer *xfer;
1296	struct fw_pkt *fp;
1297SBP_DEBUG(1)
1298	device_printf(sdev->target->sbp->fd.dev,
1299		"%s:%s\n", __func__, sdev->bustgtlun);
1300END_DEBUG
1301
1302	if ((sdev->flags & ORB_DOORBELL_ACTIVE) != 0) {
1303		sdev->flags |= ORB_DOORBELL_NEED;
1304		return;
1305	}
1306	sdev->flags |= ORB_DOORBELL_ACTIVE;
1307	xfer = sbp_write_cmd_locked(sdev, FWTCODE_WREQQ, 0x10);
1308	if (xfer == NULL)
1309		return;
1310	xfer->hand = sbp_doorbell_callback;
1311	fp = &xfer->send.hdr;
1312	fp->mode.wreqq.data = htonl(0xf);
1313	fw_asyreq(xfer->fc, -1, xfer);
1314}
1315
1316static struct fw_xfer *
1317sbp_write_cmd_locked(struct sbp_dev *sdev, int tcode, int offset)
1318{
1319	struct fw_xfer *xfer;
1320	struct fw_pkt *fp;
1321	struct sbp_target *target;
1322	int s, new = 0;
1323
1324	mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
1325
1326	target = sdev->target;
1327	s = splfw();
1328	xfer = STAILQ_FIRST(&target->xferlist);
1329	if (xfer == NULL) {
1330		if (target->n_xfer > 5 /* XXX */) {
1331			printf("sbp: no more xfer for this target\n");
1332			splx(s);
1333			return(NULL);
1334		}
1335		xfer = fw_xfer_alloc_buf(M_SBP, 8, 0);
1336		if(xfer == NULL){
1337			printf("sbp: fw_xfer_alloc_buf failed\n");
1338			splx(s);
1339			return NULL;
1340		}
1341		target->n_xfer ++;
1342		if (debug)
1343			printf("sbp: alloc %d xfer\n", target->n_xfer);
1344		new = 1;
1345	} else {
1346		STAILQ_REMOVE_HEAD(&target->xferlist, link);
1347	}
1348	splx(s);
1349
1350	if (new) {
1351		xfer->recv.pay_len = 0;
1352		xfer->send.spd = min(sdev->target->fwdev->speed, max_speed);
1353		xfer->fc = sdev->target->sbp->fd.fc;
1354	}
1355
1356	if (tcode == FWTCODE_WREQB)
1357		xfer->send.pay_len = 8;
1358	else
1359		xfer->send.pay_len = 0;
1360
1361	xfer->sc = (caddr_t)sdev;
1362	fp = &xfer->send.hdr;
1363	fp->mode.wreqq.dest_hi = sdev->login->cmd_hi;
1364	fp->mode.wreqq.dest_lo = sdev->login->cmd_lo + offset;
1365	fp->mode.wreqq.tlrt = 0;
1366	fp->mode.wreqq.tcode = tcode;
1367	fp->mode.wreqq.pri = 0;
1368	fp->mode.wreqq.dst = FWLOCALBUS | sdev->target->fwdev->dst;
1369
1370	return xfer;
1371
1372}
1373
1374static struct fw_xfer *
1375sbp_write_cmd(struct sbp_dev *sdev, int tcode, int offset)
1376{
1377	struct sbp_softc *sbp = sdev->target->sbp;
1378	struct fw_xfer *xfer;
1379
1380	SBP_LOCK(sbp);
1381	xfer = sbp_write_cmd_locked(sdev, tcode, offset);
1382	SBP_UNLOCK(sbp);
1383
1384	return (xfer);
1385}
1386
1387static void
1388sbp_mgm_orb(struct sbp_dev *sdev, int func, struct sbp_ocb *aocb)
1389{
1390	struct fw_xfer *xfer;
1391	struct fw_pkt *fp;
1392	struct sbp_ocb *ocb;
1393	struct sbp_target *target;
1394	int s, nid;
1395
1396	target = sdev->target;
1397	nid = target->sbp->fd.fc->nodeid | FWLOCALBUS;
1398
1399	s = splfw();
1400	SBP_LOCK(target->sbp);
1401	if (func == ORB_FUN_RUNQUEUE) {
1402		ocb = STAILQ_FIRST(&target->mgm_ocb_queue);
1403		if (target->mgm_ocb_cur != NULL || ocb == NULL) {
1404			SBP_UNLOCK(target->sbp);
1405			splx(s);
1406			return;
1407		}
1408		STAILQ_REMOVE_HEAD(&target->mgm_ocb_queue, ocb);
1409		SBP_UNLOCK(target->sbp);
1410		goto start;
1411	}
1412	if ((ocb = sbp_get_ocb(sdev)) == NULL) {
1413		SBP_UNLOCK(target->sbp);
1414		splx(s);
1415		/* XXX */
1416		return;
1417	}
1418	SBP_UNLOCK(target->sbp);
1419	ocb->flags = OCB_ACT_MGM;
1420	ocb->sdev = sdev;
1421
1422	bzero((void *)ocb->orb, sizeof(ocb->orb));
1423	ocb->orb[6] = htonl((nid << 16) | SBP_BIND_HI);
1424	ocb->orb[7] = htonl(SBP_DEV2ADDR(target->target_id, sdev->lun_id));
1425
1426SBP_DEBUG(0)
1427	device_printf(sdev->target->sbp->fd.dev,
1428		 "%s:%s %s\n",
1429		 __func__,sdev->bustgtlun,
1430		 orb_fun_name[(func>>16)&0xf]);
1431END_DEBUG
1432	switch (func) {
1433	case ORB_FUN_LGI:
1434		ocb->orb[0] = ocb->orb[1] = 0; /* password */
1435		ocb->orb[2] = htonl(nid << 16);
1436		ocb->orb[3] = htonl(sdev->dma.bus_addr);
1437		ocb->orb[4] = htonl(ORB_NOTIFY | sdev->lun_id);
1438		if (ex_login)
1439			ocb->orb[4] |= htonl(ORB_EXV);
1440		ocb->orb[5] = htonl(SBP_LOGIN_SIZE);
1441		fwdma_sync(&sdev->dma, BUS_DMASYNC_PREREAD);
1442		break;
1443	case ORB_FUN_ATA:
1444		ocb->orb[0] = htonl((0 << 16) | 0);
1445		ocb->orb[1] = htonl(aocb->bus_addr & 0xffffffff);
1446		/* fall through */
1447	case ORB_FUN_RCN:
1448	case ORB_FUN_LGO:
1449	case ORB_FUN_LUR:
1450	case ORB_FUN_RST:
1451	case ORB_FUN_ATS:
1452		ocb->orb[4] = htonl(ORB_NOTIFY | func | sdev->login->id);
1453		break;
1454	}
1455
1456	if (target->mgm_ocb_cur != NULL) {
1457		/* there is a standing ORB */
1458		SBP_LOCK(target->sbp);
1459		STAILQ_INSERT_TAIL(&sdev->target->mgm_ocb_queue, ocb, ocb);
1460		SBP_UNLOCK(target->sbp);
1461		splx(s);
1462		return;
1463	}
1464start:
1465	target->mgm_ocb_cur = ocb;
1466	splx(s);
1467
1468	callout_reset(&target->mgm_ocb_timeout, 5*hz,
1469				sbp_mgm_timeout, (caddr_t)ocb);
1470	xfer = sbp_write_cmd(sdev, FWTCODE_WREQB, 0);
1471	if(xfer == NULL){
1472		return;
1473	}
1474	xfer->hand = sbp_mgm_callback;
1475
1476	fp = &xfer->send.hdr;
1477	fp->mode.wreqb.dest_hi = sdev->target->mgm_hi;
1478	fp->mode.wreqb.dest_lo = sdev->target->mgm_lo;
1479	fp->mode.wreqb.len = 8;
1480	fp->mode.wreqb.extcode = 0;
1481	xfer->send.payload[0] = htonl(nid << 16);
1482	xfer->send.payload[1] = htonl(ocb->bus_addr & 0xffffffff);
1483
1484	fw_asyreq(xfer->fc, -1, xfer);
1485}
1486
1487static void
1488sbp_print_scsi_cmd(struct sbp_ocb *ocb)
1489{
1490	struct ccb_scsiio *csio;
1491
1492	csio = &ocb->ccb->csio;
1493	printf("%s:%d:%d XPT_SCSI_IO: "
1494		"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
1495		", flags: 0x%02x, "
1496		"%db cmd/%db data/%db sense\n",
1497		device_get_nameunit(ocb->sdev->target->sbp->fd.dev),
1498		ocb->ccb->ccb_h.target_id, ocb->ccb->ccb_h.target_lun,
1499		csio->cdb_io.cdb_bytes[0],
1500		csio->cdb_io.cdb_bytes[1],
1501		csio->cdb_io.cdb_bytes[2],
1502		csio->cdb_io.cdb_bytes[3],
1503		csio->cdb_io.cdb_bytes[4],
1504		csio->cdb_io.cdb_bytes[5],
1505		csio->cdb_io.cdb_bytes[6],
1506		csio->cdb_io.cdb_bytes[7],
1507		csio->cdb_io.cdb_bytes[8],
1508		csio->cdb_io.cdb_bytes[9],
1509		ocb->ccb->ccb_h.flags & CAM_DIR_MASK,
1510		csio->cdb_len, csio->dxfer_len,
1511		csio->sense_len);
1512}
1513
1514static void
1515sbp_scsi_status(struct sbp_status *sbp_status, struct sbp_ocb *ocb)
1516{
1517	struct sbp_cmd_status *sbp_cmd_status;
1518	struct scsi_sense_data_fixed *sense;
1519
1520	sbp_cmd_status = (struct sbp_cmd_status *)sbp_status->data;
1521	sense = (struct scsi_sense_data_fixed *)&ocb->ccb->csio.sense_data;
1522
1523SBP_DEBUG(0)
1524	sbp_print_scsi_cmd(ocb);
1525	/* XXX need decode status */
1526	printf("%s: SCSI status %x sfmt %x valid %x key %x code %x qlfr %x len %d\n",
1527		ocb->sdev->bustgtlun,
1528		sbp_cmd_status->status,
1529		sbp_cmd_status->sfmt,
1530		sbp_cmd_status->valid,
1531		sbp_cmd_status->s_key,
1532		sbp_cmd_status->s_code,
1533		sbp_cmd_status->s_qlfr,
1534		sbp_status->len);
1535END_DEBUG
1536
1537	switch (sbp_cmd_status->status) {
1538	case SCSI_STATUS_CHECK_COND:
1539	case SCSI_STATUS_BUSY:
1540	case SCSI_STATUS_CMD_TERMINATED:
1541		if(sbp_cmd_status->sfmt == SBP_SFMT_CURR){
1542			sense->error_code = SSD_CURRENT_ERROR;
1543		}else{
1544			sense->error_code = SSD_DEFERRED_ERROR;
1545		}
1546		if(sbp_cmd_status->valid)
1547			sense->error_code |= SSD_ERRCODE_VALID;
1548		sense->flags = sbp_cmd_status->s_key;
1549		if(sbp_cmd_status->mark)
1550			sense->flags |= SSD_FILEMARK;
1551		if(sbp_cmd_status->eom)
1552			sense->flags |= SSD_EOM;
1553		if(sbp_cmd_status->ill_len)
1554			sense->flags |= SSD_ILI;
1555
1556		bcopy(&sbp_cmd_status->info, &sense->info[0], 4);
1557
1558		if (sbp_status->len <= 1)
1559			/* XXX not scsi status. shouldn't be happened */
1560			sense->extra_len = 0;
1561		else if (sbp_status->len <= 4)
1562			/* add_sense_code(_qual), info, cmd_spec_info */
1563			sense->extra_len = 6;
1564		else
1565			/* fru, sense_key_spec */
1566			sense->extra_len = 10;
1567
1568		bcopy(&sbp_cmd_status->cdb, &sense->cmd_spec_info[0], 4);
1569
1570		sense->add_sense_code = sbp_cmd_status->s_code;
1571		sense->add_sense_code_qual = sbp_cmd_status->s_qlfr;
1572		sense->fru = sbp_cmd_status->fru;
1573
1574		bcopy(&sbp_cmd_status->s_keydep[0],
1575		    &sense->sense_key_spec[0], 3);
1576
1577		ocb->ccb->csio.scsi_status = sbp_cmd_status->status;
1578		ocb->ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR
1579							| CAM_AUTOSNS_VALID;
1580/*
1581{
1582		uint8_t j, *tmp;
1583		tmp = sense;
1584		for( j = 0 ; j < 32 ; j+=8){
1585			printf("sense %02x%02x %02x%02x %02x%02x %02x%02x\n",
1586				tmp[j], tmp[j+1], tmp[j+2], tmp[j+3],
1587				tmp[j+4], tmp[j+5], tmp[j+6], tmp[j+7]);
1588		}
1589
1590}
1591*/
1592		break;
1593	default:
1594		device_printf(ocb->sdev->target->sbp->fd.dev,
1595				"%s:%s unknown scsi status 0x%x\n",
1596				__func__, ocb->sdev->bustgtlun,
1597				sbp_cmd_status->status);
1598	}
1599}
1600
1601static void
1602sbp_fix_inq_data(struct sbp_ocb *ocb)
1603{
1604	union ccb *ccb;
1605	struct sbp_dev *sdev;
1606	struct scsi_inquiry_data *inq;
1607
1608	ccb = ocb->ccb;
1609	sdev = ocb->sdev;
1610
1611	if (ccb->csio.cdb_io.cdb_bytes[1] & SI_EVPD)
1612		return;
1613SBP_DEBUG(1)
1614	device_printf(sdev->target->sbp->fd.dev,
1615		"%s:%s\n", __func__, sdev->bustgtlun);
1616END_DEBUG
1617	inq = (struct scsi_inquiry_data *) ccb->csio.data_ptr;
1618	switch (SID_TYPE(inq)) {
1619	case T_DIRECT:
1620#if 0
1621		/*
1622		 * XXX Convert Direct Access device to RBC.
1623		 * I've never seen FireWire DA devices which support READ_6.
1624		 */
1625		if (SID_TYPE(inq) == T_DIRECT)
1626			inq->device |= T_RBC; /*  T_DIRECT == 0 */
1627#endif
1628		/* fall through */
1629	case T_RBC:
1630		/*
1631		 * Override vendor/product/revision information.
1632		 * Some devices sometimes return strange strings.
1633		 */
1634#if 1
1635		bcopy(sdev->vendor, inq->vendor, sizeof(inq->vendor));
1636		bcopy(sdev->product, inq->product, sizeof(inq->product));
1637		bcopy(sdev->revision+2, inq->revision, sizeof(inq->revision));
1638#endif
1639		break;
1640	}
1641	/*
1642	 * Force to enable/disable tagged queuing.
1643	 * XXX CAM also checks SCP_QUEUE_DQUE flag in the control mode page.
1644	 */
1645	if (sbp_tags > 0)
1646		inq->flags |= SID_CmdQue;
1647	else if (sbp_tags < 0)
1648		inq->flags &= ~SID_CmdQue;
1649
1650}
1651
1652static void
1653sbp_recv1(struct fw_xfer *xfer)
1654{
1655	struct fw_pkt *rfp;
1656#if NEED_RESPONSE
1657	struct fw_pkt *sfp;
1658#endif
1659	struct sbp_softc *sbp;
1660	struct sbp_dev *sdev;
1661	struct sbp_ocb *ocb;
1662	struct sbp_login_res *login_res = NULL;
1663	struct sbp_status *sbp_status;
1664	struct sbp_target *target;
1665	int	orb_fun, status_valid0, status_valid, t, l, reset_agent = 0;
1666	uint32_t addr;
1667/*
1668	uint32_t *ld;
1669	ld = xfer->recv.buf;
1670printf("sbp %x %d %d %08x %08x %08x %08x\n",
1671			xfer->resp, xfer->recv.len, xfer->recv.off, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
1672printf("sbp %08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
1673printf("sbp %08x %08x %08x %08x\n", ntohl(ld[8]), ntohl(ld[9]), ntohl(ld[10]), ntohl(ld[11]));
1674*/
1675	sbp = (struct sbp_softc *)xfer->sc;
1676	if (xfer->resp != 0){
1677		printf("sbp_recv: xfer->resp = %d\n", xfer->resp);
1678		goto done0;
1679	}
1680	if (xfer->recv.payload == NULL){
1681		printf("sbp_recv: xfer->recv.payload == NULL\n");
1682		goto done0;
1683	}
1684	rfp = &xfer->recv.hdr;
1685	if(rfp->mode.wreqb.tcode != FWTCODE_WREQB){
1686		printf("sbp_recv: tcode = %d\n", rfp->mode.wreqb.tcode);
1687		goto done0;
1688	}
1689	sbp_status = (struct sbp_status *)xfer->recv.payload;
1690	addr = rfp->mode.wreqb.dest_lo;
1691SBP_DEBUG(2)
1692	printf("received address 0x%x\n", addr);
1693END_DEBUG
1694	t = SBP_ADDR2TRG(addr);
1695	if (t >= SBP_NUM_TARGETS) {
1696		device_printf(sbp->fd.dev,
1697			"sbp_recv1: invalid target %d\n", t);
1698		goto done0;
1699	}
1700	target = &sbp->targets[t];
1701	l = SBP_ADDR2LUN(addr);
1702	if (l >= target->num_lun || target->luns[l] == NULL) {
1703		device_printf(sbp->fd.dev,
1704			"sbp_recv1: invalid lun %d (target=%d)\n", l, t);
1705		goto done0;
1706	}
1707	sdev = target->luns[l];
1708
1709	ocb = NULL;
1710	switch (sbp_status->src) {
1711	case 0:
1712	case 1:
1713		/* check mgm_ocb_cur first */
1714		ocb  = target->mgm_ocb_cur;
1715		if (ocb != NULL) {
1716			if (OCB_MATCH(ocb, sbp_status)) {
1717				callout_stop(&target->mgm_ocb_timeout);
1718				target->mgm_ocb_cur = NULL;
1719				break;
1720			}
1721		}
1722		ocb = sbp_dequeue_ocb(sdev, sbp_status);
1723		if (ocb == NULL) {
1724			device_printf(sdev->target->sbp->fd.dev,
1725#if defined(__DragonFly__) || __FreeBSD_version < 500000
1726				"%s:%s No ocb(%lx) on the queue\n",
1727#else
1728				"%s:%s No ocb(%x) on the queue\n",
1729#endif
1730				__func__,sdev->bustgtlun,
1731				ntohl(sbp_status->orb_lo));
1732		}
1733		break;
1734	case 2:
1735		/* unsolicit */
1736		device_printf(sdev->target->sbp->fd.dev,
1737			"%s:%s unsolicit status received\n",
1738			__func__, sdev->bustgtlun);
1739		break;
1740	default:
1741		device_printf(sdev->target->sbp->fd.dev,
1742			"%s:%s unknown sbp_status->src\n",
1743			__func__, sdev->bustgtlun);
1744	}
1745
1746	status_valid0 = (sbp_status->src < 2
1747			&& sbp_status->resp == ORB_RES_CMPL
1748			&& sbp_status->dead == 0);
1749	status_valid = (status_valid0 && sbp_status->status == 0);
1750
1751	if (!status_valid0 || debug > 2){
1752		int status;
1753SBP_DEBUG(0)
1754		device_printf(sdev->target->sbp->fd.dev,
1755			"%s:%s ORB status src:%x resp:%x dead:%x"
1756#if defined(__DragonFly__) || __FreeBSD_version < 500000
1757				" len:%x stat:%x orb:%x%08lx\n",
1758#else
1759				" len:%x stat:%x orb:%x%08x\n",
1760#endif
1761			__func__, sdev->bustgtlun,
1762			sbp_status->src, sbp_status->resp, sbp_status->dead,
1763			sbp_status->len, sbp_status->status,
1764			ntohs(sbp_status->orb_hi), ntohl(sbp_status->orb_lo));
1765END_DEBUG
1766		device_printf(sdev->target->sbp->fd.dev,
1767				"%s\n", sdev->bustgtlun);
1768		status = sbp_status->status;
1769		switch(sbp_status->resp) {
1770		case 0:
1771			if (status > MAX_ORB_STATUS0)
1772				printf("%s\n", orb_status0[MAX_ORB_STATUS0]);
1773			else
1774				printf("%s\n", orb_status0[status]);
1775			break;
1776		case 1:
1777			printf("Obj: %s, Error: %s\n",
1778				orb_status1_object[(status>>6) & 3],
1779				orb_status1_serial_bus_error[status & 0xf]);
1780			break;
1781		case 2:
1782			printf("Illegal request\n");
1783			break;
1784		case 3:
1785			printf("Vendor dependent\n");
1786			break;
1787		default:
1788			printf("unknown respose code %d\n", sbp_status->resp);
1789		}
1790	}
1791
1792	/* we have to reset the fetch agent if it's dead */
1793	if (sbp_status->dead) {
1794		if (sdev->path) {
1795			SBP_LOCK(sbp);
1796			xpt_freeze_devq(sdev->path, 1);
1797			sdev->freeze ++;
1798			SBP_UNLOCK(sbp);
1799		}
1800		reset_agent = 1;
1801	}
1802
1803	if (ocb == NULL)
1804		goto done;
1805
1806	switch(ntohl(ocb->orb[4]) & ORB_FMT_MSK){
1807	case ORB_FMT_NOP:
1808		break;
1809	case ORB_FMT_VED:
1810		break;
1811	case ORB_FMT_STD:
1812		switch(ocb->flags) {
1813		case OCB_ACT_MGM:
1814			orb_fun = ntohl(ocb->orb[4]) & ORB_FUN_MSK;
1815			reset_agent = 0;
1816			switch(orb_fun) {
1817			case ORB_FUN_LGI:
1818				fwdma_sync(&sdev->dma, BUS_DMASYNC_POSTREAD);
1819				login_res = sdev->login;
1820				login_res->len = ntohs(login_res->len);
1821				login_res->id = ntohs(login_res->id);
1822				login_res->cmd_hi = ntohs(login_res->cmd_hi);
1823				login_res->cmd_lo = ntohl(login_res->cmd_lo);
1824				if (status_valid) {
1825SBP_DEBUG(0)
1826					device_printf(sdev->target->sbp->fd.dev,
1827						"%s:%s login: len %d, ID %d, cmd %08x%08x, recon_hold %d\n",
1828						__func__, sdev->bustgtlun,
1829						login_res->len, login_res->id,
1830						login_res->cmd_hi, login_res->cmd_lo,
1831						ntohs(login_res->recon_hold));
1832END_DEBUG
1833					sbp_busy_timeout(sdev);
1834				} else {
1835					/* forgot logout? */
1836					device_printf(sdev->target->sbp->fd.dev,
1837						"%s:%s login failed\n",
1838						__func__, sdev->bustgtlun);
1839					sdev->status = SBP_DEV_RESET;
1840				}
1841				break;
1842			case ORB_FUN_RCN:
1843				login_res = sdev->login;
1844				if (status_valid) {
1845SBP_DEBUG(0)
1846					device_printf(sdev->target->sbp->fd.dev,
1847						"%s:%s reconnect: len %d, ID %d, cmd %08x%08x\n",
1848						__func__, sdev->bustgtlun,
1849						login_res->len, login_res->id,
1850						login_res->cmd_hi, login_res->cmd_lo);
1851END_DEBUG
1852					if (sdev->status == SBP_DEV_ATTACHED)
1853						sbp_scan_dev(sdev);
1854					else
1855						sbp_agent_reset(sdev);
1856				} else {
1857					/* reconnection hold time exceed? */
1858SBP_DEBUG(0)
1859					device_printf(sdev->target->sbp->fd.dev,
1860						"%s:%s reconnect failed\n",
1861						__func__, sdev->bustgtlun);
1862END_DEBUG
1863					sbp_login(sdev);
1864				}
1865				break;
1866			case ORB_FUN_LGO:
1867				sdev->status = SBP_DEV_RESET;
1868				break;
1869			case ORB_FUN_RST:
1870				sbp_busy_timeout(sdev);
1871				break;
1872			case ORB_FUN_LUR:
1873			case ORB_FUN_ATA:
1874			case ORB_FUN_ATS:
1875				sbp_agent_reset(sdev);
1876				break;
1877			default:
1878				device_printf(sdev->target->sbp->fd.dev,
1879					"%s:%s unknown function %d\n",
1880					__func__, sdev->bustgtlun, orb_fun);
1881				break;
1882			}
1883			sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
1884			break;
1885		case OCB_ACT_CMD:
1886			sdev->timeout = 0;
1887			if(ocb->ccb != NULL){
1888				union ccb *ccb;
1889
1890				ccb = ocb->ccb;
1891				if(sbp_status->len > 1){
1892					sbp_scsi_status(sbp_status, ocb);
1893				}else{
1894					if(sbp_status->resp != ORB_RES_CMPL){
1895						ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1896					}else{
1897						ccb->ccb_h.status = CAM_REQ_CMP;
1898					}
1899				}
1900				/* fix up inq data */
1901				if (ccb->csio.cdb_io.cdb_bytes[0] == INQUIRY)
1902					sbp_fix_inq_data(ocb);
1903				SBP_LOCK(sbp);
1904				xpt_done(ccb);
1905				SBP_UNLOCK(sbp);
1906			}
1907			break;
1908		default:
1909			break;
1910		}
1911	}
1912
1913	if (!use_doorbell)
1914		sbp_free_ocb(sdev, ocb);
1915done:
1916	if (reset_agent)
1917		sbp_agent_reset(sdev);
1918
1919done0:
1920	xfer->recv.pay_len = SBP_RECV_LEN;
1921/* The received packet is usually small enough to be stored within
1922 * the buffer. In that case, the controller return ack_complete and
1923 * no respose is necessary.
1924 *
1925 * XXX fwohci.c and firewire.c should inform event_code such as
1926 * ack_complete or ack_pending to upper driver.
1927 */
1928#if NEED_RESPONSE
1929	xfer->send.off = 0;
1930	sfp = (struct fw_pkt *)xfer->send.buf;
1931	sfp->mode.wres.dst = rfp->mode.wreqb.src;
1932	xfer->dst = sfp->mode.wres.dst;
1933	xfer->spd = min(sdev->target->fwdev->speed, max_speed);
1934	xfer->hand = sbp_loginres_callback;
1935
1936	sfp->mode.wres.tlrt = rfp->mode.wreqb.tlrt;
1937	sfp->mode.wres.tcode = FWTCODE_WRES;
1938	sfp->mode.wres.rtcode = 0;
1939	sfp->mode.wres.pri = 0;
1940
1941	fw_asyreq(xfer->fc, -1, xfer);
1942#else
1943	/* recycle */
1944	/* we don't need a lock here because bottom half is serialized */
1945	STAILQ_INSERT_TAIL(&sbp->fwb.xferlist, xfer, link);
1946#endif
1947
1948	return;
1949
1950}
1951
1952static void
1953sbp_recv(struct fw_xfer *xfer)
1954{
1955	int s;
1956
1957	s = splcam();
1958	sbp_recv1(xfer);
1959	splx(s);
1960}
1961/*
1962 * sbp_attach()
1963 */
1964static int
1965sbp_attach(device_t dev)
1966{
1967	struct sbp_softc *sbp;
1968	struct cam_devq *devq;
1969	struct firewire_comm *fc;
1970	int i, s, error;
1971
1972	if (DFLTPHYS > SBP_MAXPHYS)
1973		device_printf(dev, "Warning, DFLTPHYS(%dKB) is larger than "
1974			"SBP_MAXPHYS(%dKB).\n", DFLTPHYS / 1024,
1975			SBP_MAXPHYS / 1024);
1976
1977	if (!firewire_phydma_enable)
1978		device_printf(dev, "Warning, hw.firewire.phydma_enable must be 1 "
1979			"for SBP over FireWire.\n");
1980SBP_DEBUG(0)
1981	printf("sbp_attach (cold=%d)\n", cold);
1982END_DEBUG
1983
1984	if (cold)
1985		sbp_cold ++;
1986	sbp = ((struct sbp_softc *)device_get_softc(dev));
1987	bzero(sbp, sizeof(struct sbp_softc));
1988	sbp->fd.dev = dev;
1989	sbp->fd.fc = fc = device_get_ivars(dev);
1990	mtx_init(&sbp->mtx, "sbp", NULL, MTX_DEF);
1991
1992	if (max_speed < 0)
1993		max_speed = fc->speed;
1994
1995	error = bus_dma_tag_create(/*parent*/fc->dmat,
1996				/* XXX shoud be 4 for sane backend? */
1997				/*alignment*/1,
1998				/*boundary*/0,
1999				/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
2000				/*highaddr*/BUS_SPACE_MAXADDR,
2001				/*filter*/NULL, /*filterarg*/NULL,
2002				/*maxsize*/0x100000, /*nsegments*/SBP_IND_MAX,
2003				/*maxsegsz*/SBP_SEG_MAX,
2004				/*flags*/BUS_DMA_ALLOCNOW,
2005#if defined(__FreeBSD__) && __FreeBSD_version >= 501102
2006				/*lockfunc*/busdma_lock_mutex,
2007				/*lockarg*/&sbp->mtx,
2008#endif
2009				&sbp->dmat);
2010	if (error != 0) {
2011		printf("sbp_attach: Could not allocate DMA tag "
2012			"- error %d\n", error);
2013			return (ENOMEM);
2014	}
2015
2016	devq = cam_simq_alloc(/*maxopenings*/SBP_NUM_OCB);
2017	if (devq == NULL)
2018		return (ENXIO);
2019
2020	for( i = 0 ; i < SBP_NUM_TARGETS ; i++){
2021		sbp->targets[i].fwdev = NULL;
2022		sbp->targets[i].luns = NULL;
2023	}
2024
2025	sbp->sim = cam_sim_alloc(sbp_action, sbp_poll, "sbp", sbp,
2026				 device_get_unit(dev),
2027				 &sbp->mtx,
2028				 /*untagged*/ 1,
2029				 /*tagged*/ SBP_QUEUE_LEN - 1,
2030				 devq);
2031
2032	if (sbp->sim == NULL) {
2033		cam_simq_free(devq);
2034		return (ENXIO);
2035	}
2036
2037	SBP_LOCK(sbp);
2038	if (xpt_bus_register(sbp->sim, dev, /*bus*/0) != CAM_SUCCESS)
2039		goto fail;
2040
2041	if (xpt_create_path(&sbp->path, xpt_periph, cam_sim_path(sbp->sim),
2042	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2043		xpt_bus_deregister(cam_sim_path(sbp->sim));
2044		goto fail;
2045	}
2046	SBP_UNLOCK(sbp);
2047
2048	/* We reserve 16 bit space (4 bytes X 64 targets X 256 luns) */
2049	sbp->fwb.start = ((u_int64_t)SBP_BIND_HI << 32) | SBP_DEV2ADDR(0, 0);
2050	sbp->fwb.end = sbp->fwb.start + 0xffff;
2051	/* pre-allocate xfer */
2052	STAILQ_INIT(&sbp->fwb.xferlist);
2053	fw_xferlist_add(&sbp->fwb.xferlist, M_SBP,
2054	    /*send*/ 0, /*recv*/ SBP_RECV_LEN, SBP_NUM_OCB/2,
2055	    fc, (void *)sbp, sbp_recv);
2056
2057	fw_bindadd(fc, &sbp->fwb);
2058
2059	sbp->fd.post_busreset = sbp_post_busreset;
2060	sbp->fd.post_explore = sbp_post_explore;
2061
2062	if (fc->status != -1) {
2063		s = splfw();
2064		sbp_post_busreset((void *)sbp);
2065		sbp_post_explore((void *)sbp);
2066		splx(s);
2067	}
2068	SBP_LOCK(sbp);
2069	xpt_async(AC_BUS_RESET, sbp->path, /*arg*/ NULL);
2070	SBP_UNLOCK(sbp);
2071
2072	return (0);
2073fail:
2074	SBP_UNLOCK(sbp);
2075	cam_sim_free(sbp->sim, /*free_devq*/TRUE);
2076	return (ENXIO);
2077}
2078
2079static int
2080sbp_logout_all(struct sbp_softc *sbp)
2081{
2082	struct sbp_target *target;
2083	struct sbp_dev *sdev;
2084	int i, j;
2085
2086SBP_DEBUG(0)
2087	printf("sbp_logout_all\n");
2088END_DEBUG
2089	for (i = 0 ; i < SBP_NUM_TARGETS ; i ++) {
2090		target = &sbp->targets[i];
2091		if (target->luns == NULL)
2092			continue;
2093		for (j = 0; j < target->num_lun; j++) {
2094			sdev = target->luns[j];
2095			if (sdev == NULL)
2096				continue;
2097			callout_stop(&sdev->login_callout);
2098			if (sdev->status >= SBP_DEV_TOATTACH &&
2099					sdev->status <= SBP_DEV_ATTACHED)
2100				sbp_mgm_orb(sdev, ORB_FUN_LGO, NULL);
2101		}
2102	}
2103
2104	return 0;
2105}
2106
2107static int
2108sbp_shutdown(device_t dev)
2109{
2110	struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2111
2112	sbp_logout_all(sbp);
2113	return (0);
2114}
2115
2116static void
2117sbp_free_sdev(struct sbp_dev *sdev)
2118{
2119	int i;
2120
2121	if (sdev == NULL)
2122		return;
2123	for (i = 0; i < SBP_QUEUE_LEN; i++)
2124		bus_dmamap_destroy(sdev->target->sbp->dmat,
2125		    sdev->ocb[i].dmamap);
2126	fwdma_free(sdev->target->sbp->fd.fc, &sdev->dma);
2127	free(sdev, M_SBP);
2128	sdev = NULL;
2129}
2130
2131static void
2132sbp_free_target(struct sbp_target *target)
2133{
2134	struct sbp_softc *sbp;
2135	struct fw_xfer *xfer, *next;
2136	int i;
2137
2138	if (target->luns == NULL)
2139		return;
2140	callout_stop(&target->mgm_ocb_timeout);
2141	sbp = target->sbp;
2142	for (i = 0; i < target->num_lun; i++)
2143		sbp_free_sdev(target->luns[i]);
2144
2145	for (xfer = STAILQ_FIRST(&target->xferlist);
2146			xfer != NULL; xfer = next) {
2147		next = STAILQ_NEXT(xfer, link);
2148		fw_xfer_free_buf(xfer);
2149	}
2150	STAILQ_INIT(&target->xferlist);
2151	free(target->luns, M_SBP);
2152	target->num_lun = 0;
2153	target->luns = NULL;
2154	target->fwdev = NULL;
2155}
2156
2157static int
2158sbp_detach(device_t dev)
2159{
2160	struct sbp_softc *sbp = ((struct sbp_softc *)device_get_softc(dev));
2161	struct firewire_comm *fc = sbp->fd.fc;
2162	int i;
2163
2164SBP_DEBUG(0)
2165	printf("sbp_detach\n");
2166END_DEBUG
2167
2168	for (i = 0; i < SBP_NUM_TARGETS; i ++)
2169		sbp_cam_detach_target(&sbp->targets[i]);
2170
2171	SBP_LOCK(sbp);
2172	xpt_async(AC_LOST_DEVICE, sbp->path, NULL);
2173	xpt_free_path(sbp->path);
2174	xpt_bus_deregister(cam_sim_path(sbp->sim));
2175	cam_sim_free(sbp->sim, /*free_devq*/ TRUE);
2176	SBP_UNLOCK(sbp);
2177
2178	sbp_logout_all(sbp);
2179
2180	/* XXX wait for logout completion */
2181	pause("sbpdtc", hz/2);
2182
2183	for (i = 0 ; i < SBP_NUM_TARGETS ; i ++)
2184		sbp_free_target(&sbp->targets[i]);
2185
2186	fw_bindremove(fc, &sbp->fwb);
2187	fw_xferlist_remove(&sbp->fwb.xferlist);
2188
2189	bus_dma_tag_destroy(sbp->dmat);
2190	mtx_destroy(&sbp->mtx);
2191
2192	return (0);
2193}
2194
2195static void
2196sbp_cam_detach_sdev(struct sbp_dev *sdev)
2197{
2198	if (sdev == NULL)
2199		return;
2200	if (sdev->status == SBP_DEV_DEAD)
2201		return;
2202	if (sdev->status == SBP_DEV_RESET)
2203		return;
2204	sbp_abort_all_ocbs(sdev, CAM_DEV_NOT_THERE);
2205	if (sdev->path) {
2206		SBP_LOCK(sdev->target->sbp);
2207		xpt_release_devq(sdev->path,
2208				 sdev->freeze, TRUE);
2209		sdev->freeze = 0;
2210		xpt_async(AC_LOST_DEVICE, sdev->path, NULL);
2211		xpt_free_path(sdev->path);
2212		sdev->path = NULL;
2213		SBP_UNLOCK(sdev->target->sbp);
2214	}
2215}
2216
2217static void
2218sbp_cam_detach_target(struct sbp_target *target)
2219{
2220	int i;
2221
2222	if (target->luns != NULL) {
2223SBP_DEBUG(0)
2224		printf("sbp_detach_target %d\n", target->target_id);
2225END_DEBUG
2226		callout_stop(&target->scan_callout);
2227		for (i = 0; i < target->num_lun; i++)
2228			sbp_cam_detach_sdev(target->luns[i]);
2229	}
2230}
2231
2232static void
2233sbp_target_reset(struct sbp_dev *sdev, int method)
2234{
2235	int i;
2236	struct sbp_target *target = sdev->target;
2237	struct sbp_dev *tsdev;
2238
2239	for (i = 0; i < target->num_lun; i++) {
2240		tsdev = target->luns[i];
2241		if (tsdev == NULL)
2242			continue;
2243		if (tsdev->status == SBP_DEV_DEAD)
2244			continue;
2245		if (tsdev->status == SBP_DEV_RESET)
2246			continue;
2247		SBP_LOCK(target->sbp);
2248		xpt_freeze_devq(tsdev->path, 1);
2249		tsdev->freeze ++;
2250		SBP_UNLOCK(target->sbp);
2251		sbp_abort_all_ocbs(tsdev, CAM_CMD_TIMEOUT);
2252		if (method == 2)
2253			tsdev->status = SBP_DEV_LOGIN;
2254	}
2255	switch(method) {
2256	case 1:
2257		printf("target reset\n");
2258		sbp_mgm_orb(sdev, ORB_FUN_RST, NULL);
2259		break;
2260	case 2:
2261		printf("reset start\n");
2262		sbp_reset_start(sdev);
2263		break;
2264	}
2265
2266}
2267
2268static void
2269sbp_mgm_timeout(void *arg)
2270{
2271	struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2272	struct sbp_dev *sdev = ocb->sdev;
2273	struct sbp_target *target = sdev->target;
2274
2275	device_printf(sdev->target->sbp->fd.dev,
2276		"%s:%s request timeout(mgm orb:0x%08x)\n",
2277		__func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2278	target->mgm_ocb_cur = NULL;
2279	sbp_free_ocb(sdev, ocb);
2280#if 0
2281	/* XXX */
2282	printf("run next request\n");
2283	sbp_mgm_orb(sdev, ORB_FUN_RUNQUEUE, NULL);
2284#endif
2285	device_printf(sdev->target->sbp->fd.dev,
2286		"%s:%s reset start\n",
2287		__func__, sdev->bustgtlun);
2288	sbp_reset_start(sdev);
2289}
2290
2291static void
2292sbp_timeout(void *arg)
2293{
2294	struct sbp_ocb *ocb = (struct sbp_ocb *)arg;
2295	struct sbp_dev *sdev = ocb->sdev;
2296
2297	device_printf(sdev->target->sbp->fd.dev,
2298		"%s:%s request timeout(cmd orb:0x%08x) ... ",
2299		__func__, sdev->bustgtlun, (uint32_t)ocb->bus_addr);
2300
2301	sdev->timeout ++;
2302	switch(sdev->timeout) {
2303	case 1:
2304		printf("agent reset\n");
2305		SBP_LOCK(sdev->target->sbp);
2306		xpt_freeze_devq(sdev->path, 1);
2307		sdev->freeze ++;
2308		SBP_UNLOCK(sdev->target->sbp);
2309		sbp_abort_all_ocbs(sdev, CAM_CMD_TIMEOUT);
2310		sbp_agent_reset(sdev);
2311		break;
2312	case 2:
2313	case 3:
2314		sbp_target_reset(sdev, sdev->timeout - 1);
2315		break;
2316#if 0
2317	default:
2318		/* XXX give up */
2319		sbp_cam_detach_target(target);
2320		if (target->luns != NULL)
2321			free(target->luns, M_SBP);
2322		target->num_lun = 0;
2323		target->luns = NULL;
2324		target->fwdev = NULL;
2325#endif
2326	}
2327}
2328
2329static void
2330sbp_action1(struct cam_sim *sim, union ccb *ccb)
2331{
2332
2333	struct sbp_softc *sbp = (struct sbp_softc *)sim->softc;
2334	struct sbp_target *target = NULL;
2335	struct sbp_dev *sdev = NULL;
2336
2337	/* target:lun -> sdev mapping */
2338	if (sbp != NULL
2339			&& ccb->ccb_h.target_id != CAM_TARGET_WILDCARD
2340			&& ccb->ccb_h.target_id < SBP_NUM_TARGETS) {
2341		target = &sbp->targets[ccb->ccb_h.target_id];
2342		if (target->fwdev != NULL
2343				&& ccb->ccb_h.target_lun != CAM_LUN_WILDCARD
2344				&& ccb->ccb_h.target_lun < target->num_lun) {
2345			sdev = target->luns[ccb->ccb_h.target_lun];
2346			if (sdev != NULL && sdev->status != SBP_DEV_ATTACHED &&
2347				sdev->status != SBP_DEV_PROBE)
2348				sdev = NULL;
2349		}
2350	}
2351
2352SBP_DEBUG(1)
2353	if (sdev == NULL)
2354		printf("invalid target %d lun %d\n",
2355			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2356END_DEBUG
2357
2358	switch (ccb->ccb_h.func_code) {
2359	case XPT_SCSI_IO:
2360	case XPT_RESET_DEV:
2361	case XPT_GET_TRAN_SETTINGS:
2362	case XPT_SET_TRAN_SETTINGS:
2363	case XPT_CALC_GEOMETRY:
2364		if (sdev == NULL) {
2365SBP_DEBUG(1)
2366			printf("%s:%d:%d:func_code 0x%04x: "
2367				"Invalid target (target needed)\n",
2368				device_get_nameunit(sbp->fd.dev),
2369				ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
2370				ccb->ccb_h.func_code);
2371END_DEBUG
2372
2373			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2374			xpt_done(ccb);
2375			return;
2376		}
2377		break;
2378	case XPT_PATH_INQ:
2379	case XPT_NOOP:
2380		/* The opcodes sometimes aimed at a target (sc is valid),
2381		 * sometimes aimed at the SIM (sc is invalid and target is
2382		 * CAM_TARGET_WILDCARD)
2383		 */
2384		if (sbp == NULL &&
2385			ccb->ccb_h.target_id != CAM_TARGET_WILDCARD) {
2386SBP_DEBUG(0)
2387			printf("%s:%d:%d func_code 0x%04x: "
2388				"Invalid target (no wildcard)\n",
2389				device_get_nameunit(sbp->fd.dev),
2390				ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
2391				ccb->ccb_h.func_code);
2392END_DEBUG
2393			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2394			xpt_done(ccb);
2395			return;
2396		}
2397		break;
2398	default:
2399		/* XXX Hm, we should check the input parameters */
2400		break;
2401	}
2402
2403	switch (ccb->ccb_h.func_code) {
2404	case XPT_SCSI_IO:
2405	{
2406		struct ccb_scsiio *csio;
2407		struct sbp_ocb *ocb;
2408		int speed;
2409		void *cdb;
2410
2411		csio = &ccb->csio;
2412		mtx_assert(sim->mtx, MA_OWNED);
2413
2414SBP_DEBUG(2)
2415		printf("%s:%d:%d XPT_SCSI_IO: "
2416			"cmd: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x"
2417			", flags: 0x%02x, "
2418			"%db cmd/%db data/%db sense\n",
2419			device_get_nameunit(sbp->fd.dev),
2420			ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
2421			csio->cdb_io.cdb_bytes[0],
2422			csio->cdb_io.cdb_bytes[1],
2423			csio->cdb_io.cdb_bytes[2],
2424			csio->cdb_io.cdb_bytes[3],
2425			csio->cdb_io.cdb_bytes[4],
2426			csio->cdb_io.cdb_bytes[5],
2427			csio->cdb_io.cdb_bytes[6],
2428			csio->cdb_io.cdb_bytes[7],
2429			csio->cdb_io.cdb_bytes[8],
2430			csio->cdb_io.cdb_bytes[9],
2431			ccb->ccb_h.flags & CAM_DIR_MASK,
2432			csio->cdb_len, csio->dxfer_len,
2433			csio->sense_len);
2434END_DEBUG
2435		if(sdev == NULL){
2436			ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2437			xpt_done(ccb);
2438			return;
2439		}
2440#if 0
2441		/* if we are in probe stage, pass only probe commands */
2442		if (sdev->status == SBP_DEV_PROBE) {
2443			char *name;
2444			name = xpt_path_periph(ccb->ccb_h.path)->periph_name;
2445			printf("probe stage, periph name: %s\n", name);
2446			if (strcmp(name, "probe") != 0) {
2447				ccb->ccb_h.status = CAM_REQUEUE_REQ;
2448				xpt_done(ccb);
2449				return;
2450			}
2451		}
2452#endif
2453		if ((ocb = sbp_get_ocb(sdev)) == NULL) {
2454			ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
2455			if (sdev->freeze == 0) {
2456				SBP_LOCK(sdev->target->sbp);
2457				xpt_freeze_devq(sdev->path, 1);
2458				sdev->freeze ++;
2459				SBP_UNLOCK(sdev->target->sbp);
2460			}
2461			xpt_done(ccb);
2462			return;
2463		}
2464
2465		ocb->flags = OCB_ACT_CMD;
2466		ocb->sdev = sdev;
2467		ocb->ccb = ccb;
2468		ccb->ccb_h.ccb_sdev_ptr = sdev;
2469		ocb->orb[0] = htonl(1 << 31);
2470		ocb->orb[1] = 0;
2471		ocb->orb[2] = htonl(((sbp->fd.fc->nodeid | FWLOCALBUS )<< 16) );
2472		ocb->orb[3] = htonl(ocb->bus_addr + IND_PTR_OFFSET);
2473		speed = min(target->fwdev->speed, max_speed);
2474		ocb->orb[4] = htonl(ORB_NOTIFY | ORB_CMD_SPD(speed)
2475						| ORB_CMD_MAXP(speed + 7));
2476		if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN){
2477			ocb->orb[4] |= htonl(ORB_CMD_IN);
2478		}
2479
2480		if (csio->ccb_h.flags & CAM_SCATTER_VALID)
2481			printf("sbp: CAM_SCATTER_VALID\n");
2482		if (csio->ccb_h.flags & CAM_DATA_PHYS)
2483			printf("sbp: CAM_DATA_PHYS\n");
2484
2485		if (csio->ccb_h.flags & CAM_CDB_POINTER)
2486			cdb = (void *)csio->cdb_io.cdb_ptr;
2487		else
2488			cdb = (void *)&csio->cdb_io.cdb_bytes;
2489		bcopy(cdb, (void *)&ocb->orb[5], csio->cdb_len);
2490/*
2491printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[0]), ntohl(ocb->orb[1]), ntohl(ocb->orb[2]), ntohl(ocb->orb[3]));
2492printf("ORB %08x %08x %08x %08x\n", ntohl(ocb->orb[4]), ntohl(ocb->orb[5]), ntohl(ocb->orb[6]), ntohl(ocb->orb[7]));
2493*/
2494		if (ccb->csio.dxfer_len > 0) {
2495			int s, error;
2496
2497			s = splsoftvm();
2498			error = bus_dmamap_load(/*dma tag*/sbp->dmat,
2499					/*dma map*/ocb->dmamap,
2500					ccb->csio.data_ptr,
2501					ccb->csio.dxfer_len,
2502					sbp_execute_ocb,
2503					ocb,
2504					/*flags*/0);
2505			splx(s);
2506			if (error)
2507				printf("sbp: bus_dmamap_load error %d\n", error);
2508		} else
2509			sbp_execute_ocb(ocb, NULL, 0, 0);
2510		break;
2511	}
2512	case XPT_CALC_GEOMETRY:
2513	{
2514		struct ccb_calc_geometry *ccg;
2515#if defined(__DragonFly__) || __FreeBSD_version < 501100
2516		uint32_t size_mb;
2517		uint32_t secs_per_cylinder;
2518		int extended = 1;
2519#endif
2520
2521		ccg = &ccb->ccg;
2522		if (ccg->block_size == 0) {
2523			printf("sbp_action1: block_size is 0.\n");
2524			ccb->ccb_h.status = CAM_REQ_INVALID;
2525			xpt_done(ccb);
2526			break;
2527		}
2528SBP_DEBUG(1)
2529		printf("%s:%d:%d:%d:XPT_CALC_GEOMETRY: "
2530#if defined(__DragonFly__) || __FreeBSD_version < 500000
2531			"Volume size = %d\n",
2532#else
2533			"Volume size = %jd\n",
2534#endif
2535			device_get_nameunit(sbp->fd.dev),
2536			cam_sim_path(sbp->sim),
2537			ccb->ccb_h.target_id, ccb->ccb_h.target_lun,
2538#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
2539			(uintmax_t)
2540#endif
2541				ccg->volume_size);
2542END_DEBUG
2543
2544#if defined(__DragonFly__) || __FreeBSD_version < 501100
2545		size_mb = ccg->volume_size
2546			/ ((1024L * 1024L) / ccg->block_size);
2547
2548		if (size_mb > 1024 && extended) {
2549			ccg->heads = 255;
2550			ccg->secs_per_track = 63;
2551		} else {
2552			ccg->heads = 64;
2553			ccg->secs_per_track = 32;
2554		}
2555		secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2556		ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2557		ccb->ccb_h.status = CAM_REQ_CMP;
2558#else
2559		cam_calc_geometry(ccg, /*extended*/1);
2560#endif
2561		xpt_done(ccb);
2562		break;
2563	}
2564	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
2565	{
2566
2567SBP_DEBUG(1)
2568		printf("%s:%d:XPT_RESET_BUS: \n",
2569			device_get_nameunit(sbp->fd.dev), cam_sim_path(sbp->sim));
2570END_DEBUG
2571
2572		ccb->ccb_h.status = CAM_REQ_INVALID;
2573		xpt_done(ccb);
2574		break;
2575	}
2576	case XPT_PATH_INQ:		/* Path routing inquiry */
2577	{
2578		struct ccb_pathinq *cpi = &ccb->cpi;
2579
2580SBP_DEBUG(1)
2581		printf("%s:%d:%d XPT_PATH_INQ:.\n",
2582			device_get_nameunit(sbp->fd.dev),
2583			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2584END_DEBUG
2585		cpi->version_num = 1; /* XXX??? */
2586		cpi->hba_inquiry = PI_TAG_ABLE;
2587		cpi->target_sprt = 0;
2588		cpi->hba_misc = PIM_NOBUSRESET | PIM_NO_6_BYTE;
2589		cpi->hba_eng_cnt = 0;
2590		cpi->max_target = SBP_NUM_TARGETS - 1;
2591		cpi->max_lun = SBP_NUM_LUNS - 1;
2592		cpi->initiator_id = SBP_INITIATOR;
2593		cpi->bus_id = sim->bus_id;
2594		cpi->base_transfer_speed = 400 * 1000 / 8;
2595		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2596		strncpy(cpi->hba_vid, "SBP", HBA_IDLEN);
2597		strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
2598		cpi->unit_number = sim->unit_number;
2599                cpi->transport = XPORT_SPI;	/* XX should have a FireWire */
2600                cpi->transport_version = 2;
2601                cpi->protocol = PROTO_SCSI;
2602                cpi->protocol_version = SCSI_REV_2;
2603
2604		cpi->ccb_h.status = CAM_REQ_CMP;
2605		xpt_done(ccb);
2606		break;
2607	}
2608	case XPT_GET_TRAN_SETTINGS:
2609	{
2610		struct ccb_trans_settings *cts = &ccb->cts;
2611		struct ccb_trans_settings_scsi *scsi =
2612		    &cts->proto_specific.scsi;
2613		struct ccb_trans_settings_spi *spi =
2614		    &cts->xport_specific.spi;
2615
2616		cts->protocol = PROTO_SCSI;
2617		cts->protocol_version = SCSI_REV_2;
2618		cts->transport = XPORT_SPI;	/* should have a FireWire */
2619		cts->transport_version = 2;
2620		spi->valid = CTS_SPI_VALID_DISC;
2621		spi->flags = CTS_SPI_FLAGS_DISC_ENB;
2622		scsi->valid = CTS_SCSI_VALID_TQ;
2623		scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;
2624SBP_DEBUG(1)
2625		printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n",
2626			device_get_nameunit(sbp->fd.dev),
2627			ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
2628END_DEBUG
2629		cts->ccb_h.status = CAM_REQ_CMP;
2630		xpt_done(ccb);
2631		break;
2632	}
2633	case XPT_ABORT:
2634		ccb->ccb_h.status = CAM_UA_ABORT;
2635		xpt_done(ccb);
2636		break;
2637	case XPT_SET_TRAN_SETTINGS:
2638		/* XXX */
2639	default:
2640		ccb->ccb_h.status = CAM_REQ_INVALID;
2641		xpt_done(ccb);
2642		break;
2643	}
2644	return;
2645}
2646
2647static void
2648sbp_action(struct cam_sim *sim, union ccb *ccb)
2649{
2650	int s;
2651
2652	s = splfw();
2653	sbp_action1(sim, ccb);
2654	splx(s);
2655}
2656
2657static void
2658sbp_execute_ocb(void *arg,  bus_dma_segment_t *segments, int seg, int error)
2659{
2660	int i;
2661	struct sbp_ocb *ocb;
2662	struct sbp_ocb *prev;
2663	bus_dma_segment_t *s;
2664
2665	if (error)
2666		printf("sbp_execute_ocb: error=%d\n", error);
2667
2668	ocb = (struct sbp_ocb *)arg;
2669
2670SBP_DEBUG(2)
2671	printf("sbp_execute_ocb: seg %d", seg);
2672	for (i = 0; i < seg; i++)
2673#if defined(__DragonFly__) || __FreeBSD_version < 500000
2674		printf(", %x:%d", segments[i].ds_addr, segments[i].ds_len);
2675#else
2676		printf(", %jx:%jd", (uintmax_t)segments[i].ds_addr,
2677					(uintmax_t)segments[i].ds_len);
2678#endif
2679	printf("\n");
2680END_DEBUG
2681
2682	if (seg == 1) {
2683		/* direct pointer */
2684		s = &segments[0];
2685		if (s->ds_len > SBP_SEG_MAX)
2686			panic("ds_len > SBP_SEG_MAX, fix busdma code");
2687		ocb->orb[3] = htonl(s->ds_addr);
2688		ocb->orb[4] |= htonl(s->ds_len);
2689	} else if(seg > 1) {
2690		/* page table */
2691		for (i = 0; i < seg; i++) {
2692			s = &segments[i];
2693SBP_DEBUG(0)
2694			/* XXX LSI Logic "< 16 byte" bug might be hit */
2695			if (s->ds_len < 16)
2696				printf("sbp_execute_ocb: warning, "
2697#if defined(__DragonFly__) || __FreeBSD_version < 500000
2698					"segment length(%d) is less than 16."
2699#else
2700					"segment length(%zd) is less than 16."
2701#endif
2702					"(seg=%d/%d)\n", (size_t)s->ds_len, i+1, seg);
2703END_DEBUG
2704			if (s->ds_len > SBP_SEG_MAX)
2705				panic("ds_len > SBP_SEG_MAX, fix busdma code");
2706			ocb->ind_ptr[i].hi = htonl(s->ds_len << 16);
2707			ocb->ind_ptr[i].lo = htonl(s->ds_addr);
2708		}
2709		ocb->orb[4] |= htonl(ORB_CMD_PTBL | seg);
2710	}
2711
2712	if (seg > 0)
2713		bus_dmamap_sync(ocb->sdev->target->sbp->dmat, ocb->dmamap,
2714			(ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2715			BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
2716	prev = sbp_enqueue_ocb(ocb->sdev, ocb);
2717	fwdma_sync(&ocb->sdev->dma, BUS_DMASYNC_PREWRITE);
2718	if (use_doorbell) {
2719		if (prev == NULL) {
2720			if (ocb->sdev->last_ocb != NULL)
2721				sbp_doorbell(ocb->sdev);
2722			else
2723				sbp_orb_pointer(ocb->sdev, ocb);
2724		}
2725	} else {
2726		if (prev == NULL || (ocb->sdev->flags & ORB_LINK_DEAD) != 0) {
2727			ocb->sdev->flags &= ~ORB_LINK_DEAD;
2728			sbp_orb_pointer(ocb->sdev, ocb);
2729		}
2730	}
2731}
2732
2733static void
2734sbp_poll(struct cam_sim *sim)
2735{
2736	struct sbp_softc *sbp;
2737	struct firewire_comm *fc;
2738
2739	sbp = (struct sbp_softc *)sim->softc;
2740	fc = sbp->fd.fc;
2741
2742	fc->poll(fc, 0, -1);
2743
2744	return;
2745}
2746
2747static struct sbp_ocb *
2748sbp_dequeue_ocb(struct sbp_dev *sdev, struct sbp_status *sbp_status)
2749{
2750	struct sbp_ocb *ocb;
2751	struct sbp_ocb *next;
2752	int s = splfw(), order = 0;
2753	int flags;
2754
2755SBP_DEBUG(1)
2756	device_printf(sdev->target->sbp->fd.dev,
2757#if defined(__DragonFly__) || __FreeBSD_version < 500000
2758	"%s:%s 0x%08lx src %d\n",
2759#else
2760	"%s:%s 0x%08x src %d\n",
2761#endif
2762	    __func__, sdev->bustgtlun, ntohl(sbp_status->orb_lo), sbp_status->src);
2763END_DEBUG
2764	SBP_LOCK(sdev->target->sbp);
2765	for (ocb = STAILQ_FIRST(&sdev->ocbs); ocb != NULL; ocb = next) {
2766		next = STAILQ_NEXT(ocb, ocb);
2767		flags = ocb->flags;
2768		if (OCB_MATCH(ocb, sbp_status)) {
2769			/* found */
2770			STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb);
2771			if (ocb->ccb != NULL)
2772				untimeout(sbp_timeout, (caddr_t)ocb,
2773						ocb->ccb->ccb_h.timeout_ch);
2774			if (ntohl(ocb->orb[4]) & 0xffff) {
2775				bus_dmamap_sync(sdev->target->sbp->dmat,
2776					ocb->dmamap,
2777					(ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2778					BUS_DMASYNC_POSTREAD :
2779					BUS_DMASYNC_POSTWRITE);
2780				bus_dmamap_unload(sdev->target->sbp->dmat,
2781					ocb->dmamap);
2782			}
2783			if (!use_doorbell) {
2784				if (sbp_status->src == SRC_NO_NEXT) {
2785					if (next != NULL)
2786						sbp_orb_pointer(sdev, next);
2787					else if (order > 0) {
2788						/*
2789						 * Unordered execution
2790						 * We need to send pointer for
2791						 * next ORB
2792						 */
2793						sdev->flags |= ORB_LINK_DEAD;
2794					}
2795				}
2796			} else {
2797				/*
2798				 * XXX this is not correct for unordered
2799				 * execution.
2800				 */
2801				if (sdev->last_ocb != NULL) {
2802					SBP_UNLOCK(sdev->target->sbp);
2803					sbp_free_ocb(sdev, sdev->last_ocb);
2804					SBP_LOCK(sdev->target->sbp);
2805				}
2806				sdev->last_ocb = ocb;
2807				if (next != NULL &&
2808				    sbp_status->src == SRC_NO_NEXT)
2809					sbp_doorbell(sdev);
2810			}
2811			break;
2812		} else
2813			order ++;
2814	}
2815	SBP_UNLOCK(sdev->target->sbp);
2816	splx(s);
2817SBP_DEBUG(0)
2818	if (ocb && order > 0) {
2819		device_printf(sdev->target->sbp->fd.dev,
2820			"%s:%s unordered execution order:%d\n",
2821			__func__, sdev->bustgtlun, order);
2822	}
2823END_DEBUG
2824	return (ocb);
2825}
2826
2827static struct sbp_ocb *
2828sbp_enqueue_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2829{
2830	int s = splfw();
2831	struct sbp_ocb *prev, *prev2;
2832
2833	mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
2834SBP_DEBUG(1)
2835	device_printf(sdev->target->sbp->fd.dev,
2836#if defined(__DragonFly__) || __FreeBSD_version < 500000
2837	"%s:%s 0x%08x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2838#else
2839	"%s:%s 0x%08jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2840#endif
2841END_DEBUG
2842	prev2 = prev = STAILQ_LAST(&sdev->ocbs, sbp_ocb, ocb);
2843	STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb);
2844
2845	if (ocb->ccb != NULL)
2846		ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb,
2847					(ocb->ccb->ccb_h.timeout * hz) / 1000);
2848
2849	if (use_doorbell && prev == NULL)
2850		prev2 = sdev->last_ocb;
2851
2852	if (prev2 != NULL && (ocb->sdev->flags & ORB_LINK_DEAD) == 0) {
2853SBP_DEBUG(1)
2854#if defined(__DragonFly__) || __FreeBSD_version < 500000
2855		printf("linking chain 0x%x -> 0x%x\n",
2856		    prev2->bus_addr, ocb->bus_addr);
2857#else
2858		printf("linking chain 0x%jx -> 0x%jx\n",
2859		    (uintmax_t)prev2->bus_addr, (uintmax_t)ocb->bus_addr);
2860#endif
2861END_DEBUG
2862		/*
2863		 * Suppress compiler optimization so that orb[1] must be written first.
2864		 * XXX We may need an explicit memory barrier for other architectures
2865		 * other than i386/amd64.
2866		 */
2867		*(volatile uint32_t *)&prev2->orb[1] = htonl(ocb->bus_addr);
2868		*(volatile uint32_t *)&prev2->orb[0] = 0;
2869	}
2870	splx(s);
2871
2872	return prev;
2873}
2874
2875static struct sbp_ocb *
2876sbp_get_ocb(struct sbp_dev *sdev)
2877{
2878	struct sbp_ocb *ocb;
2879	int s = splfw();
2880
2881	mtx_assert(&sdev->target->sbp->mtx, MA_OWNED);
2882	ocb = STAILQ_FIRST(&sdev->free_ocbs);
2883	if (ocb == NULL) {
2884		sdev->flags |= ORB_SHORTAGE;
2885		printf("ocb shortage!!!\n");
2886		splx(s);
2887		return NULL;
2888	}
2889	STAILQ_REMOVE_HEAD(&sdev->free_ocbs, ocb);
2890	splx(s);
2891	ocb->ccb = NULL;
2892	return (ocb);
2893}
2894
2895static void
2896sbp_free_ocb(struct sbp_dev *sdev, struct sbp_ocb *ocb)
2897{
2898	ocb->flags = 0;
2899	ocb->ccb = NULL;
2900
2901	SBP_LOCK(sdev->target->sbp);
2902	STAILQ_INSERT_TAIL(&sdev->free_ocbs, ocb, ocb);
2903	if ((sdev->flags & ORB_SHORTAGE) != 0) {
2904		int count;
2905
2906		sdev->flags &= ~ORB_SHORTAGE;
2907		count = sdev->freeze;
2908		sdev->freeze = 0;
2909		xpt_release_devq(sdev->path, count, TRUE);
2910	}
2911	SBP_UNLOCK(sdev->target->sbp);
2912}
2913
2914static void
2915sbp_abort_ocb(struct sbp_ocb *ocb, int status)
2916{
2917	struct sbp_dev *sdev;
2918
2919	sdev = ocb->sdev;
2920SBP_DEBUG(0)
2921	device_printf(sdev->target->sbp->fd.dev,
2922#if defined(__DragonFly__) || __FreeBSD_version < 500000
2923	"%s:%s 0x%x\n", __func__, sdev->bustgtlun, ocb->bus_addr);
2924#else
2925	"%s:%s 0x%jx\n", __func__, sdev->bustgtlun, (uintmax_t)ocb->bus_addr);
2926#endif
2927END_DEBUG
2928SBP_DEBUG(1)
2929	if (ocb->ccb != NULL)
2930		sbp_print_scsi_cmd(ocb);
2931END_DEBUG
2932	if (ntohl(ocb->orb[4]) & 0xffff) {
2933		bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap,
2934			(ntohl(ocb->orb[4]) & ORB_CMD_IN) ?
2935			BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
2936		bus_dmamap_unload(sdev->target->sbp->dmat, ocb->dmamap);
2937	}
2938	if (ocb->ccb != NULL) {
2939		untimeout(sbp_timeout, (caddr_t)ocb,
2940					ocb->ccb->ccb_h.timeout_ch);
2941		ocb->ccb->ccb_h.status = status;
2942		SBP_LOCK(sdev->target->sbp);
2943		xpt_done(ocb->ccb);
2944		SBP_UNLOCK(sdev->target->sbp);
2945	}
2946	sbp_free_ocb(sdev, ocb);
2947}
2948
2949static void
2950sbp_abort_all_ocbs(struct sbp_dev *sdev, int status)
2951{
2952	int s;
2953	struct sbp_ocb *ocb, *next;
2954	STAILQ_HEAD(, sbp_ocb) temp;
2955
2956	s = splfw();
2957
2958	STAILQ_INIT(&temp);
2959	SBP_LOCK(sdev->target->sbp);
2960	STAILQ_CONCAT(&temp, &sdev->ocbs);
2961	STAILQ_INIT(&sdev->ocbs);
2962	SBP_UNLOCK(sdev->target->sbp);
2963
2964	for (ocb = STAILQ_FIRST(&temp); ocb != NULL; ocb = next) {
2965		next = STAILQ_NEXT(ocb, ocb);
2966		sbp_abort_ocb(ocb, status);
2967	}
2968	if (sdev->last_ocb != NULL) {
2969		sbp_free_ocb(sdev, sdev->last_ocb);
2970		sdev->last_ocb = NULL;
2971	}
2972
2973	splx(s);
2974}
2975
2976static devclass_t sbp_devclass;
2977
2978static device_method_t sbp_methods[] = {
2979	/* device interface */
2980	DEVMETHOD(device_identify,	sbp_identify),
2981	DEVMETHOD(device_probe,		sbp_probe),
2982	DEVMETHOD(device_attach,	sbp_attach),
2983	DEVMETHOD(device_detach,	sbp_detach),
2984	DEVMETHOD(device_shutdown,	sbp_shutdown),
2985
2986	{ 0, 0 }
2987};
2988
2989static driver_t sbp_driver = {
2990	"sbp",
2991	sbp_methods,
2992	sizeof(struct sbp_softc),
2993};
2994#ifdef __DragonFly__
2995DECLARE_DUMMY_MODULE(sbp);
2996#endif
2997DRIVER_MODULE(sbp, firewire, sbp_driver, sbp_devclass, 0, 0);
2998MODULE_VERSION(sbp, 1);
2999MODULE_DEPEND(sbp, firewire, 1, 1, 1);
3000MODULE_DEPEND(sbp, cam, 1, 1, 1);
3001