From owner-p4-projects@FreeBSD.ORG Mon May 21 05:50:31 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 561C216A469; Mon, 21 May 2007 05:50:31 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id D351116A400 for ; Mon, 21 May 2007 05:50:30 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id C3D5613C447 for ; Mon, 21 May 2007 05:50:30 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l4L5oUYn073527 for ; Mon, 21 May 2007 05:50:30 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l4L5oUcF073518 for perforce@freebsd.org; Mon, 21 May 2007 05:50:30 GMT (envelope-from mjacob@freebsd.org) Date: Mon, 21 May 2007 05:50:30 GMT Message-Id: <200705210550.l4L5oUcF073518@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 120150 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 May 2007 05:50:31 -0000 http://perforce.freebsd.org/chv.cgi?CH=120150 Change 120150 by mjacob@mjexp on 2007/05/21 05:49:28 IFC Affected files ... .. //depot/projects/mjexp/sys/dev/firewire/firewire.c#5 integrate .. //depot/projects/mjexp/sys/dev/firewire/firewirereg.h#4 integrate .. //depot/projects/mjexp/sys/ia64/ia64/trap.c#4 integrate Differences ... ==== //depot/projects/mjexp/sys/dev/firewire/firewire.c#5 (text+ko) ==== @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.92 2007/04/30 13:51:13 simokawa Exp $ + * $FreeBSD: src/sys/dev/firewire/firewire.c,v 1.93 2007/05/21 02:18:49 simokawa Exp $ * */ @@ -44,6 +44,7 @@ #include #include #include +#include #if defined(__DragonFly__) || __FreeBSD_version < 500000 #include /* for DELAY() */ @@ -103,14 +104,11 @@ static void fw_asystart (struct fw_xfer *); static int fw_get_tlabel (struct firewire_comm *, struct fw_xfer *); static void fw_bus_probe (struct firewire_comm *); -static void fw_bus_explore (struct firewire_comm *); -static void fw_bus_explore_callback (struct fw_xfer *); static void fw_attach_dev (struct firewire_comm *); +static void fw_bus_probe_thread(void *); #ifdef FW_VMACCESS static void fw_vmaccess (struct fw_xfer *); #endif -struct fw_xfer *asyreqq (struct firewire_comm *, uint8_t, uint8_t, uint8_t, - uint32_t, uint32_t, void (*)(struct fw_xfer *)); static int fw_bmr (struct firewire_comm *); static device_method_t firewire_methods[] = { @@ -379,6 +377,7 @@ struct firewire_softc *sc = device_get_softc(dev); device_t pa = device_get_parent(dev); struct firewire_comm *fc; + struct proc *p; fc = (struct firewire_comm *)device_get_softc(pa); sc->fc = fc; @@ -396,6 +395,10 @@ callout_reset(&sc->fc->timeout_callout, hz, (void *)firewire_watchdog, (void *)sc->fc); + /* create thread */ + kthread_create(fw_bus_probe_thread, (void *)fc, &p, + 0, 0, "fw%d_probe", unit); + /* Locate our children */ bus_generic_probe(dev); @@ -448,34 +451,38 @@ firewire_detach(device_t dev) { struct firewire_softc *sc; - struct csrdir *csrd, *next; + struct firewire_comm *fc; struct fw_device *fwdev, *fwdev_next; int err; sc = (struct firewire_softc *)device_get_softc(dev); + fc = sc->fc; + fc->status = FWBUSDETACH; + if ((err = fwdev_destroydev(sc)) != 0) return err; if ((err = bus_generic_detach(dev)) != 0) return err; - callout_stop(&sc->fc->timeout_callout); - callout_stop(&sc->fc->bmr_callout); - callout_stop(&sc->fc->busprobe_callout); + callout_stop(&fc->timeout_callout); + callout_stop(&fc->bmr_callout); + callout_stop(&fc->busprobe_callout); /* XXX xfree_free and untimeout on all xfers */ - for (fwdev = STAILQ_FIRST(&sc->fc->devices); fwdev != NULL; + for (fwdev = STAILQ_FIRST(&fc->devices); fwdev != NULL; fwdev = fwdev_next) { fwdev_next = STAILQ_NEXT(fwdev, link); free(fwdev, M_FW); } - for (csrd = SLIST_FIRST(&sc->fc->csrfree); csrd != NULL; csrd = next) { - next = SLIST_NEXT(csrd, link); - free(csrd, M_FW); - } - free(sc->fc->topology_map, M_FW); - free(sc->fc->speed_map, M_FW); - free(sc->fc->crom_src_buf, M_FW); + free(fc->topology_map, M_FW); + free(fc->speed_map, M_FW); + free(fc->crom_src_buf, M_FW); + + wakeup(fc); + if (tsleep(fc, PWAIT, "fwthr", hz * 60)) + printf("firewire task thread didn't die\n"); + return(0); } #if 0 @@ -678,7 +685,6 @@ void fw_init(struct firewire_comm *fc) { int i; - struct csrdir *csrd; #ifdef FW_VMACCESS struct fw_xfer *xfer; struct fw_bind *fwb; @@ -742,15 +748,6 @@ STAILQ_INIT(&fc->devices); -/* Initialize csr ROM work space */ - SLIST_INIT(&fc->ongocsr); - SLIST_INIT(&fc->csrfree); - for( i = 0 ; i < FWMAXCSRDIR ; i++){ - csrd = (struct csrdir *) malloc(sizeof(struct csrdir), M_FW,M_NOWAIT); - if(csrd == NULL) break; - SLIST_INSERT_HEAD(&fc->csrfree, csrd, link); - } - /* Initialize Async handlers */ STAILQ_INIT(&fc->binds); for( i = 0 ; i < 0x40 ; i++){ @@ -1284,105 +1281,146 @@ fwdev->status = FWDEVINVAL; fwdev->rcnt = 0; } + splx(s); + + wakeup((void *)fc); +} + +static int +fw_explore_read_quads(struct fw_device *fwdev, int offset, + uint32_t *quad, int n) +{ + struct fw_xfer *xfer; + uint32_t tmp; + int i, error; + + for (i = 0; i < n; i ++, offset += sizeof(uint32_t)) { + xfer = fwmem_read_quad(fwdev, NULL, -1, + 0xffff, 0xf0000000 | offset, (void *)&tmp, + fw_asy_callback); + if (xfer == NULL) + return (-1); + tsleep((void *)xfer, PWAIT|PCATCH, "rquad", 0); - fc->ongonode = 0; - fc->ongoaddr = CSRROMOFF; - fc->ongodev = NULL; - fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff; - fw_bus_explore(fc); - splx(s); + if (xfer->resp == 0) + quad[i] = ntohl(tmp); + + error = xfer->resp; + fw_xfer_free(xfer); + if (error) + return (error); + } + return (0); } -/* - * Find the self_id packet for a node, ignoring sequels. - */ -static union fw_self_id * -fw_find_self_id(struct firewire_comm *fc, int node) + +static int +fw_explore_csrblock(struct fw_device *fwdev, int offset, int recur) { - uint32_t i; - union fw_self_id *s; + int err, i, off; + struct csrdirectory *dir; + struct csrreg *reg; + + dir = (struct csrdirectory *)&fwdev->csrrom[offset/sizeof(uint32_t)]; + err = fw_explore_read_quads(fwdev, CSRROMOFF + offset, + (uint32_t *)dir, 1); + if (err) + return (-1); + + offset += sizeof(uint32_t); + reg = (struct csrreg *)&fwdev->csrrom[offset/sizeof(uint32_t)]; + err = fw_explore_read_quads(fwdev, CSRROMOFF + offset, + (uint32_t *)reg, dir->crc_len); + if (err) + return (-1); + + /* XXX check CRC */ + + off = CSRROMOFF + offset + sizeof(uint32_t) * (dir->crc_len - 1); + if (fwdev->rommax < off) + fwdev->rommax = off; + + if (recur == 0) + return (0); - for (i = 0; i < fc->topology_map->self_id_count; i++) { - s = &fc->topology_map->self_id[i]; - if (s->p0.sequel) + for (i = 0; i < dir->crc_len; i ++, offset += sizeof(uint32_t)) { + if (reg[i].key == CROM_UDIR) + recur = 1; + else if (reg[i].key == CROM_TEXTLEAF) + recur = 0; + else continue; - if (s->p0.phy_id == node) - return s; + + off = offset + reg[i].val * sizeof(uint32_t); + if (off > CROMSIZE) { + printf("%s: invalid offset %d\n", __FUNCTION__, off); + return(-1); + } + err = fw_explore_csrblock(fwdev, off, recur); + if (err) + return (-1); } - return 0; + return (0); } -/* - * To collect device informations on the IEEE1394 bus. - */ -static void -fw_bus_explore(struct firewire_comm *fc ) +static int +fw_explore_node(struct fw_device *dfwdev) { - int err = 0; + struct firewire_comm *fc; struct fw_device *fwdev, *pfwdev, *tfwdev; - uint32_t addr; - struct fw_xfer *xfer; - struct fw_pkt *fp; - union fw_self_id *fwsid; + uint32_t *csr; + struct csrhdr *hdr; + struct bus_info *binfo; + int err, node, spd; - if(fc->status != FWBUSEXPLORE) - return; + fc = dfwdev->fc; + csr = dfwdev->csrrom; + node = dfwdev->dst; -loop: - if(fc->ongonode == fc->nodeid) fc->ongonode++; + /* First quad */ + err = fw_explore_read_quads(dfwdev, CSRROMOFF, &csr[0], 1); + if (err) + return (-1); + hdr = (struct csrhdr *)&csr[0]; + if (hdr->info_len != 4) { + if (firewire_debug) + printf("node%d: wrong bus info len(%d)\n", + node, hdr->info_len); + return (-1); + } - if(fc->ongonode > fc->max_node) goto done; - if(fc->ongonode >= 0x3f) goto done; - - /* check link */ - /* XXX we need to check phy_id first */ - fwsid = fw_find_self_id(fc, fc->ongonode); - if (!fwsid || !fwsid->p0.link_active) { + /* bus info */ + err = fw_explore_read_quads(dfwdev, CSRROMOFF + 0x04, &csr[1], 4); + if (err) + return (-1); + binfo = (struct bus_info *)&csr[1]; + if (binfo->bus_name != CSR_BUS_NAME_IEEE1394) { if (firewire_debug) - printf("node%d: link down\n", fc->ongonode); - fc->ongonode++; - goto loop; + printf("node%d: invalid bus name 0x%08x\n", + node, binfo->bus_name); + return (-1); } - - if(fc->ongoaddr <= CSRROMOFF && - fc->ongoeui.hi == 0xffffffff && - fc->ongoeui.lo == 0xffffffff ){ - fc->ongoaddr = CSRROMOFF; - addr = 0xf0000000 | fc->ongoaddr; - }else if(fc->ongoeui.hi == 0xffffffff ){ - fc->ongoaddr = CSRROMOFF + 0xc; - addr = 0xf0000000 | fc->ongoaddr; - }else if(fc->ongoeui.lo == 0xffffffff ){ - fc->ongoaddr = CSRROMOFF + 0x10; - addr = 0xf0000000 | fc->ongoaddr; - }else if(fc->ongodev == NULL){ - STAILQ_FOREACH(fwdev, &fc->devices, link) - if (FW_EUI64_EQUAL(fwdev->eui, fc->ongoeui)) - break; - if(fwdev != NULL){ - fwdev->dst = fc->ongonode; - fwdev->status = FWDEVINIT; - fc->ongodev = fwdev; - fc->ongoaddr = CSRROMOFF; - addr = 0xf0000000 | fc->ongoaddr; - goto dorequest; + spd = fc->speed_map->speed[fc->nodeid][node]; + STAILQ_FOREACH(fwdev, &fc->devices, link) + if (FW_EUI64_EQUAL(fwdev->eui, binfo->eui64)) + break; + if (fwdev == NULL) { + /* new device */ + fwdev = malloc(sizeof(struct fw_device), M_FW, + M_NOWAIT | M_ZERO); + if (fwdev == NULL) { + if (firewire_debug) + printf("node%d: no memory\n", node); + return (-1); } - fwdev = malloc(sizeof(struct fw_device), M_FW, - M_NOWAIT | M_ZERO); - if(fwdev == NULL) - return; fwdev->fc = fc; - fwdev->rommax = 0; - fwdev->dst = fc->ongonode; - fwdev->eui.hi = fc->ongoeui.hi; fwdev->eui.lo = fc->ongoeui.lo; - fwdev->status = FWDEVINIT; - fwdev->speed = fc->speed_map->speed[fc->nodeid][fc->ongonode]; - + fwdev->eui = binfo->eui64; + /* inesrt into sorted fwdev list */ pfwdev = NULL; STAILQ_FOREACH(tfwdev, &fc->devices, link) { if (tfwdev->eui.hi > fwdev->eui.hi || - (tfwdev->eui.hi == fwdev->eui.hi && - tfwdev->eui.lo > fwdev->eui.lo)) + (tfwdev->eui.hi == fwdev->eui.hi && + tfwdev->eui.lo > fwdev->eui.lo)) break; pfwdev = tfwdev; } @@ -1392,258 +1430,121 @@ STAILQ_INSERT_AFTER(&fc->devices, pfwdev, fwdev, link); device_printf(fc->bdev, "New %s device ID:%08x%08x\n", - linkspeed[fwdev->speed], - fc->ongoeui.hi, fc->ongoeui.lo); - - fc->ongodev = fwdev; - fc->ongoaddr = CSRROMOFF; - addr = 0xf0000000 | fc->ongoaddr; - }else{ - addr = 0xf0000000 | fc->ongoaddr; + linkspeed[spd], + fwdev->eui.hi, fwdev->eui.lo); } -dorequest: -#if 0 - xfer = asyreqq(fc, FWSPD_S100, 0, 0, - ((FWLOCALBUS | fc->ongonode) << 16) | 0xffff , addr, - fw_bus_explore_callback); - if(xfer == NULL) goto done; -#else - xfer = fw_xfer_alloc(M_FWXFER); - if(xfer == NULL){ - goto done; - } - xfer->send.spd = 0; - fp = &xfer->send.hdr; - fp->mode.rreqq.dest_hi = 0xffff; - fp->mode.rreqq.tlrt = 0; - fp->mode.rreqq.tcode = FWTCODE_RREQQ; - fp->mode.rreqq.pri = 0; - fp->mode.rreqq.src = 0; - fp->mode.rreqq.dst = FWLOCALBUS | fc->ongonode; - fp->mode.rreqq.dest_lo = addr; - xfer->hand = fw_bus_explore_callback; + fwdev->dst = node; + fwdev->status = FWDEVINIT; + fwdev->speed = spd; - if (firewire_debug) - printf("node%d: explore addr=0x%x\n", - fc->ongonode, fc->ongoaddr); - err = fw_asyreq(fc, -1, xfer); - if(err){ - fw_xfer_free( xfer); - return; + /* unchanged ? */ + if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { + if (firewire_debug) + printf("node%d: crom unchanged\n", node); + return (0); } -#endif - return; -done: - /* fw_attach_devs */ - fc->status = FWBUSEXPDONE; - if (firewire_debug) - printf("bus_explore done\n"); - fw_attach_dev(fc); - return; -} + bzero(&fwdev->csrrom[0], CROMSIZE); -/* Portable Async. request read quad */ -struct fw_xfer * -asyreqq(struct firewire_comm *fc, uint8_t spd, uint8_t tl, uint8_t rt, - uint32_t addr_hi, uint32_t addr_lo, - void (*hand) (struct fw_xfer*)) -{ - struct fw_xfer *xfer; - struct fw_pkt *fp; - int err; + /* copy first quad and bus info block */ + bcopy(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5); + fwdev->rommax = CSRROMOFF + sizeof(uint32_t) * 4; - xfer = fw_xfer_alloc(M_FWXFER); - if (xfer == NULL) - return NULL; + err = fw_explore_csrblock(fwdev, 0x14, 1); /* root directory */ - xfer->send.spd = spd; /* XXX:min(spd, fc->spd) */ - fp = &xfer->send.hdr; - fp->mode.rreqq.dest_hi = addr_hi & 0xffff; - if(tl & FWP_TL_VALID){ - fp->mode.rreqq.tlrt = (tl & 0x3f) << 2; - }else{ - fp->mode.rreqq.tlrt = 0; + if (err) { + fwdev->status = FWDEVINVAL; + fwdev->csrrom[0] = 0; } - fp->mode.rreqq.tlrt |= rt & 0x3; - fp->mode.rreqq.tcode = FWTCODE_RREQQ; - fp->mode.rreqq.pri = 0; - fp->mode.rreqq.src = 0; - fp->mode.rreqq.dst = addr_hi >> 16; - fp->mode.rreqq.dest_lo = addr_lo; - xfer->hand = hand; + return (err); - err = fw_asyreq(fc, -1, xfer); - if(err){ - fw_xfer_free( xfer); - return NULL; - } - return xfer; } /* - * Callback for the IEEE1394 bus information collection. + * Find the self_id packet for a node, ignoring sequels. */ -static void -fw_bus_explore_callback(struct fw_xfer *xfer) +static union fw_self_id * +fw_find_self_id(struct firewire_comm *fc, int node) { - struct firewire_comm *fc; - struct fw_pkt *sfp,*rfp; - struct csrhdr *chdr; - struct csrdir *csrd; - struct csrreg *csrreg; - uint32_t offset; + uint32_t i; + union fw_self_id *s; - - if(xfer == NULL) { - printf("xfer == NULL\n"); - return; + for (i = 0; i < fc->topology_map->self_id_count; i++) { + s = &fc->topology_map->self_id[i]; + if (s->p0.sequel) + continue; + if (s->p0.phy_id == node) + return s; } - fc = xfer->fc; + return 0; +} - if (firewire_debug) - printf("node%d: callback addr=0x%x\n", - fc->ongonode, fc->ongoaddr); +static void +fw_explore(struct firewire_comm *fc) +{ + int node, err, s, i, todo, todo2, trys; + char nodes[63]; + struct fw_device dfwdev; - if(xfer->resp != 0){ - device_printf(fc->bdev, - "bus_explore node=%d addr=0x%x resp=%d\n", - fc->ongonode, fc->ongoaddr, xfer->resp); - goto errnode; - } + todo = 0; + /* setup dummy fwdev */ + dfwdev.fc = fc; + dfwdev.speed = 0; + dfwdev.maxrec = 8; /* 512 */ + dfwdev.status = FWDEVINIT; - sfp = &xfer->send.hdr; - rfp = &xfer->recv.hdr; -#if 0 - { - uint32_t *qld; - int i; - qld = (uint32_t *)xfer->recv.buf; - printf("len:%d\n", xfer->recv.len); - for( i = 0 ; i <= xfer->recv.len && i < 32; i+= 4){ - printf("0x%08x ", rfp->mode.ld[i/4]); - if((i % 16) == 15) printf("\n"); + for (node = 0; node <= fc->max_node; node ++) { + /* We don't probe myself and linkdown nodes */ + if (node == fc->nodeid) + continue; + if (!fw_find_self_id(fc, node)->p0.link_active) { + if (firewire_debug) + printf("node%d: link down\n", node); + continue; } - if((i % 16) != 15) printf("\n"); + nodes[todo++] = node; } -#endif - if(fc->ongodev == NULL){ - if(sfp->mode.rreqq.dest_lo == (0xf0000000 | CSRROMOFF)){ - rfp->mode.rresq.data = ntohl(rfp->mode.rresq.data); - chdr = (struct csrhdr *)(&rfp->mode.rresq.data); -/* If CSR is minimal confinguration, more investigation is not needed. */ - if(chdr->info_len == 1){ - if (firewire_debug) - printf("node%d: minimal config\n", - fc->ongonode); - goto nextnode; - }else{ - fc->ongoaddr = CSRROMOFF + 0xc; - } - }else if(sfp->mode.rreqq.dest_lo == (0xf0000000 |(CSRROMOFF + 0xc))){ - fc->ongoeui.hi = ntohl(rfp->mode.rresq.data); - fc->ongoaddr = CSRROMOFF + 0x10; - }else if(sfp->mode.rreqq.dest_lo == (0xf0000000 |(CSRROMOFF + 0x10))){ - fc->ongoeui.lo = ntohl(rfp->mode.rresq.data); - if (fc->ongoeui.hi == 0 && fc->ongoeui.lo == 0) { - if (firewire_debug) - printf("node%d: eui64 is zero.\n", - fc->ongonode); - goto nextnode; - } - fc->ongoaddr = CSRROMOFF; - } - }else{ - if (fc->ongoaddr == CSRROMOFF && - fc->ongodev->csrrom[0] == ntohl(rfp->mode.rresq.data)) { - fc->ongodev->status = FWDEVATTACHED; - goto nextnode; - } - fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4] = ntohl(rfp->mode.rresq.data); - if(fc->ongoaddr > fc->ongodev->rommax){ - fc->ongodev->rommax = fc->ongoaddr; - } - csrd = SLIST_FIRST(&fc->ongocsr); - if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){ - chdr = (struct csrhdr *)(fc->ongodev->csrrom); - offset = CSRROMOFF; - }else{ - chdr = (struct csrhdr *)&fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4]; - offset = csrd->off; - } - if(fc->ongoaddr > (CSRROMOFF + 0x14) && fc->ongoaddr != offset){ - csrreg = (struct csrreg *)&fc->ongodev->csrrom[(fc->ongoaddr - CSRROMOFF)/4]; - if( csrreg->key == 0x81 || csrreg->key == 0xd1){ - csrd = SLIST_FIRST(&fc->csrfree); - if(csrd == NULL){ - goto nextnode; - }else{ - csrd->ongoaddr = fc->ongoaddr; - fc->ongoaddr += csrreg->val * 4; - csrd->off = fc->ongoaddr; - SLIST_REMOVE_HEAD(&fc->csrfree, link); - SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link); - goto nextaddr; - } - } - } - fc->ongoaddr += 4; - if(((fc->ongoaddr - offset)/4 > chdr->crc_len) && - (fc->ongodev->rommax < 0x414)){ - if(fc->ongodev->rommax <= 0x414){ - csrd = SLIST_FIRST(&fc->csrfree); - if(csrd == NULL) goto nextnode; - csrd->off = fc->ongoaddr; - csrd->ongoaddr = fc->ongoaddr; - SLIST_REMOVE_HEAD(&fc->csrfree, link); - SLIST_INSERT_HEAD(&fc->ongocsr, csrd, link); - } - goto nextaddr; - } - while(((fc->ongoaddr - offset)/4 > chdr->crc_len)){ - if(csrd == NULL){ - goto nextnode; - }; - fc->ongoaddr = csrd->ongoaddr + 4; - SLIST_REMOVE_HEAD(&fc->ongocsr, link); - SLIST_INSERT_HEAD(&fc->csrfree, csrd, link); - csrd = SLIST_FIRST(&fc->ongocsr); - if((csrd = SLIST_FIRST(&fc->ongocsr)) == NULL){ - chdr = (struct csrhdr *)(fc->ongodev->csrrom); - offset = CSRROMOFF; - }else{ - chdr = (struct csrhdr *)&(fc->ongodev->csrrom[(csrd->off - CSRROMOFF)/4]); - offset = csrd->off; - } + s = splfw(); + for (trys = 0; todo > 0 && trys < 3; trys ++) { + todo2 = 0; + for (i = 0; i < todo; i ++) { + dfwdev.dst = nodes[i]; + err = fw_explore_node(&dfwdev); + if (err) + nodes[todo2++] = nodes[i]; + if (firewire_debug) + printf("%s: node %d, err = %d\n", + __FUNCTION__, node, err); } - if((fc->ongoaddr - CSRROMOFF) > CSRROMSIZE){ - goto nextnode; - } + todo = todo2; } -nextaddr: - fw_xfer_free( xfer); - fw_bus_explore(fc); - return; -errnode: - if (fc->ongodev != NULL) { - fc->ongodev->status = FWDEVINVAL; - /* Invalidate ROM */ - fc->ongodev->csrrom[0] = 0; + splx(s); +} + + +static void +fw_bus_probe_thread(void *arg) +{ + struct firewire_comm *fc; + + fc = (struct firewire_comm *)arg; + + mtx_lock(&Giant); + while (1) { + if (fc->status == FWBUSEXPLORE) { + fw_explore(fc); + fc->status = FWBUSEXPDONE; + if (firewire_debug) + printf("bus_explore done\n"); + fw_attach_dev(fc); + } else if (fc->status == FWBUSDETACH) + break; + tsleep((void *)fc, PWAIT|PCATCH, "-", 0); } -nextnode: - fw_xfer_free( xfer); - fc->ongonode++; -/* housekeeping work space */ - fc->ongoaddr = CSRROMOFF; - fc->ongodev = NULL; - fc->ongoeui.hi = 0xffffffff; fc->ongoeui.lo = 0xffffffff; - while((csrd = SLIST_FIRST(&fc->ongocsr)) != NULL){ - SLIST_REMOVE_HEAD(&fc->ongocsr, link); - SLIST_INSERT_HEAD(&fc->csrfree, csrd, link); - } - fw_bus_explore(fc); - return; + mtx_unlock(&Giant); + wakeup(fc); + kthread_exit(0); } /* ==== //depot/projects/mjexp/sys/dev/firewire/firewirereg.h#4 (text+ko) ==== @@ -31,7 +31,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/firewire/firewirereg.h,v 1.45 2007/04/30 13:41:40 simokawa Exp $ + * $FreeBSD: src/sys/dev/firewire/firewirereg.h,v 1.46 2007/05/21 02:18:50 simokawa Exp $ * */ @@ -113,15 +113,8 @@ u_int max_node; u_int max_hop; #define FWPHYASYST (1 << 0) - uint32_t ongobus:10, - ongonode:6, - ongoaddr:16; - struct fw_device *ongodev; - struct fw_eui64 ongoeui; -#define FWMAXCSRDIR 16 - SLIST_HEAD(, csrdir) ongocsr; - SLIST_HEAD(, csrdir) csrfree; uint32_t status; +#define FWBUSDETACH (-2) #define FWBUSNOTREADY (-1) #define FWBUSRESET 0 #define FWBUSINIT 1 @@ -170,12 +163,6 @@ }; #define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4]) -struct csrdir{ - uint32_t ongoaddr; - uint32_t off; - SLIST_ENTRY(csrdir) link; -}; - struct fw_xferq { int flag; #define FWXFERQ_CHTAGMASK 0xff ==== //depot/projects/mjexp/sys/ia64/ia64/trap.c#4 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/ia64/ia64/trap.c,v 1.126 2007/03/09 04:02:37 mohans Exp $"); +__FBSDID("$FreeBSD: src/sys/ia64/ia64/trap.c,v 1.127 2007/05/21 05:11:43 marcel Exp $"); #include "opt_ddb.h" #include "opt_ktrace.h" @@ -629,8 +629,20 @@ break; } + case IA64_VEC_SPECULATION: + /* + * The branching behaviour of the chk instruction is not + * implemented by the processor. All we need to do is + * compute the target address of the branch and make sure + * that control is transfered to that address. + * We should do this in the IVT table and not by entring + * the kernel... + */ + tf->tf_special.iip += tf->tf_special.ifa << 4; + tf->tf_special.psr &= ~IA64_PSR_RI; + goto out; + case IA64_VEC_NAT_CONSUMPTION: - case IA64_VEC_SPECULATION: case IA64_VEC_UNSUPP_DATA_REFERENCE: if (user) { ucode = vector;