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

Cache object: 6d302d262d1b8e76e944041322700715


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