The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/firewire/firewire.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: ad3672babb0b56da63c090741b1442ae


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.