f90b741c0c22a1997e0ed064df0d99bb979d7a73
[dragonfly.git] / sys / bus / firewire / firewire.c
1 /*
2  * Copyright (c) 2003 Hidetoshi Shimokawa
3  * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the acknowledgement as bellow:
16  *
17  *    This product includes software developed by K. Kobayashi and H. Shimokawa
18  *
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
26  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  * 
34  * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.68 2004/01/08 14:58:09 simokawa Exp $
35  * $DragonFly: src/sys/bus/firewire/firewire.c,v 1.5 2004/02/05 13:32:07 joerg Exp $
36  *
37  */
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/types.h>
42
43 #include <sys/kernel.h>
44 #include <sys/malloc.h>
45 #include <sys/conf.h>
46 #include <sys/sysctl.h>
47
48 #if __FreeBSD_version < 500000
49 #include <machine/clock.h>      /* for DELAY() */
50 #endif
51
52 #include <sys/bus.h>            /* used by smbus and newbus */
53 #include <machine/bus.h>
54
55 #ifdef __DragonFly__
56 #include "firewire.h"
57 #include "firewirereg.h"
58 #include "fwmem.h"
59 #include "iec13213.h"
60 #include "iec68113.h"
61 #else
62 #include <dev/firewire/firewire.h>
63 #include <dev/firewire/firewirereg.h>
64 #include <dev/firewire/fwmem.h>
65 #include <dev/firewire/iec13213.h>
66 #include <dev/firewire/iec68113.h>
67 #endif
68
69 struct crom_src_buf {
70         struct crom_src src;
71         struct crom_chunk root;
72         struct crom_chunk vendor;
73         struct crom_chunk hw;
74 };
75
76 int firewire_debug=0, try_bmr=1, hold_count=3;
77 SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0,
78         "FireWire driver debug flag");
79 SYSCTL_NODE(_hw, OID_AUTO, firewire, CTLFLAG_RD, 0, "FireWire Subsystem");
80 SYSCTL_INT(_hw_firewire, OID_AUTO, try_bmr, CTLFLAG_RW, &try_bmr, 0,
81         "Try to be a bus manager");
82 SYSCTL_INT(_hw_firewire, OID_AUTO, hold_count, CTLFLAG_RW, &hold_count, 0,
83         "Number of count of bus resets for removing lost device information");
84
85 MALLOC_DEFINE(M_FW, "firewire", "FireWire");
86 MALLOC_DEFINE(M_FWXFER, "fw_xfer", "XFER/FireWire");
87
88 #define FW_MAXASYRTY 4
89
90 devclass_t firewire_devclass;
91
92 static void firewire_identify   (driver_t *, device_t);
93 static int firewire_probe       (device_t);
94 static int firewire_attach      (device_t);
95 static int firewire_detach      (device_t);
96 static int firewire_resume      (device_t);
97 #if 0
98 static int firewire_shutdown    (device_t);
99 #endif
100 static device_t firewire_add_child   (device_t, int, const char *, int);
101 static void fw_try_bmr (void *);
102 static void fw_try_bmr_callback (struct fw_xfer *);
103 static void fw_asystart (struct fw_xfer *);
104 static int fw_get_tlabel (struct firewire_comm *, struct fw_xfer *);
105 static void fw_bus_probe (struct firewire_comm *);
106 static void fw_bus_explore (struct firewire_comm *);
107 static void fw_bus_explore_callback (struct fw_xfer *);
108 static void fw_attach_dev (struct firewire_comm *);
109 #ifdef FW_VMACCESS
110 static void fw_vmaccess (struct fw_xfer *);
111 #endif
112 struct fw_xfer *asyreqq (struct firewire_comm *, u_int8_t, u_int8_t, u_int8_t,
113         u_int32_t, u_int32_t, void (*)(struct fw_xfer *));
114 static int fw_bmr (struct firewire_comm *);
115
116 static device_method_t firewire_methods[] = {
117         /* Device interface */
118         DEVMETHOD(device_identify,      firewire_identify),
119         DEVMETHOD(device_probe,         firewire_probe),
120         DEVMETHOD(device_attach,        firewire_attach),
121         DEVMETHOD(device_detach,        firewire_detach),
122         DEVMETHOD(device_suspend,       bus_generic_suspend),
123         DEVMETHOD(device_resume,        firewire_resume),
124         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
125
126         /* Bus interface */
127         DEVMETHOD(bus_add_child,        firewire_add_child),
128         DEVMETHOD(bus_print_child,      bus_generic_print_child),
129
130         { 0, 0 }
131 };
132 char *linkspeed[] = {
133         "S100", "S200", "S400", "S800",
134         "S1600", "S3200", "undef", "undef"
135 };
136
137 static char *tcode_str[] = {
138         "WREQQ", "WREQB", "WRES",   "undef",
139         "RREQQ", "RREQB", "RRESQ",  "RRESB",
140         "CYCS",  "LREQ",  "STREAM", "LRES",
141         "undef", "undef", "PHY",    "undef"
142 };
143
144 /* IEEE-1394a Table C-2 Gap count as a function of hops*/
145 #define MAX_GAPHOP 15
146 u_int gap_cnt[] = { 5,  5,  7,  8, 10, 13, 16, 18,
147                    21, 24, 26, 29, 32, 35, 37, 40};
148
149 static driver_t firewire_driver = {
150         "firewire",
151         firewire_methods,
152         sizeof(struct firewire_softc),
153 };
154
155 /*
156  * Lookup fwdev by node id.
157  */
158 struct fw_device *
159 fw_noderesolve_nodeid(struct firewire_comm *fc, int dst)
160 {
161         struct fw_device *fwdev;
162         int s;
163
164         s = splfw();
165         STAILQ_FOREACH(fwdev, &fc->devices, link)
166                 if (fwdev->dst == dst && fwdev->status != FWDEVINVAL)
167                         break;
168         splx(s);
169
170         return fwdev;
171 }
172
173 /*
174  * Lookup fwdev by EUI64.
175  */
176 struct fw_device *
177 fw_noderesolve_eui64(struct firewire_comm *fc, struct fw_eui64 *eui)
178 {
179         struct fw_device *fwdev;
180         int s;
181
182         s = splfw();
183         STAILQ_FOREACH(fwdev, &fc->devices, link)
184                 if (FW_EUI64_EQUAL(fwdev->eui, *eui))
185                         break;
186         splx(s);
187
188         if(fwdev == NULL) return NULL;
189         if(fwdev->status == FWDEVINVAL) return NULL;
190         return fwdev;
191 }
192
193 /*
194  * Async. request procedure for userland application.
195  */
196 int
197 fw_asyreq(struct firewire_comm *fc, int sub, struct fw_xfer *xfer)
198 {
199         int err = 0;
200         struct fw_xferq *xferq;
201         int tl = 0, len;
202         struct fw_pkt *fp;
203         int tcode;
204         struct tcode_info *info;
205
206         if(xfer == NULL) return EINVAL;
207         if(xfer->act.hand == NULL){
208                 printf("act.hand == NULL\n");
209                 return EINVAL;
210         }
211         fp = &xfer->send.hdr;
212
213         tcode = fp->mode.common.tcode & 0xf;
214         info = &fc->tcode[tcode];
215         if (info->flag == 0) {
216                 printf("invalid tcode=%x\n", tcode);
217                 return EINVAL;
218         }
219         if (info->flag & FWTI_REQ)
220                 xferq = fc->atq;
221         else
222                 xferq = fc->ats;
223         len = info->hdr_len;
224         if (xfer->send.pay_len > MAXREC(fc->maxrec)) {
225                 printf("send.pay_len > maxrec\n");
226                 return EINVAL;
227         }
228         if (info->flag & FWTI_BLOCK_STR)
229                 len = fp->mode.stream.len;
230         else if (info->flag & FWTI_BLOCK_ASY)
231                 len = fp->mode.rresb.len;
232         else
233                 len = 0;
234         if (len != xfer->send.pay_len){
235                 printf("len(%d) != send.pay_len(%d) %s(%x)\n",
236                     len, xfer->send.pay_len, tcode_str[tcode], tcode);
237                 return EINVAL; 
238         }
239
240         if(xferq->start == NULL){
241                 printf("xferq->start == NULL\n");
242                 return EINVAL;
243         }
244         if(!(xferq->queued < xferq->maxq)){
245                 device_printf(fc->bdev, "Discard a packet (queued=%d)\n",
246                         xferq->queued);
247                 return EINVAL;
248         }
249
250         microtime(&xfer->tv);
251         if (info->flag & FWTI_TLABEL) {
252                 if((tl = fw_get_tlabel(fc, xfer)) == -1 )
253                         return EIO;
254                 fp->mode.hdr.tlrt = tl << 2;
255         }
256
257         xfer->tl = tl;
258         xfer->resp = 0;
259         xfer->fc = fc;
260         xfer->q = xferq;
261         xfer->retry_req = fw_asybusy;
262
263         fw_asystart(xfer);
264         return err;
265 }
266 /*
267  * Wakeup blocked process.
268  */
269 void
270 fw_asy_callback(struct fw_xfer *xfer){
271         wakeup(xfer);
272         return;
273 }
274 /*
275  * Postpone to later retry.
276  */
277 void fw_asybusy(struct fw_xfer *xfer){
278         printf("fw_asybusy\n");
279 /*
280         xfer->ch =  timeout((timeout_t *)fw_asystart, (void *)xfer, 20000);
281 */
282 #if 0
283         DELAY(20000);
284 #endif
285         fw_asystart(xfer);
286         return;
287 }
288
289 /*
290  * Async. request with given xfer structure.
291  */
292 static void
293 fw_asystart(struct fw_xfer *xfer)
294 {
295         struct firewire_comm *fc = xfer->fc;
296         int s;
297         if(xfer->retry++ >= fc->max_asyretry){
298                 device_printf(fc->bdev, "max_asyretry exceeded\n");
299                 xfer->resp = EBUSY;
300                 xfer->state = FWXF_BUSY;
301                 xfer->act.hand(xfer);
302                 return;
303         }
304 #if 0 /* XXX allow bus explore packets only after bus rest */
305         if (fc->status < FWBUSEXPLORE) {
306                 xfer->resp = EAGAIN;
307                 xfer->state = FWXF_BUSY;
308                 if (xfer->act.hand != NULL)
309                         xfer->act.hand(xfer);
310                 return;
311         }
312 #endif
313         s = splfw();
314         xfer->state = FWXF_INQ;
315         STAILQ_INSERT_TAIL(&xfer->q->q, xfer, link);
316         xfer->q->queued ++;
317         splx(s);
318         /* XXX just queue for mbuf */
319         if (xfer->mbuf == NULL)
320                 xfer->q->start(fc);
321         return;
322 }
323
324 static void
325 firewire_identify(driver_t *driver, device_t parent)
326 {
327         BUS_ADD_CHILD(parent, 0, "firewire", -1);
328 }
329
330 static int
331 firewire_probe(device_t dev)
332 {
333         device_set_desc(dev, "IEEE1394(FireWire) bus");
334         return (0);
335 }
336
337 static void
338 firewire_xfer_timeout(struct firewire_comm *fc)
339 {
340         struct fw_xfer *xfer;
341         struct tlabel *tl;
342         struct timeval tv;
343         struct timeval split_timeout;
344         int i, s;
345
346         split_timeout.tv_sec = 0;
347         split_timeout.tv_usec = 200 * 1000;      /* 200 msec */
348
349         microtime(&tv);
350         timevalsub(&tv, &split_timeout);
351
352         s = splfw();
353         for (i = 0; i < 0x40; i ++) {
354                 while ((tl = STAILQ_FIRST(&fc->tlabels[i])) != NULL) {
355                         xfer = tl->xfer;
356                         if (timevalcmp(&xfer->tv, &tv, >))
357                                 /* the rests are newer than this */
358                                 break;
359                         if (xfer->state == FWXF_START)
360                                 /* not sent yet */
361                                 break;
362                         device_printf(fc->bdev,
363                                 "split transaction timeout dst=0x%x tl=0x%x state=%d\n",
364                                 xfer->send.hdr.mode.hdr.dst, i, xfer->state);
365                         xfer->resp = ETIMEDOUT;
366                         STAILQ_REMOVE_HEAD(&fc->tlabels[i], link);
367                         fw_xfer_done(xfer);
368                 }
369         }
370         splx(s);
371 }
372
373 #define WATCHDOC_HZ 10
374 static void
375 firewire_watchdog(void *arg)
376 {
377         struct firewire_comm *fc;
378         static int watchdoc_clock = 0;
379
380         fc = (struct firewire_comm *)arg;
381
382         /*
383          * At boot stage, the device interrupt is disabled and
384          * We encounter a timeout easily. To avoid this,
385          * ignore clock interrupt for a while.
386          */
387         if (watchdoc_clock > WATCHDOC_HZ * 15) {
388                 firewire_xfer_timeout(fc);
389                 fc->timeout(fc);
390         } else
391                 watchdoc_clock ++;
392
393         callout_reset(&fc->timeout_callout, hz / WATCHDOC_HZ,
394                         (void *)firewire_watchdog, (void *)fc);
395 }
396
397 /*
398  * The attach routine.
399  */
400 static int
401 firewire_attach(device_t dev)
402 {
403         int unit;
404         struct firewire_softc *sc = device_get_softc(dev);
405         device_t pa = device_get_parent(dev);
406         struct firewire_comm *fc;
407
408         fc = (struct firewire_comm *)device_get_softc(pa);
409         sc->fc = fc;
410         fc->status = FWBUSNOTREADY;
411
412         unit = device_get_unit(dev);
413         if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
414
415         fwdev_makedev(sc);
416
417         CALLOUT_INIT(&sc->fc->timeout_callout);
418         CALLOUT_INIT(&sc->fc->bmr_callout);
419         CALLOUT_INIT(&sc->fc->retry_probe_callout);
420         CALLOUT_INIT(&sc->fc->busprobe_callout);
421
422         callout_reset(&sc->fc->timeout_callout, hz,
423                         (void *)firewire_watchdog, (void *)sc->fc);
424
425         /* Locate our children */
426         bus_generic_probe(dev);
427
428         /* launch attachement of the added children */
429         bus_generic_attach(dev);
430
431         /* bus_reset */
432         fw_busreset(fc);
433         fc->ibr(fc);
434
435         return 0;
436 }
437
438 /*
439  * Attach it as child.
440  */
441 static device_t
442 firewire_add_child(device_t dev, int order, const char *name, int unit)
443 {
444         device_t child;
445         struct firewire_softc *sc;
446
447         sc = (struct firewire_softc *)device_get_softc(dev);
448         child = device_add_child(dev, name, unit);
449         if (child) {
450                 device_set_ivars(child, sc->fc);
451                 device_probe_and_attach(child);
452         }
453
454         return child;
455 }
456
457 static int
458 firewire_resume(device_t dev)
459 {
460         struct firewire_softc *sc;
461
462         sc = (struct firewire_softc *)device_get_softc(dev);
463         sc->fc->status = FWBUSNOTREADY;
464         
465         bus_generic_resume(dev);
466
467         return(0);
468 }
469
470 /*
471  * Dettach it.
472  */
473 static int
474 firewire_detach(device_t dev)
475 {
476         struct firewire_softc *sc;
477         struct csrdir *csrd, *next;
478         struct fw_device *fwdev, *fwdev_next;
479         int err;
480
481         sc = (struct firewire_softc *)device_get_softc(dev);
482         if ((err = fwdev_destroydev(sc)) != 0)
483                 return err;
484
485         if ((err = bus_generic_detach(dev)) != 0)
486                 return err;
487
488         callout_stop(&sc->fc->timeout_callout);
489         callout_stop(&sc->fc->bmr_callout);
490         callout_stop(&sc->fc->retry_probe_callout);
491         callout_stop(&sc->fc->busprobe_callout);
492
493         /* XXX xfree_free and untimeout on all xfers */
494         for (fwdev = STAILQ_FIRST(&sc->fc->devices); fwdev != NULL;
495                                                         fwdev = fwdev_next) {
496                 fwdev_next = STAILQ_NEXT(fwdev, link);
497                 free(fwdev, M_FW);
498         }
499         for (csrd = SLIST_FIRST(&sc->fc->csrfree); csrd != NULL; csrd = next) {
500                 next = SLIST_NEXT(csrd, link);
501                 free(csrd, M_FW);
502         }
503         free(sc->fc->topology_map, M_FW);
504         free(sc->fc->speed_map, M_FW);
505         free(sc->fc->crom_src_buf, M_FW);
506         return(0);
507 }
508 #if 0
509 static int
510 firewire_shutdown( device_t dev )
511 {
512         return 0;
513 }
514 #endif
515
516
517 static void
518 fw_xferq_drain(struct fw_xferq *xferq)
519 {
520         struct fw_xfer *xfer;
521
522         while ((xfer = STAILQ_FIRST(&xferq->q)) != NULL) {
523                 STAILQ_REMOVE_HEAD(&xferq->q, link);
524                 xferq->queued --;
525                 xfer->resp = EAGAIN;
526                 fw_xfer_done(xfer);
527         }
528 }
529
530 void
531 fw_drain_txq(struct firewire_comm *fc)
532 {
533         int i;
534
535         fw_xferq_drain(fc->atq);
536         fw_xferq_drain(fc->ats);
537         for(i = 0; i < fc->nisodma; i++)
538                 fw_xferq_drain(fc->it[i]);
539 }
540
541 static void
542 fw_reset_csr(struct firewire_comm *fc)
543 {
544         int i;
545
546         CSRARC(fc, STATE_CLEAR)
547                         = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
548         CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
549         CSRARC(fc, NODE_IDS) = 0x3f;
550
551         CSRARC(fc, TOPO_MAP + 8) = 0;
552         fc->irm = -1;
553
554         fc->max_node = -1;
555
556         for(i = 2; i < 0x100/4 - 2 ; i++){
557                 CSRARC(fc, SPED_MAP + i * 4) = 0;
558         }
559         CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ;
560         CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
561         CSRARC(fc, RESET_START) = 0;
562         CSRARC(fc, SPLIT_TIMEOUT_HI) = 0;
563         CSRARC(fc, SPLIT_TIMEOUT_LO) = 800 << 19;
564         CSRARC(fc, CYCLE_TIME) = 0x0;
565         CSRARC(fc, BUS_TIME) = 0x0;
566         CSRARC(fc, BUS_MGR_ID) = 0x3f;
567         CSRARC(fc, BANDWIDTH_AV) = 4915;
568         CSRARC(fc, CHANNELS_AV_HI) = 0xffffffff;
569         CSRARC(fc, CHANNELS_AV_LO) = 0xffffffff;
570         CSRARC(fc, IP_CHANNELS) = (1 << 31);
571
572         CSRARC(fc, CONF_ROM) = 0x04 << 24;
573         CSRARC(fc, CONF_ROM + 4) = 0x31333934; /* means strings 1394 */
574         CSRARC(fc, CONF_ROM + 8) = 1 << 31 | 1 << 30 | 1 << 29 |
575                                 1 << 28 | 0xff << 16 | 0x09 << 8;
576         CSRARC(fc, CONF_ROM + 0xc) = 0;
577
578 /* DV depend CSRs see blue book */
579         CSRARC(fc, oPCR) &= ~DV_BROADCAST_ON; 
580         CSRARC(fc, iPCR) &= ~DV_BROADCAST_ON; 
581
582         CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 );
583         CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR);
584 }
585
586 static void
587 fw_init_crom(struct firewire_comm *fc)
588 {
589         struct crom_src *src;
590
591         fc->crom_src_buf = (struct crom_src_buf *)
592                 malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO);
593         if (fc->crom_src_buf == NULL)
594                 return;
595
596         src = &fc->crom_src_buf->src;
597         bzero(src, sizeof(struct crom_src));
598
599         /* BUS info sample */
600         src->hdr.info_len = 4;
601
602         src->businfo.bus_name = CSR_BUS_NAME_IEEE1394;
603
604         src->businfo.irmc = 1;
605         src->businfo.cmc = 1;
606         src->businfo.isc = 1;
607         src->businfo.bmc = 1;
608         src->businfo.pmc = 0;
609         src->businfo.cyc_clk_acc = 100;
610         src->businfo.max_rec = fc->maxrec;
611         src->businfo.max_rom = MAXROM_4;
612         src->businfo.generation = 1;
613         src->businfo.link_spd = fc->speed;
614
615         src->businfo.eui64.hi = fc->eui.hi;
616         src->businfo.eui64.lo = fc->eui.lo;
617
618         STAILQ_INIT(&src->chunk_list);
619
620         fc->crom_src = src;
621         fc->crom_root = &fc->crom_src_buf->root;
622 }
623
624 static void
625 fw_reset_crom(struct firewire_comm *fc)
626 {
627         struct crom_src_buf *buf;
628         struct crom_src *src;
629         struct crom_chunk *root;
630
631         if (fc->crom_src_buf == NULL)
632                 fw_init_crom(fc);
633
634         buf =  fc->crom_src_buf;
635         src = fc->crom_src;
636         root = fc->crom_root;
637
638         STAILQ_INIT(&src->chunk_list);
639
640         bzero(root, sizeof(struct crom_chunk));
641         crom_add_chunk(src, NULL, root, 0);
642         crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */
643         /* private company_id */
644         crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE);
645         crom_add_simple_text(src, root, &buf->vendor, "FreeBSD Project");
646         crom_add_entry(root, CSRKEY_HW, __FreeBSD_version);
647         crom_add_simple_text(src, root, &buf->hw, hostname);
648 }
649
650 /*
651  * Called after bus reset.
652  */
653 void
654 fw_busreset(struct firewire_comm *fc)
655 {
656         struct firewire_dev_comm *fdc;
657         struct crom_src *src;
658         device_t *devlistp;
659         void *newrom;
660         int i, devcnt;
661
662         switch(fc->status){
663         case FWBUSMGRELECT:
664                 callout_stop(&fc->bmr_callout);
665                 break;
666         default:
667                 break;
668         }
669         fc->status = FWBUSRESET;
670         fw_reset_csr(fc);
671         fw_reset_crom(fc);
672
673         if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) {
674                 for( i = 0 ; i < devcnt ; i++)
675                         if (device_get_state(devlistp[i]) >= DS_ATTACHED)  {
676                                 fdc = device_get_softc(devlistp[i]);
677                                 if (fdc->post_busreset != NULL)
678                                         fdc->post_busreset(fdc);
679                         }
680                 free(devlistp, M_TEMP);
681         }
682
683         newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO);
684         src = &fc->crom_src_buf->src;
685         crom_load(src, (u_int32_t *)newrom, CROMSIZE);
686         if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
687                 /* bump generation and reload */
688                 src->businfo.generation ++;
689                 /* generation must be between 0x2 and 0xF */
690                 if (src->businfo.generation < 2)
691                         src->businfo.generation ++;
692                 crom_load(src, (u_int32_t *)newrom, CROMSIZE);
693                 bcopy(newrom, (void *)fc->config_rom, CROMSIZE);
694         }
695         free(newrom, M_FW);
696 }
697
698 /* Call once after reboot */
699 void fw_init(struct firewire_comm *fc)
700 {
701         int i;
702         struct csrdir *csrd;
703 #ifdef FW_VMACCESS
704         struct fw_xfer *xfer;
705         struct fw_bind *fwb;
706 #endif
707
708         fc->max_asyretry = FW_MAXASYRTY;
709
710         fc->arq->queued = 0;
711         fc->ars->queued = 0;
712         fc->atq->queued = 0;
713         fc->ats->queued = 0;
714
715         fc->arq->buf = NULL;
716         fc->ars->buf = NULL;
717         fc->atq->buf = NULL;
718         fc->ats->buf = NULL;
719
720         fc->arq->flag = 0;
721         fc->ars->flag = 0;
722         fc->atq->flag = 0;
723         fc->ats->flag = 0;
724
725         STAILQ_INIT(&fc->atq->q);
726         STAILQ_INIT(&fc->ats->q);
727
728         for( i = 0 ; i < fc->nisodma ; i ++ ){
729                 fc->it[i]->queued = 0;
730                 fc->ir[i]->queued = 0;
731
732                 fc->it[i]->start = NULL;
733                 fc->ir[i]->start = NULL;
734
735                 fc->it[i]->buf = NULL;
736                 fc->ir[i]->buf = NULL;
737
738                 fc->it[i]->flag = FWXFERQ_STREAM;
739                 fc->ir[i]->flag = FWXFERQ_STREAM;
740
741                 STAILQ_INIT(&fc->it[i]->q);
742                 STAILQ_INIT(&fc->ir[i]->q);
743
744                 STAILQ_INIT(&fc->it[i]->binds);
745                 STAILQ_INIT(&fc->ir[i]->binds);
746         }
747
748         fc->arq->maxq = FWMAXQUEUE;
749         fc->ars->maxq = FWMAXQUEUE;
750         fc->atq->maxq = FWMAXQUEUE;
751         fc->ats->maxq = FWMAXQUEUE;
752
753         for( i = 0 ; i < fc->nisodma ; i++){
754                 fc->ir[i]->maxq = FWMAXQUEUE;
755                 fc->it[i]->maxq = FWMAXQUEUE;
756         }
757 /* Initialize csr registers */
758         fc->topology_map = (struct fw_topology_map *)malloc(
759                                 sizeof(struct fw_topology_map),
760                                 M_FW, M_NOWAIT | M_ZERO);
761         fc->speed_map = (struct fw_speed_map *)malloc(
762                                 sizeof(struct fw_speed_map),
763                                 M_FW, M_NOWAIT | M_ZERO);
764         CSRARC(fc, TOPO_MAP) = 0x3f1 << 16;
765         CSRARC(fc, TOPO_MAP + 4) = 1;
766         CSRARC(fc, SPED_MAP) = 0x3f1 << 16;
767         CSRARC(fc, SPED_MAP + 4) = 1;
768
769         STAILQ_INIT(&fc->devices);
770
771 /* Initialize csr ROM work space */
772         SLIST_INIT(&fc->ongocsr);
773         SLIST_INIT(&fc->csrfree);
774         for( i = 0 ; i < FWMAXCSRDIR ; i++){
775                 csrd = (struct csrdir *) malloc(sizeof(struct csrdir), M_FW,M_NOWAIT);
776                 if(csrd == NULL) break;
777                 SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
778         }
779
780 /* Initialize Async handlers */
781         STAILQ_INIT(&fc->binds);
782         for( i = 0 ; i < 0x40 ; i++){
783                 STAILQ_INIT(&fc->tlabels[i]);
784         }
785
786 /* DV depend CSRs see blue book */
787 #if 0
788         CSRARC(fc, oMPR) = 0x3fff0001; /* # output channel = 1 */
789         CSRARC(fc, oPCR) = 0x8000007a;
790         for(i = 4 ; i < 0x7c/4 ; i+=4){
791                 CSRARC(fc, i + oPCR) = 0x8000007a; 
792         }
793  
794         CSRARC(fc, iMPR) = 0x00ff0001; /* # input channel = 1 */
795         CSRARC(fc, iPCR) = 0x803f0000;
796         for(i = 4 ; i < 0x7c/4 ; i+=4){
797                 CSRARC(fc, i + iPCR) = 0x0; 
798         }
799 #endif
800
801         fc->crom_src_buf = NULL;
802
803 #ifdef FW_VMACCESS
804         xfer = fw_xfer_alloc();
805         if(xfer == NULL) return;
806
807         fwb = (struct fw_bind *)malloc(sizeof (struct fw_bind), M_FW, M_NOWAIT);
808         if(fwb == NULL){
809                 fw_xfer_free(xfer);
810         }
811         xfer->act.hand = fw_vmaccess;
812         xfer->fc = fc;
813         xfer->sc = NULL;
814
815         fwb->start_hi = 0x2;
816         fwb->start_lo = 0;
817         fwb->addrlen = 0xffffffff;
818         fwb->xfer = xfer;
819         fw_bindadd(fc, fwb);
820 #endif
821 }
822
823 #define BIND_CMP(addr, fwb) (((addr) < (fwb)->start)?-1:\
824     ((fwb)->end < (addr))?1:0)
825
826 /*
827  * To lookup binded process from IEEE1394 address.
828  */
829 struct fw_bind *
830 fw_bindlookup(struct firewire_comm *fc, u_int16_t dest_hi, u_int32_t dest_lo)
831 {
832         u_int64_t addr;
833         struct fw_bind *tfw;
834
835         addr = ((u_int64_t)dest_hi << 32) | dest_lo;
836         STAILQ_FOREACH(tfw, &fc->binds, fclist)
837                 if (tfw->act_type != FWACT_NULL && BIND_CMP(addr, tfw) == 0)
838                         return(tfw);
839         return(NULL);
840 }
841
842 /*
843  * To bind IEEE1394 address block to process.
844  */
845 int
846 fw_bindadd(struct firewire_comm *fc, struct fw_bind *fwb)
847 {
848         struct fw_bind *tfw, *prev = NULL;
849
850         if (fwb->start > fwb->end) {
851                 printf("%s: invalid range\n", __FUNCTION__);
852                 return EINVAL;
853         }
854
855         STAILQ_FOREACH(tfw, &fc->binds, fclist) {
856                 if (fwb->end < tfw->start)
857                         break;
858                 prev = tfw;
859         }
860         if (prev == NULL) {
861                 STAILQ_INSERT_HEAD(&fc->binds, fwb, fclist);
862                 goto out;
863         }
864         if (prev->end < fwb->start) {
865                 STAILQ_INSERT_AFTER(&fc->binds, prev, fwb, fclist);
866                 goto out;
867         }
868
869         printf("%s: bind failed\n", __FUNCTION__);
870         return (EBUSY);
871
872 out:
873         if (fwb->act_type == FWACT_CH)
874                 STAILQ_INSERT_HEAD(&fc->ir[fwb->sub]->binds, fwb, chlist);
875         return (0);
876 }
877
878 /*
879  * To free IEEE1394 address block.
880  */
881 int
882 fw_bindremove(struct firewire_comm *fc, struct fw_bind *fwb)
883 {
884 #if 0
885         struct fw_xfer *xfer, *next;
886 #endif
887         struct fw_bind *tfw;
888         int s;
889
890         s = splfw();
891         STAILQ_FOREACH(tfw, &fc->binds, fclist)
892                 if (tfw == fwb) {
893                         STAILQ_REMOVE(&fc->binds, fwb, fw_bind, fclist);
894                         goto found;
895                 }
896
897         printf("%s: no such bind\n", __FUNCTION__);
898         splx(s);
899         return (1);
900 found:
901 #if 0
902         /* shall we do this? */
903         for (xfer = STAILQ_FIRST(&fwb->xferlist); xfer != NULL; xfer = next) {
904                 next = STAILQ_NEXT(xfer, link);
905                 fw_xfer_free(xfer);
906         }
907         STAILQ_INIT(&fwb->xferlist);
908 #endif
909
910         splx(s);
911         return 0;
912 }
913
914 /*
915  * To free transaction label.
916  */
917 static void
918 fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
919 {
920         struct tlabel *tl;
921         int s = splfw();
922
923         for( tl = STAILQ_FIRST(&fc->tlabels[xfer->tl]); tl != NULL;
924                 tl = STAILQ_NEXT(tl, link)){
925                 if(tl->xfer == xfer){
926                         STAILQ_REMOVE(&fc->tlabels[xfer->tl], tl, tlabel, link);
927                         free(tl, M_FW);
928                         splx(s);
929                         return;
930                 }
931         }
932         splx(s);
933         return;
934 }
935
936 /*
937  * To obtain XFER structure by transaction label.
938  */
939 static struct fw_xfer *
940 fw_tl2xfer(struct firewire_comm *fc, int node, int tlabel)
941 {
942         struct fw_xfer *xfer;
943         struct tlabel *tl;
944         int s = splfw();
945
946         for( tl = STAILQ_FIRST(&fc->tlabels[tlabel]); tl != NULL;
947                 tl = STAILQ_NEXT(tl, link)){
948                 if(tl->xfer->send.hdr.mode.hdr.dst == node){
949                         xfer = tl->xfer;
950                         splx(s);
951                         if (firewire_debug > 2)
952                                 printf("fw_tl2xfer: found tl=%d\n", tlabel);
953                         return(xfer);
954                 }
955         }
956         if (firewire_debug > 1)
957                 printf("fw_tl2xfer: not found tl=%d\n", tlabel);
958         splx(s);
959         return(NULL);
960 }
961
962 /*
963  * To allocate IEEE1394 XFER structure.
964  */
965 struct fw_xfer *
966 fw_xfer_alloc(struct malloc_type *type)
967 {
968         struct fw_xfer *xfer;
969
970         xfer = malloc(sizeof(struct fw_xfer), type, M_NOWAIT | M_ZERO);
971         if (xfer == NULL)
972                 return xfer;
973
974         xfer->malloc = type;
975
976         return xfer;
977 }
978
979 struct fw_xfer *
980 fw_xfer_alloc_buf(struct malloc_type *type, int send_len, int recv_len)
981 {
982         struct fw_xfer *xfer;
983
984         xfer = fw_xfer_alloc(type);
985         xfer->send.pay_len = send_len;
986         xfer->recv.pay_len = recv_len;
987         if (xfer == NULL)
988                 return(NULL);
989         if (send_len > 0) {
990                 xfer->send.payload = malloc(send_len, type, M_NOWAIT | M_ZERO);
991                 if (xfer->send.payload == NULL) {
992                         fw_xfer_free(xfer);
993                         return(NULL);
994                 }
995         }
996         if (recv_len > 0) {
997                 xfer->recv.payload = malloc(recv_len, type, M_NOWAIT);
998                 if (xfer->recv.payload == NULL) {
999                         if (xfer->send.payload != NULL)
1000                                 free(xfer->send.payload, type);
1001                         fw_xfer_free(xfer);
1002                         return(NULL);
1003                 }
1004         }
1005         return(xfer);
1006 }
1007
1008 /*
1009  * IEEE1394 XFER post process.
1010  */
1011 void
1012 fw_xfer_done(struct fw_xfer *xfer)
1013 {
1014         if (xfer->act.hand == NULL) {
1015                 printf("act.hand == NULL\n");
1016                 return;
1017         }
1018
1019         if (xfer->fc == NULL)
1020                 panic("fw_xfer_done: why xfer->fc is NULL?");
1021
1022         xfer->act.hand(xfer);
1023 }
1024
1025 void
1026 fw_xfer_unload(struct fw_xfer* xfer)
1027 {
1028         int s;
1029
1030         if(xfer == NULL ) return;
1031         if(xfer->state == FWXF_INQ){
1032                 printf("fw_xfer_free FWXF_INQ\n");
1033                 s = splfw();
1034                 STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
1035                 xfer->q->queued --;
1036                 splx(s);
1037         }
1038         if (xfer->fc != NULL) {
1039 #if 1
1040                 if(xfer->state == FWXF_START)
1041                         /*
1042                          * This could happen if:
1043                          *  1. We call fwohci_arcv() before fwohci_txd().
1044                          *  2. firewire_watch() is called.
1045                          */
1046                         printf("fw_xfer_free FWXF_START\n");
1047 #endif
1048                 fw_tl_free(xfer->fc, xfer);
1049         }
1050         xfer->state = FWXF_INIT;
1051         xfer->resp = 0;
1052         xfer->retry = 0;
1053 }
1054 /*
1055  * To free IEEE1394 XFER structure. 
1056  */
1057 void
1058 fw_xfer_free_buf( struct fw_xfer* xfer)
1059 {
1060         if (xfer == NULL) {
1061                 printf("%s: xfer == NULL\n", __FUNCTION__);
1062                 return;
1063         }
1064         fw_xfer_unload(xfer);
1065         if(xfer->send.payload != NULL){
1066                 free(xfer->send.payload, xfer->malloc);
1067         }
1068         if(xfer->recv.payload != NULL){
1069                 free(xfer->recv.payload, xfer->malloc);
1070         }
1071         free(xfer, xfer->malloc);
1072 }
1073
1074 void
1075 fw_xfer_free( struct fw_xfer* xfer)
1076 {
1077         if (xfer == NULL) {
1078                 printf("%s: xfer == NULL\n", __FUNCTION__);
1079                 return;
1080         }
1081         fw_xfer_unload(xfer);
1082         free(xfer, xfer->malloc);
1083 }
1084
1085 void
1086 fw_asy_callback_free(struct fw_xfer *xfer)
1087 {
1088 #if 0
1089         printf("asyreq done state=%d resp=%d\n",
1090                                 xfer->state, xfer->resp);
1091 #endif
1092         fw_xfer_free(xfer);
1093 }
1094
1095 /*
1096  * To configure PHY. 
1097  */
1098 static void
1099 fw_phy_config(struct firewire_comm *fc, int root_node, int gap_count)
1100 {
1101         struct fw_xfer *xfer;
1102         struct fw_pkt *fp;
1103
1104         fc->status = FWBUSPHYCONF;
1105
1106         xfer = fw_xfer_alloc(M_FWXFER);
1107         if (xfer == NULL)
1108                 return;
1109         xfer->fc = fc;
1110         xfer->retry_req = fw_asybusy;
1111         xfer->act.hand = fw_asy_callback_free;
1112
1113         fp = &xfer->send.hdr;
1114         fp->mode.ld[1] = 0;
1115         if (root_node >= 0)
1116                 fp->mode.ld[1] |= (root_node & 0x3f) << 24 | 1 << 23;
1117         if (gap_count >= 0)
1118                 fp->mode.ld[1] |= 1 << 22 | (gap_count & 0x3f) << 16;
1119         fp->mode.ld[2] = ~fp->mode.ld[1];
1120 /* XXX Dangerous, how to pass PHY packet to device driver */
1121         fp->mode.common.tcode |= FWTCODE_PHY;
1122
1123         if (firewire_debug)
1124                 printf("send phy_config root_node=%d gap_count=%d\n",
1125                                                 root_node, gap_count);
1126         fw_asyreq(fc, -1, xfer);
1127 }
1128
1129 #if 0
1130 /*
1131  * Dump self ID. 
1132  */
1133 static void
1134 fw_print_sid(u_int32_t sid)
1135 {
1136         union fw_self_id *s;
1137         s = (union fw_self_id *) &sid;
1138         printf("node:%d link:%d gap:%d spd:%d del:%d con:%d pwr:%d"
1139                 " p0:%d p1:%d p2:%d i:%d m:%d\n",
1140                 s->p0.phy_id, s->p0.link_active, s->p0.gap_count,
1141                 s->p0.phy_speed, s->p0.phy_delay, s->p0.contender,
1142                 s->p0.power_class, s->p0.port0, s->p0.port1,
1143                 s->p0.port2, s->p0.initiated_reset, s->p0.more_packets);
1144 }
1145 #endif
1146
1147 /*
1148  * To receive self ID. 
1149  */
1150 void fw_sidrcv(struct firewire_comm* fc, u_int32_t *sid, u_int len)
1151 {
1152         u_int32_t *p;
1153         union fw_self_id *self_id;
1154         u_int i, j, node, c_port = 0, i_branch = 0;
1155
1156         fc->sid_cnt = len /(sizeof(u_int32_t) * 2);
1157         fc->status = FWBUSINIT;
1158         fc->max_node = fc->nodeid & 0x3f;
1159         CSRARC(fc, NODE_IDS) = ((u_int32_t)fc->nodeid) << 16;
1160         fc->status = FWBUSCYMELECT;
1161         fc->topology_map->crc_len = 2;
1162         fc->topology_map->generation ++;
1163         fc->topology_map->self_id_count = 0;
1164         fc->topology_map->node_count = 0;
1165         fc->speed_map->generation ++;
1166         fc->speed_map->crc_len = 1 + (64*64 + 3) / 4;
1167         self_id = &fc->topology_map->self_id[0];
1168         for(i = 0; i < fc->sid_cnt; i ++){
1169                 if (sid[1] != ~sid[0]) {
1170                         printf("fw_sidrcv: invalid self-id packet\n");
1171                         sid += 2;
1172                         continue;
1173                 }
1174                 *self_id = *((union fw_self_id *)sid);
1175                 fc->topology_map->crc_len++;
1176                 if(self_id->p0.sequel == 0){
1177                         fc->topology_map->node_count ++;
1178                         c_port = 0;
1179 #if 0
1180                         fw_print_sid(sid[0]);
1181 #endif
1182                         node = self_id->p0.phy_id;
1183                         if(fc->max_node < node){
1184                                 fc->max_node = self_id->p0.phy_id;
1185                         }
1186                         /* XXX I'm not sure this is the right speed_map */
1187                         fc->speed_map->speed[node][node]
1188                                         = self_id->p0.phy_speed;
1189                         for (j = 0; j < node; j ++) {
1190                                 fc->speed_map->speed[j][node]
1191                                         = fc->speed_map->speed[node][j]
1192                                         = min(fc->speed_map->speed[j][j],
1193                                                         self_id->p0.phy_speed);
1194                         }
1195                         if ((fc->irm == -1 || self_id->p0.phy_id > fc->irm) &&
1196                           (self_id->p0.link_active && self_id->p0.contender)) {
1197                                 fc->irm = self_id->p0.phy_id;
1198                         }
1199                         if(self_id->p0.port0 >= 0x2){
1200                                 c_port++;
1201                         }
1202                         if(self_id->p0.port1 >= 0x2){
1203                                 c_port++;
1204                         }
1205                         if(self_id->p0.port2 >= 0x2){
1206                                 c_port++;
1207                         }
1208                 }
1209                 if(c_port > 2){
1210                         i_branch += (c_port - 2);
1211                 }
1212                 sid += 2;
1213                 self_id++;
1214                 fc->topology_map->self_id_count ++;
1215         }
1216         device_printf(fc->bdev, "%d nodes", fc->max_node + 1);
1217         /* CRC */
1218         fc->topology_map->crc = fw_crc16(
1219                         (u_int32_t *)&fc->topology_map->generation,
1220                         fc->topology_map->crc_len * 4);
1221         fc->speed_map->crc = fw_crc16(
1222                         (u_int32_t *)&fc->speed_map->generation,
1223                         fc->speed_map->crc_len * 4);
1224         /* byteswap and copy to CSR */
1225         p = (u_int32_t *)fc->topology_map;
1226         for (i = 0; i <= fc->topology_map->crc_len; i++)
1227                 CSRARC(fc, TOPO_MAP + i * 4) = htonl(*p++);
1228         p = (u_int32_t *)fc->speed_map;
1229         CSRARC(fc, SPED_MAP) = htonl(*p++);
1230         CSRARC(fc, SPED_MAP + 4) = htonl(*p++);
1231         /* don't byte-swap u_int8_t array */
1232         bcopy(p, &CSRARC(fc, SPED_MAP + 8), (fc->speed_map->crc_len - 1)*4);
1233
1234         fc->max_hop = fc->max_node - i_branch;
1235         printf(", maxhop <= %d", fc->max_hop);
1236                 
1237         if(fc->irm == -1 ){
1238                 printf(", Not found IRM capable node");
1239         }else{
1240                 printf(", cable IRM = %d", fc->irm);
1241                 if (fc->irm == fc->nodeid)
1242                         printf(" (me)");
1243         }
1244         printf("\n");
1245
1246         if (try_bmr && (fc->irm != -1) && (CSRARC(fc, BUS_MGR_ID) == 0x3f)) {
1247                 if (fc->irm == fc->nodeid) {
1248                         fc->status = FWBUSMGRDONE;
1249                         CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, fc->irm);
1250                         fw_bmr(fc);
1251                 } else {
1252                         fc->status = FWBUSMGRELECT;
1253                         callout_reset(&fc->bmr_callout, hz/8,
1254                                 (void *)fw_try_bmr, (void *)fc);
1255                 }
1256         } else
1257                 fc->status = FWBUSMGRDONE;
1258
1259         callout_reset(&fc->busprobe_callout, hz/4,
1260                         (void *)fw_bus_probe, (void *)fc);
1261 }
1262
1263 /*
1264  * To probe devices on the IEEE1394 bus. 
1265  */
1266 static void
1267 fw_bus_probe(struct firewire_comm *fc)
1268 {
1269         int s;
1270         struct fw_device *fwdev;
1271
1272         s = splfw();
1273         fc->status = FWBUSEXPLORE;
1274         fc->retry_count = 0;
1275
1276         /* Invalidate all devices, just after bus reset. */
1277         STAILQ_FOREACH(fwdev, &fc->devices, link)
1278                 if (fwdev->status != FWDEVINVAL) {
1279                         fwdev->status = FWDEVINVAL;
1280                         fwdev->rcnt = 0;
1281                 }
1282
1283         fc->ongonode = 0;
1284         fc->ongoaddr = CSRROMOFF;
1285         fc->ongodev = NULL;
1286         fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1287         fw_bus_explore(fc);
1288         splx(s);
1289 }
1290
1291 /*
1292  * To collect device informations on the IEEE1394 bus. 
1293  */
1294 static void
1295 fw_bus_explore(struct firewire_comm *fc )
1296 {
1297         int err = 0;
1298         struct fw_device *fwdev, *pfwdev, *tfwdev;
1299         u_int32_t addr;
1300         struct fw_xfer *xfer;
1301         struct fw_pkt *fp;
1302
1303         if(fc->status != FWBUSEXPLORE)
1304                 return;
1305
1306 loop:
1307         if(fc->ongonode == fc->nodeid) fc->ongonode++;
1308
1309         if(fc->ongonode > fc->max_node) goto done;
1310         if(fc->ongonode >= 0x3f) goto done;
1311
1312         /* check link */
1313         /* XXX we need to check phy_id first */
1314         if (!fc->topology_map->self_id[fc->ongonode].p0.link_active) {
1315                 if (firewire_debug)
1316                         printf("node%d: link down\n", fc->ongonode);
1317                 fc->ongonode++;
1318                 goto loop;
1319         }
1320
1321         if(fc->ongoaddr <= CSRROMOFF &&
1322                 fc->ongoeui.hi == 0xffffffff &&
1323                 fc->ongoeui.lo == 0xffffffff ){
1324                 fc->ongoaddr = CSRROMOFF;
1325                 addr = 0xf0000000 | fc->ongoaddr;
1326         }else if(fc->ongoeui.hi == 0xffffffff ){
1327                 fc->ongoaddr = CSRROMOFF + 0xc;
1328                 addr = 0xf0000000 | fc->ongoaddr;
1329         }else if(fc->ongoeui.lo == 0xffffffff ){
1330                 fc->ongoaddr = CSRROMOFF + 0x10;
1331                 addr = 0xf0000000 | fc->ongoaddr;
1332         }else if(fc->ongodev == NULL){
1333                 STAILQ_FOREACH(fwdev, &fc->devices, link)
1334                         if (FW_EUI64_EQUAL(fwdev->eui, fc->ongoeui))
1335                                 break;
1336                 if(fwdev != NULL){
1337                         fwdev->dst = fc->ongonode;
1338                         fwdev->status = FWDEVINIT;
1339                         fc->ongodev = fwdev;
1340                         fc->ongoaddr = CSRROMOFF;
1341                         addr = 0xf0000000 | fc->ongoaddr;
1342                         goto dorequest;
1343                 }
1344                 fwdev = malloc(sizeof(struct fw_device), M_FW,
1345                                                         M_NOWAIT | M_ZERO);
1346                 if(fwdev == NULL)
1347                         return;
1348                 fwdev->fc = fc;
1349                 fwdev->rommax = 0;
1350                 fwdev->dst = fc->ongonode;
1351                 fwdev->eui.hi = fc->ongoeui.hi; fwdev->eui.lo = fc->ongoeui.lo;
1352                 fwdev->status = FWDEVINIT;
1353                 fwdev->speed = fc->speed_map->speed[fc->nodeid][fc->ongonode];
1354
1355                 pfwdev = NULL;
1356                 STAILQ_FOREACH(tfwdev, &fc->devices, link) {
1357                         if (tfwdev->eui.hi > fwdev->eui.hi ||
1358                                         (tfwdev->eui.hi == fwdev->eui.hi &&
1359                                         tfwdev->eui.lo > fwdev->eui.lo))
1360                                 break;
1361                         pfwdev = tfwdev;
1362                 }
1363                 if (pfwdev == NULL)
1364                         STAILQ_INSERT_HEAD(&fc->devices, fwdev, link);
1365                 else
1366                         STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link);
1367
1368                 device_printf(fc->bdev, "New %s device ID:%08x%08x\n",
1369                         linkspeed[fwdev->speed],
1370                         fc->ongoeui.hi, fc->ongoeui.lo);
1371
1372                 fc->ongodev = fwdev;
1373                 fc->ongoaddr = CSRROMOFF;
1374                 addr = 0xf0000000 | fc->ongoaddr;
1375         }else{
1376                 addr = 0xf0000000 | fc->ongoaddr;
1377         }
1378 dorequest:
1379 #if 0
1380         xfer = asyreqq(fc, FWSPD_S100, 0, 0,
1381                 ((FWLOCALBUS | fc->ongonode) << 16) | 0xffff , addr,
1382                 fw_bus_explore_callback);
1383         if(xfer == NULL) goto done;
1384 #else
1385         xfer = fw_xfer_alloc(M_FWXFER);
1386         if(xfer == NULL){
1387                 goto done;
1388         }
1389         xfer->send.spd = 0;
1390         fp = &xfer->send.hdr;
1391         fp->mode.rreqq.dest_hi = 0xffff;
1392         fp->mode.rreqq.tlrt = 0;
1393         fp->mode.rreqq.tcode = FWTCODE_RREQQ;
1394         fp->mode.rreqq.pri = 0;
1395         fp->mode.rreqq.src = 0;
1396         fp->mode.rreqq.dst = FWLOCALBUS | fc->ongonode;
1397         fp->mode.rreqq.dest_lo = addr;
1398         xfer->act.hand = fw_bus_explore_callback;
1399
1400         if (firewire_debug)
1401                 printf("node%d: explore addr=0x%x\n",
1402                                 fc->ongonode, fc->ongoaddr);
1403         err = fw_asyreq(fc, -1, xfer);
1404         if(err){
1405                 fw_xfer_free( xfer);
1406                 return;
1407         }
1408 #endif
1409         return;
1410 done:
1411         /* fw_attach_devs */
1412         fc->status = FWBUSEXPDONE;
1413         if (firewire_debug)
1414                 printf("bus_explore done\n");
1415         fw_attach_dev(fc);
1416         return;
1417
1418 }
1419
1420 /* Portable Async. request read quad */
1421 struct fw_xfer *
1422 asyreqq(struct firewire_comm *fc, u_int8_t spd, u_int8_t tl, u_int8_t rt,
1423         u_int32_t addr_hi, u_int32_t addr_lo,
1424         void (*hand) (struct fw_xfer*))
1425 {
1426         struct fw_xfer *xfer;
1427         struct fw_pkt *fp;
1428         int err;
1429
1430         xfer = fw_xfer_alloc(M_FWXFER);
1431         if (xfer == NULL)
1432                 return NULL;
1433
1434         xfer->send.spd = spd; /* XXX:min(spd, fc->spd) */
1435         fp = &xfer->send.hdr;
1436         fp->mode.rreqq.dest_hi = addr_hi & 0xffff;
1437         if(tl & FWP_TL_VALID){
1438                 fp->mode.rreqq.tlrt = (tl & 0x3f) << 2;
1439         }else{
1440                 fp->mode.rreqq.tlrt = 0;
1441         }
1442         fp->mode.rreqq.tlrt |= rt & 0x3;
1443         fp->mode.rreqq.tcode = FWTCODE_RREQQ;
1444         fp->mode.rreqq.pri = 0;
1445         fp->mode.rreqq.src = 0;
1446         fp->mode.rreqq.dst = addr_hi >> 16;
1447         fp->mode.rreqq.dest_lo = addr_lo;
1448         xfer->act.hand = hand;
1449
1450         err = fw_asyreq(fc, -1, xfer);
1451         if(err){
1452                 fw_xfer_free( xfer);
1453                 return NULL;
1454         }
1455         return xfer;
1456 }
1457
1458 /*
1459  * Callback for the IEEE1394 bus information collection. 
1460  */
1461 static void
1462 fw_bus_explore_callback(struct fw_xfer *xfer)
1463 {
1464         struct firewire_comm *fc;
1465         struct fw_pkt *sfp,*rfp;
1466         struct csrhdr *chdr;
1467         struct csrdir *csrd;
1468         struct csrreg *csrreg;
1469         u_int32_t offset;
1470
1471         
1472         if(xfer == NULL) {
1473                 printf("xfer == NULL\n");
1474                 return;
1475         }
1476         fc = xfer->fc;
1477
1478         if (firewire_debug)
1479                 printf("node%d: callback addr=0x%x\n",
1480                         fc->ongonode, fc->ongoaddr);
1481
1482         if(xfer->resp != 0){
1483                 printf("node%d: resp=%d addr=0x%x\n",
1484                         fc->ongonode, xfer->resp, fc->ongoaddr);
1485                 goto errnode;
1486         }
1487
1488         sfp = &xfer->send.hdr;
1489         rfp = &xfer->recv.hdr;
1490 #if 0
1491         {
1492                 u_int32_t *qld;
1493                 int i;
1494                 qld = (u_int32_t *)xfer->recv.buf;
1495                 printf("len:%d\n", xfer->recv.len);
1496                 for( i = 0 ; i <= xfer->recv.len && i < 32; i+= 4){
1497                         printf("0x%08x ", rfp->mode.ld[i/4]);
1498                         if((i % 16) == 15) printf("\n");
1499                 }
1500                 if((i % 16) != 15) printf("\n");
1501         }
1502 #endif
1503         if(fc->ongodev == NULL){
1504                 if(sfp->mode.rreqq.dest_lo == (0xf0000000 | CSRROMOFF)){
1505                         rfp->mode.rresq.data = ntohl(rfp->mode.rresq.data);
1506                         chdr = (struct csrhdr *)(&rfp->mode.rresq.data);
1507 /* If CSR is minimal confinguration, more investgation is not needed. */
1508                         if(chdr->info_len == 1){
1509                                 if (firewire_debug)
1510                                         printf("node%d: minimal config\n",
1511                                                                 fc->ongonode);
1512                                 goto nextnode;
1513                         }else{
1514                                 fc->ongoaddr = CSRROMOFF + 0xc;
1515                         }
1516                 }else if(sfp->mode.rreqq.dest_lo == (0xf0000000 |(CSRROMOFF + 0xc))){
1517                         fc->ongoeui.hi = ntohl(rfp->mode.rresq.data);
1518                         fc->ongoaddr = CSRROMOFF + 0x10;
1519                 }else if(sfp->mode.rreqq.dest_lo == (0xf0000000 |(CSRROMOFF + 0x10))){
1520                         fc->ongoeui.lo = ntohl(rfp->mode.rresq.data);
1521                         if (fc->ongoeui.hi == 0 && fc->ongoeui.lo == 0) {
1522                                 if (firewire_debug)
1523                                         printf("node%d: eui64 is zero.\n",
1524                                                         fc->ongonode);
1525                                 goto nextnode;
1526                         }
1527                         fc->ongoaddr = CSRROMOFF;
1528                 }
1529         }else{
1530                 if (fc->ongoaddr == CSRROMOFF &&
1531                     fc->ongodev->csrrom[0] == ntohl(rfp->mode.rresq.data)) {
1532                         fc->ongodev->status = FWDEVATTACHED;
1533                         goto nextnode;
1534                 }
1535                 fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4] = ntohl(rfp->mode.rresq.data);
1536                 if(fc->ongoaddr > fc->ongodev->rommax){
1537                         fc->ongodev->rommax = fc->ongoaddr;
1538                 }
1539                 csrd = SLIST_FIRST(&fc->ongocsr);
1540                 if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
1541                         chdr = (struct csrhdr *)(fc->ongodev->csrrom);
1542                         offset = CSRROMOFF;
1543                 }else{
1544                         chdr = (struct csrhdr *)&fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4];
1545                         offset = csrd->off;
1546                 }
1547                 if(fc->ongoaddr > (CSRROMOFF + 0x14) && fc->ongoaddr != offset){
1548                         csrreg = (struct csrreg *)&fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4];
1549                         if( csrreg->key == 0x81 || csrreg->key == 0xd1){
1550                                 csrd = SLIST_FIRST(&fc->csrfree);
1551                                 if(csrd == NULL){
1552                                         goto nextnode;
1553                                 }else{
1554                                         csrd->ongoaddr = fc->ongoaddr;
1555                                         fc->ongoaddr += csrreg->val * 4;
1556                                         csrd->off = fc->ongoaddr;
1557                                         SLIST_REMOVE_HEAD(&fc->csrfree, link);
1558                                         SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
1559                                         goto nextaddr;
1560                                 }
1561                         }
1562                 }
1563                 fc->ongoaddr += 4;
1564                 if(((fc->ongoaddr - offset)/4 > chdr->crc_len) &&
1565                                 (fc->ongodev->rommax < 0x414)){
1566                         if(fc->ongodev->rommax <= 0x414){
1567                                 csrd = SLIST_FIRST(&fc->csrfree);
1568                                 if(csrd == NULL) goto nextnode;
1569                                 csrd->off = fc->ongoaddr;
1570                                 csrd->ongoaddr = fc->ongoaddr;
1571                                 SLIST_REMOVE_HEAD(&fc->csrfree, link);
1572                                 SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link);
1573                         }
1574                         goto nextaddr;
1575                 }
1576
1577                 while(((fc->ongoaddr - offset)/4 > chdr->crc_len)){
1578                         if(csrd == NULL){
1579                                 goto nextnode;
1580                         };
1581                         fc->ongoaddr = csrd->ongoaddr + 4;
1582                         SLIST_REMOVE_HEAD(&fc->ongocsr, link);
1583                         SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1584                         csrd = SLIST_FIRST(&fc->ongocsr);
1585                         if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){
1586                                 chdr = (struct csrhdr *)(fc->ongodev->csrrom);
1587                                 offset = CSRROMOFF;
1588                         }else{
1589                                 chdr = (struct csrhdr *)&(fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4]);
1590                                 offset = csrd->off;
1591                         }
1592                 }
1593                 if((fc->ongoaddr - CSRROMOFF) > CSRROMSIZE){
1594                         goto nextnode;
1595                 }
1596         }
1597 nextaddr:
1598         fw_xfer_free( xfer);
1599         fw_bus_explore(fc);
1600         return;
1601 errnode:
1602         fc->retry_count++;
1603         if (fc->ongodev != NULL)
1604                 fc->ongodev->status = FWDEVINVAL;
1605 nextnode:
1606         fw_xfer_free( xfer);
1607         fc->ongonode++;
1608 /* housekeeping work space */
1609         fc->ongoaddr = CSRROMOFF;
1610         fc->ongodev = NULL;
1611         fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff;
1612         while((csrd = SLIST_FIRST(&fc->ongocsr)) != NULL){
1613                 SLIST_REMOVE_HEAD(&fc->ongocsr, link);
1614                 SLIST_INSERT_HEAD(&fc->csrfree, csrd, link);
1615         }
1616         fw_bus_explore(fc);
1617         return;
1618 }
1619
1620 /*
1621  * To attach sub-devices layer onto IEEE1394 bus.
1622  */
1623 static void
1624 fw_attach_dev(struct firewire_comm *fc)
1625 {
1626         struct fw_device *fwdev, *next;
1627         int i, err;
1628         device_t *devlistp;
1629         int devcnt;
1630         struct firewire_dev_comm *fdc;
1631
1632         for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = next) {
1633                 next = STAILQ_NEXT(fwdev, link);
1634                 if (fwdev->status == FWDEVINIT) {
1635                         fwdev->status = FWDEVATTACHED;
1636                 } else if (fwdev->status == FWDEVINVAL) {
1637                         fwdev->rcnt ++;
1638                         if (fwdev->rcnt > hold_count) {
1639                                 /*
1640                                  * Remove devices which have not been seen
1641                                  * for a while.
1642                                  */
1643                                 STAILQ_REMOVE(&fc->devices, fwdev, fw_device,
1644                                     link);
1645                                 free(fwdev, M_FW);
1646                         }
1647                 }
1648         }
1649
1650         err = device_get_children(fc->bdev, &devlistp, &devcnt);
1651         if( err != 0 )
1652                 return;
1653         for( i = 0 ; i < devcnt ; i++){
1654                 if (device_get_state(devlistp[i]) >= DS_ATTACHED)  {
1655                         fdc = device_get_softc(devlistp[i]);
1656                         if (fdc->post_explore != NULL)
1657                                 fdc->post_explore(fdc);
1658                 }
1659         }
1660         free(devlistp, M_TEMP);
1661
1662         if (fc->retry_count > 0) {
1663                 printf("probe failed for %d node\n", fc->retry_count);
1664 #if 0
1665                 callout_reset(&fc->retry_probe_callout, hz*2,
1666                                         (void *)fc->ibr, (void *)fc);
1667 #endif
1668         }
1669         return;
1670 }
1671
1672 /*
1673  * To allocate uniq transaction label.
1674  */
1675 static int
1676 fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer)
1677 {
1678         u_int i;
1679         struct tlabel *tl, *tmptl;
1680         int s;
1681         static u_int32_t label = 0;
1682
1683         s = splfw();
1684         for( i = 0 ; i < 0x40 ; i ++){
1685                 label = (label + 1) & 0x3f;
1686                 for(tmptl = STAILQ_FIRST(&fc->tlabels[label]);
1687                         tmptl != NULL; tmptl = STAILQ_NEXT(tmptl, link)){
1688                         if (tmptl->xfer->send.hdr.mode.hdr.dst ==
1689                             xfer->send.hdr.mode.hdr.dst)
1690                                 break;
1691                 }
1692                 if(tmptl == NULL) {
1693                         tl = malloc(sizeof(struct tlabel),M_FW,M_NOWAIT);
1694                         if (tl == NULL) {
1695                                 splx(s);
1696                                 return (-1);
1697                         }
1698                         tl->xfer = xfer;
1699                         STAILQ_INSERT_TAIL(&fc->tlabels[label], tl, link);
1700                         splx(s);
1701                         if (firewire_debug > 1)
1702                                 printf("fw_get_tlabel: dst=%d tl=%d\n",
1703                                     xfer->send.hdr.mode.hdr.dst, label);
1704                         return(label);
1705                 }
1706         }
1707         splx(s);
1708
1709         printf("fw_get_tlabel: no free tlabel\n");
1710         return(-1);
1711 }
1712
1713 static void
1714 fw_rcv_copy(struct fw_rcv_buf *rb)
1715 {
1716         struct fw_pkt *pkt;
1717         u_char *p;
1718         struct tcode_info *tinfo;
1719         u_int res, i, len, plen;
1720
1721         rb->xfer->recv.spd -= rb->spd;
1722
1723         pkt = (struct fw_pkt *)rb->vec->iov_base;
1724         tinfo = &rb->fc->tcode[pkt->mode.hdr.tcode];
1725
1726         /* Copy header */ 
1727         p = (u_char *)&rb->xfer->recv.hdr;
1728         bcopy(rb->vec->iov_base, p, tinfo->hdr_len);
1729         (u_char *)rb->vec->iov_base += tinfo->hdr_len;
1730         rb->vec->iov_len -= tinfo->hdr_len;
1731
1732         /* Copy payload */
1733         p = (u_char *)rb->xfer->recv.payload;
1734         res = rb->xfer->recv.pay_len;
1735
1736         /* special handling for RRESQ */
1737         if (pkt->mode.hdr.tcode == FWTCODE_RRESQ &&
1738             p != NULL && res >= sizeof(u_int32_t)) {
1739                 *(u_int32_t *)p = pkt->mode.rresq.data;
1740                 rb->xfer->recv.pay_len = sizeof(u_int32_t);
1741                 return;
1742         }
1743
1744         if ((tinfo->flag & FWTI_BLOCK_ASY) == 0)
1745                 return;
1746
1747         plen = pkt->mode.rresb.len;
1748
1749         for (i = 0; i < rb->nvec; i++, rb->vec++) {
1750                 len = MIN(rb->vec->iov_len, plen);
1751                 if (res < len) {
1752                         printf("rcv buffer(%d) is %d bytes short.\n",
1753                             rb->xfer->recv.pay_len, len - res);
1754                         len = res;
1755                 }
1756                 bcopy(rb->vec->iov_base, p, len);
1757                 p += len;
1758                 res -= len;
1759                 plen -= len;
1760                 if (res == 0 || plen == 0)
1761                         break;
1762         }
1763         rb->xfer->recv.pay_len -= res;
1764
1765 }
1766
1767 /*
1768  * Generic packet receving process.
1769  */
1770 void
1771 fw_rcv(struct fw_rcv_buf *rb)
1772 {
1773         struct fw_pkt *fp, *resfp;
1774         struct fw_bind *bind;
1775         int tcode, s;
1776         int i, len, oldstate;
1777 #if 0
1778         {
1779                 u_int32_t *qld;
1780                 int i;
1781                 qld = (u_int32_t *)buf;
1782                 printf("spd %d len:%d\n", spd, len);
1783                 for( i = 0 ; i <= len && i < 32; i+= 4){
1784                         printf("0x%08x ", ntohl(qld[i/4]));
1785                         if((i % 16) == 15) printf("\n");
1786                 }
1787                 if((i % 16) != 15) printf("\n");
1788         }
1789 #endif
1790         fp = (struct fw_pkt *)rb->vec[0].iov_base;
1791         tcode = fp->mode.common.tcode;
1792         switch (tcode) {
1793         case FWTCODE_WRES:
1794         case FWTCODE_RRESQ:
1795         case FWTCODE_RRESB:
1796         case FWTCODE_LRES:
1797                 rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
1798                                         fp->mode.hdr.tlrt >> 2);
1799                 if(rb->xfer == NULL) {
1800                         printf("fw_rcv: unknown response "
1801                             "%s(%x) src=0x%x tl=0x%x rt=%d data=0x%x\n",
1802                             tcode_str[tcode], tcode,
1803                             fp->mode.hdr.src,
1804                             fp->mode.hdr.tlrt >> 2,
1805                             fp->mode.hdr.tlrt & 3,
1806                             fp->mode.rresq.data);
1807 #if 1
1808                         printf("try ad-hoc work around!!\n");
1809                         rb->xfer = fw_tl2xfer(rb->fc, fp->mode.hdr.src,
1810                                         (fp->mode.hdr.tlrt >> 2)^3);
1811                         if (rb->xfer == NULL) {
1812                                 printf("no use...\n");
1813                                 goto err;
1814                         }
1815 #else
1816                         goto err;
1817 #endif
1818                 }
1819                 fw_rcv_copy(rb);
1820                 if (rb->xfer->recv.hdr.mode.wres.rtcode != RESP_CMP)
1821                         rb->xfer->resp = EIO;
1822                 else
1823                         rb->xfer->resp = 0;
1824                 /* make sure the packet is drained in AT queue */
1825                 oldstate = rb->xfer->state;
1826                 rb->xfer->state = FWXF_RCVD;
1827                 switch (oldstate) {
1828                 case FWXF_SENT:
1829                         fw_xfer_done(rb->xfer);
1830                         break;
1831                 case FWXF_START:
1832 #if 0
1833                         if (firewire_debug)
1834                                 printf("not sent yet tl=%x\n", rb->xfer->tl);
1835 #endif
1836                         break;
1837                 default:
1838                         printf("unexpected state %d\n", rb->xfer->state);
1839                 }
1840                 return;
1841         case FWTCODE_WREQQ:
1842         case FWTCODE_WREQB:
1843         case FWTCODE_RREQQ:
1844         case FWTCODE_RREQB:
1845         case FWTCODE_LREQ:
1846                 bind = fw_bindlookup(rb->fc, fp->mode.rreqq.dest_hi,
1847                         fp->mode.rreqq.dest_lo);
1848                 if(bind == NULL){
1849                         printf("Unknown service addr 0x%04x:0x%08x %s(%x)"
1850 #if __FreeBSD_version >= 500000
1851                             " src=0x%x data=%x\n",
1852 #else
1853                             " src=0x%x data=%lx\n",
1854 #endif
1855                             fp->mode.wreqq.dest_hi, fp->mode.wreqq.dest_lo,
1856                             tcode_str[tcode], tcode,
1857                             fp->mode.hdr.src, ntohl(fp->mode.wreqq.data));
1858                         if (rb->fc->status == FWBUSRESET) {
1859                                 printf("fw_rcv: cannot respond(bus reset)!\n");
1860                                 goto err;
1861                         }
1862                         rb->xfer = fw_xfer_alloc(M_FWXFER);
1863                         if(rb->xfer == NULL){
1864                                 return;
1865                         }
1866                         rb->xfer->send.spd = rb->spd;
1867                         rb->xfer->send.pay_len = 0;
1868                         resfp = &rb->xfer->send.hdr;
1869                         switch (tcode) {
1870                         case FWTCODE_WREQQ:
1871                         case FWTCODE_WREQB:
1872                                 resfp->mode.hdr.tcode = FWTCODE_WRES;
1873                                 break;
1874                         case FWTCODE_RREQQ:
1875                                 resfp->mode.hdr.tcode = FWTCODE_RRESQ;
1876                                 break;
1877                         case FWTCODE_RREQB:
1878                                 resfp->mode.hdr.tcode = FWTCODE_RRESB;
1879                                 break;
1880                         case FWTCODE_LREQ:
1881                                 resfp->mode.hdr.tcode = FWTCODE_LRES;
1882                                 break;
1883                         }
1884                         resfp->mode.hdr.dst = fp->mode.hdr.src;
1885                         resfp->mode.hdr.tlrt = fp->mode.hdr.tlrt;
1886                         resfp->mode.hdr.pri = fp->mode.hdr.pri;
1887                         resfp->mode.rresb.rtcode = RESP_ADDRESS_ERROR;
1888                         resfp->mode.rresb.extcode = 0;
1889                         resfp->mode.rresb.len = 0;
1890 /*
1891                         rb->xfer->act.hand = fw_asy_callback;
1892 */
1893                         rb->xfer->act.hand = fw_xfer_free;
1894                         if(fw_asyreq(rb->fc, -1, rb->xfer)){
1895                                 fw_xfer_free(rb->xfer);
1896                                 return;
1897                         }
1898                         goto err;
1899                 }
1900                 len = 0;
1901                 for (i = 0; i < rb->nvec; i ++)
1902                         len += rb->vec[i].iov_len;
1903                 switch(bind->act_type){
1904                 case FWACT_XFER:
1905                         /* splfw()?? */
1906                         rb->xfer = STAILQ_FIRST(&bind->xferlist);
1907                         if (rb->xfer == NULL) {
1908                                 printf("Discard a packet for this bind.\n");
1909                                 goto err;
1910                         }
1911                         STAILQ_REMOVE_HEAD(&bind->xferlist, link);
1912                         fw_rcv_copy(rb);
1913                         rb->xfer->act.hand(rb->xfer);
1914                         return;
1915                         break;
1916                 case FWACT_CH:
1917                         if(rb->fc->ir[bind->sub]->queued >=
1918                                 rb->fc->ir[bind->sub]->maxq){
1919                                 device_printf(rb->fc->bdev,
1920                                         "Discard a packet %x %d\n",
1921                                         bind->sub,
1922                                         rb->fc->ir[bind->sub]->queued);
1923                                 goto err;
1924                         }
1925                         rb->xfer = STAILQ_FIRST(&bind->xferlist);
1926                         if (rb->xfer == NULL) {
1927                                 printf("Discard packet for this bind\n");
1928                                 goto err;
1929                         }
1930                         STAILQ_REMOVE_HEAD(&bind->xferlist, link);
1931                         fw_rcv_copy(rb);
1932                         s = splfw();
1933                         rb->fc->ir[bind->sub]->queued++;
1934                         STAILQ_INSERT_TAIL(&rb->fc->ir[bind->sub]->q,
1935                             rb->xfer, link);
1936                         splx(s);
1937
1938                         wakeup((caddr_t)rb->fc->ir[bind->sub]);
1939
1940                         return;
1941                         break;
1942                 default:
1943                         goto err;
1944                         break;
1945                 }
1946                 break;
1947 #if 0 /* shouldn't happen ?? or for GASP */
1948         case FWTCODE_STREAM:
1949         {
1950                 struct fw_xferq *xferq;
1951
1952                 xferq = rb->fc->ir[sub];
1953 #if 0
1954                 printf("stream rcv dma %d len %d off %d spd %d\n",
1955                         sub, len, off, spd);
1956 #endif
1957                 if(xferq->queued >= xferq->maxq) {
1958                         printf("receive queue is full\n");
1959                         goto err;
1960                 }
1961                 /* XXX get xfer from xfer queue, we don't need copy for 
1962                         per packet mode */
1963                 rb->xfer = fw_xfer_alloc_buf(M_FWXFER, 0, /* XXX */
1964                                                 vec[0].iov_len);
1965                 if (rb->xfer == NULL) goto err;
1966                 fw_rcv_copy(rb)
1967                 s = splfw();
1968                 xferq->queued++;
1969                 STAILQ_INSERT_TAIL(&xferq->q, rb->xfer, link);
1970                 splx(s);
1971                 sc = device_get_softc(rb->fc->bdev);
1972 #if __FreeBSD_version >= 500000
1973                 if (SEL_WAITING(&xferq->rsel))
1974 #else
1975                 if (&xferq->rsel.si_pid != 0)
1976 #endif
1977                         selwakeuppri(&xferq->rsel, FWPRI);
1978                 if (xferq->flag & FWXFERQ_WAKEUP) {
1979                         xferq->flag &= ~FWXFERQ_WAKEUP;
1980                         wakeup((caddr_t)xferq);
1981                 }
1982                 if (xferq->flag & FWXFERQ_HANDLER) {
1983                         xferq->hand(xferq);
1984                 }
1985                 return;
1986                 break;
1987         }
1988 #endif
1989         default:
1990                 printf("fw_rcv: unknow tcode %d\n", tcode);
1991                 break;
1992         }
1993 err:
1994         return;
1995 }
1996
1997 /*
1998  * Post process for Bus Manager election process.
1999  */
2000 static void
2001 fw_try_bmr_callback(struct fw_xfer *xfer)
2002 {
2003         struct firewire_comm *fc;
2004         int bmr;
2005
2006         if (xfer == NULL)
2007                 return;
2008         fc = xfer->fc;
2009         if (xfer->resp != 0)
2010                 goto error;
2011         if (xfer->recv.payload == NULL)
2012                 goto error;
2013         if (xfer->recv.hdr.mode.lres.rtcode != FWRCODE_COMPLETE)
2014                 goto error;
2015
2016         bmr = ntohl(xfer->recv.payload[0]);
2017         if (bmr == 0x3f)
2018                 bmr = fc->nodeid;
2019
2020         CSRARC(fc, BUS_MGR_ID) = fc->set_bmr(fc, bmr & 0x3f);
2021         fw_xfer_free_buf(xfer);
2022         fw_bmr(fc);
2023         return;
2024
2025 error:
2026         device_printf(fc->bdev, "bus manager election failed\n");
2027         fw_xfer_free_buf(xfer);
2028 }
2029
2030
2031 /*
2032  * To candidate Bus Manager election process.
2033  */
2034 static void
2035 fw_try_bmr(void *arg)
2036 {
2037         struct fw_xfer *xfer;
2038         struct firewire_comm *fc = (struct firewire_comm *)arg;
2039         struct fw_pkt *fp;
2040         int err = 0;
2041
2042         xfer = fw_xfer_alloc_buf(M_FWXFER, 8, 4);
2043         if(xfer == NULL){
2044                 return;
2045         }
2046         xfer->send.spd = 0;
2047         fc->status = FWBUSMGRELECT;
2048
2049         fp = &xfer->send.hdr;
2050         fp->mode.lreq.dest_hi = 0xffff;
2051         fp->mode.lreq.tlrt = 0;
2052         fp->mode.lreq.tcode = FWTCODE_LREQ;
2053         fp->mode.lreq.pri = 0;
2054         fp->mode.lreq.src = 0;
2055         fp->mode.lreq.len = 8;
2056         fp->mode.lreq.extcode = EXTCODE_CMP_SWAP;
2057         fp->mode.lreq.dst = FWLOCALBUS | fc->irm;
2058         fp->mode.lreq.dest_lo = 0xf0000000 | BUS_MGR_ID;
2059         xfer->send.payload[0] = htonl(0x3f);
2060         xfer->send.payload[1] = htonl(fc->nodeid);
2061         xfer->act.hand = fw_try_bmr_callback;
2062
2063         err = fw_asyreq(fc, -1, xfer);
2064         if(err){
2065                 fw_xfer_free_buf(xfer);
2066                 return;
2067         }
2068         return;
2069 }
2070
2071 #ifdef FW_VMACCESS
2072 /*
2073  * Software implementation for physical memory block access.
2074  * XXX:Too slow, usef for debug purpose only.
2075  */
2076 static void
2077 fw_vmaccess(struct fw_xfer *xfer){
2078         struct fw_pkt *rfp, *sfp = NULL;
2079         u_int32_t *ld = (u_int32_t *)xfer->recv.buf;
2080
2081         printf("vmaccess spd:%2x len:%03x data:%08x %08x %08x %08x\n",
2082                         xfer->spd, xfer->recv.len, ntohl(ld[0]), ntohl(ld[1]), ntohl(ld[2]), ntohl(ld[3]));
2083         printf("vmaccess          data:%08x %08x %08x %08x\n", ntohl(ld[4]), ntohl(ld[5]), ntohl(ld[6]), ntohl(ld[7]));
2084         if(xfer->resp != 0){
2085                 fw_xfer_free( xfer);
2086                 return;
2087         }
2088         if(xfer->recv.buf == NULL){
2089                 fw_xfer_free( xfer);
2090                 return;
2091         }
2092         rfp = (struct fw_pkt *)xfer->recv.buf;
2093         switch(rfp->mode.hdr.tcode){
2094                 /* XXX need fix for 64bit arch */
2095                 case FWTCODE_WREQB:
2096                         xfer->send.buf = malloc(12, M_FW, M_NOWAIT);
2097                         xfer->send.len = 12;
2098                         sfp = (struct fw_pkt *)xfer->send.buf;
2099                         bcopy(rfp->mode.wreqb.payload,
2100                                 (caddr_t)ntohl(rfp->mode.wreqb.dest_lo), ntohs(rfp->mode.wreqb.len));
2101                         sfp->mode.wres.tcode = FWTCODE_WRES;
2102                         sfp->mode.wres.rtcode = 0;
2103                         break;
2104                 case FWTCODE_WREQQ:
2105                         xfer->send.buf = malloc(12, M_FW, M_NOWAIT);
2106                         xfer->send.len = 12;
2107                         sfp->mode.wres.tcode = FWTCODE_WRES;
2108                         *((u_int32_t *)(ntohl(rfp->mode.wreqb.dest_lo))) = rfp->mode.wreqq.data;
2109                         sfp->mode.wres.rtcode = 0;
2110                         break;
2111                 case FWTCODE_RREQB:
2112                         xfer->send.buf = malloc(16 + rfp->mode.rreqb.len, M_FW, M_NOWAIT);
2113                         xfer->send.len = 16 + ntohs(rfp->mode.rreqb.len);
2114                         sfp = (struct fw_pkt *)xfer->send.buf;
2115                         bcopy((caddr_t)ntohl(rfp->mode.rreqb.dest_lo),
2116                                 sfp->mode.rresb.payload, (u_int16_t)ntohs(rfp->mode.rreqb.len));
2117                         sfp->mode.rresb.tcode = FWTCODE_RRESB;
2118                         sfp->mode.rresb.len = rfp->mode.rreqb.len;
2119                         sfp->mode.rresb.rtcode = 0;
2120                         sfp->mode.rresb.extcode = 0;
2121                         break;
2122                 case FWTCODE_RREQQ:
2123                         xfer->send.buf = malloc(16, M_FW, M_NOWAIT);
2124                         xfer->send.len = 16;
2125                         sfp = (struct fw_pkt *)xfer->send.buf;
2126                         sfp->mode.rresq.data = *(u_int32_t *)(ntohl(rfp->mode.rreqq.dest_lo));
2127                         sfp->mode.wres.tcode = FWTCODE_RRESQ;
2128                         sfp->mode.rresb.rtcode = 0;
2129                         break;
2130                 default:
2131                         fw_xfer_free( xfer);
2132                         return;
2133         }
2134         sfp->mode.hdr.dst = rfp->mode.hdr.src;
2135         xfer->dst = ntohs(rfp->mode.hdr.src);
2136         xfer->act.hand = fw_xfer_free;
2137         xfer->retry_req = fw_asybusy;
2138
2139         sfp->mode.hdr.tlrt = rfp->mode.hdr.tlrt;
2140         sfp->mode.hdr.pri = 0;
2141
2142         fw_asyreq(xfer->fc, -1, xfer);
2143 /**/
2144         return;
2145 }
2146 #endif 
2147
2148 /*
2149  * CRC16 check-sum for IEEE1394 register blocks.
2150  */
2151 u_int16_t
2152 fw_crc16(u_int32_t *ptr, u_int32_t len){
2153         u_int32_t i, sum, crc = 0;
2154         int shift;
2155         len = (len + 3) & ~3;
2156         for(i = 0 ; i < len ; i+= 4){
2157                 for( shift = 28 ; shift >= 0 ; shift -= 4){
2158                         sum = ((crc >> 12) ^ (ptr[i/4] >> shift)) & 0xf;
2159                         crc = (crc << 4) ^ ( sum << 12 ) ^ ( sum << 5) ^ sum;
2160                 }
2161                 crc &= 0xffff;
2162         }
2163         return((u_int16_t) crc);
2164 }
2165
2166 static int
2167 fw_bmr(struct firewire_comm *fc)
2168 {
2169         struct fw_device fwdev;
2170         union fw_self_id *self_id;
2171         int cmstr;
2172         u_int32_t quad;
2173
2174         /* Check to see if the current root node is cycle master capable */
2175         self_id = &fc->topology_map->self_id[fc->max_node];
2176         if (fc->max_node > 0) {
2177                 /* XXX check cmc bit of businfo block rather than contender */
2178                 if (self_id->p0.link_active && self_id->p0.contender)
2179                         cmstr = fc->max_node;
2180                 else {
2181                         device_printf(fc->bdev,
2182                                 "root node is not cycle master capable\n");
2183                         /* XXX shall we be the cycle master? */
2184                         cmstr = fc->nodeid;
2185                         /* XXX need bus reset */
2186                 }
2187         } else
2188                 cmstr = -1;
2189
2190         device_printf(fc->bdev, "bus manager %d ", CSRARC(fc, BUS_MGR_ID));
2191         if(CSRARC(fc, BUS_MGR_ID) != fc->nodeid) {
2192                 /* We are not the bus manager */
2193                 printf("\n");
2194                 return(0);
2195         }
2196         printf("(me)\n");
2197
2198         /* Optimize gapcount */
2199         if(fc->max_hop <= MAX_GAPHOP )
2200                 fw_phy_config(fc, cmstr, gap_cnt[fc->max_hop]);
2201         /* If we are the cycle master, nothing to do */
2202         if (cmstr == fc->nodeid || cmstr == -1)
2203                 return 0;
2204         /* Bus probe has not finished, make dummy fwdev for cmstr */
2205         bzero(&fwdev, sizeof(fwdev));
2206         fwdev.fc = fc;
2207         fwdev.dst = cmstr;
2208         fwdev.speed = 0;
2209         fwdev.maxrec = 8; /* 512 */
2210         fwdev.status = FWDEVINIT;
2211         /* Set cmstr bit on the cycle master */
2212         quad = htonl(1 << 8);
2213         fwmem_write_quad(&fwdev, NULL, 0/*spd*/,
2214                 0xffff, 0xf0000000 | STATE_SET, &quad, fw_asy_callback_free);
2215
2216         return 0;
2217 }
2218
2219 static int
2220 fw_modevent(module_t mode, int type, void *data)
2221 {
2222         int err = 0;
2223 #if __FreeBSD_version >= 500000
2224         static eventhandler_tag fwdev_ehtag = NULL;
2225 #endif
2226
2227         switch (type) {
2228         case MOD_LOAD:
2229 #if __FreeBSD_version >= 500000
2230                 fwdev_ehtag = EVENTHANDLER_REGISTER(dev_clone,
2231                                                 fwdev_clone, 0, 1000);
2232 #endif
2233                 break;
2234         case MOD_UNLOAD:
2235 #if __FreeBSD_version >= 500000
2236                 if (fwdev_ehtag != NULL)
2237                         EVENTHANDLER_DEREGISTER(dev_clone, fwdev_ehtag);
2238 #endif
2239                 break;
2240         case MOD_SHUTDOWN:
2241                 break;
2242         }
2243         return (err);
2244 }
2245
2246 DECLARE_DUMMY_MODULE(firewire);
2247 DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,fw_modevent,0);
2248 MODULE_VERSION(firewire, 1);