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