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