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

Cache object: eb63909151bdf24b7ce5d3da498ca6c3


[ 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.