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