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:  [EMAIL PROTECTED]
Nonlinear Systems Ltd.                  Phone: +44 181 442 9037




To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to