Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Sep 1999 09:00:15 +0100 (BST)
From:      Doug Rabson <dfr@nlsystems.com>
To:        Luoqi Chen <luoqi@watermarkgroup.com>
Cc:        arthur@tucows.com, freebsd-current@FreeBSD.ORG, nick.hibma@jrc.it
Subject:   Re: Problems with the sound card.
Message-ID:  <Pine.BSF.4.10.9909030900030.2081-100000@salmon.nlsystems.com>
In-Reply-To: <199909030024.UAA02922@lor.watermarkgroup.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 2 Sep 1999, Luoqi Chen wrote:

> > That's exactly what I have. This is just so weird. I am now reading the
> > debug register chapter of intel's manual, it is virtually impossible to
> > pinpoint the location by single-stepping through the code...
> > 
> The debug register trick worked, and the discovery was quite unexpected:
> because the isa bus is hanging off the pci bus, bus_release_resource()
> call by a isa device, eventually reaches the pci_release_resource(),
> where the device is blindly assumed to be a pci device and its isa_device
> struct overwritten as if it were a struct pci_devinfo. pci_release_resource()
> should check for pass-thru releases.

How about this patch:

Index: pci.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/pci.c,v
retrieving revision 1.116
diff -u -r1.116 pci.c
--- pci.c	1999/08/28 00:51:03	1.116
+++ pci.c	1999/09/03 07:59:44
@@ -1375,40 +1375,42 @@
 	int rv;
 	struct pci_devinfo *dinfo = device_get_ivars(child);
 	pcicfgregs *cfg = &dinfo->cfg;
+	int passthrough = (device_get_parent(child) != dev);
 	int map = 0;
 
-	switch (type) {
-	case SYS_RES_IRQ:
-		if (rid != 0)
-			return EINVAL;
-		break;
+	if (!passthrough)
+	    switch (type) {
+	    case SYS_RES_IRQ:
+		    if (rid != 0)
+			    return EINVAL;
+		    break;
 
-	case SYS_RES_DRQ:		/* passthru for child isa */
-		break;
+	    case SYS_RES_DRQ:		/* passthru for child isa */
+		    break;
 
 #ifdef __alpha__
-	case SYS_RES_DENSE:
-	case SYS_RES_BWX:
+	    case SYS_RES_DENSE:
+	    case SYS_RES_BWX:
 #endif
-	case SYS_RES_MEMORY:
-	case SYS_RES_IOPORT:
-		/*
+	    case SYS_RES_MEMORY:
+	    case SYS_RES_IOPORT:
+		    /*
 		 * Only check the map registers if this is a direct
 		 * descendant.
 		 */
-		if (device_get_parent(child) == dev)
-			map = pci_mapno(cfg, rid);
-		else
-			map = -1;
-		break;
-
-	default:
-		return (ENOENT);
-	}
+		    if (device_get_parent(child) == dev)
+			    map = pci_mapno(cfg, rid);
+		    else
+			    map = -1;
+		    break;
+
+	    default:
+		    return (ENOENT);
+	    }
 
 	rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
 
-	if (rv == 0) {
+	if (!passthrough && rv == 0) {
 		switch (type) {
 		case SYS_RES_IRQ:
 			cfg->irqres = 0;

--
Doug Rabson				Mail:  dfr@nlsystems.com
Nonlinear Systems Ltd.			Phone: +44 181 442 9037




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.9909030900030.2081-100000>