PERFORCE change 120150 for review

Matt Jacob mjacob at FreeBSD.org
Mon May 21 05:50:31 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=120150

Change 120150 by mjacob at 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 <sys/malloc.h>
 #include <sys/conf.h>
 #include <sys/sysctl.h>
+#include <sys/kthread.h>
 
 #if defined(__DragonFly__) || __FreeBSD_version < 500000
 #include <machine/clock.h>	/* 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 <sys/cdefs.h>
-__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;


More information about the p4-projects mailing list