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

Cache object: 74ecdf368a340e8c9d9374e71caba9d9


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