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