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