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