Date: Fri, 12 Apr 2002 09:28:59 -0600 (MDT) From: "M. Warner Losh" <imp@village.org> To: leibrand@informatik.tu-muenchen.de Cc: freebsd-current@FreeBSD.ORG, freebsd-mobile@FreeBSD.ORG Subject: Re: Possible bug in /sys/i386/pci/pci_cfgreg.c Message-ID: <20020412.092859.98363104.imp@village.org> In-Reply-To: <Pine.GSO.4.44.0204121353110.3002-100000@sunhalle19> References: <Pine.GSO.4.44.0204121353110.3002-100000@sunhalle19>
next in thread | previous in thread | raw e-mail | index | archive | help
In message: <Pine.GSO.4.44.0204121353110.3002-100000@sunhalle19> Klaus Leibrandt <leibrand@informatik.tu-muenchen.de> writes: : Hi Folks. : : I spent some time tracking down my CardBus problem and found the : following: : : In /sys/i386/pci/pci_cfgreg.c: : In Function: static int pci_cfgintr_linked(struct PIR_entry *pe, int pin): : : There you can find this code (my changes included): : : /* link destination mapped to a unique interrupt? */ : : /* if (powerof2(pi->irqs)) { // i changed this line to the next : line of code */ : /* the reason is given below*/ : : /* On my system the CardBus bridge has no interrupt assigned (lazy BIOS I : would say). : So pi->irqs is 0. powerof2 returns true (which is wrong as ahown : below). : Then ffs returs 0. that - 1 gives an irq of -1 whis is totally wrong) : The if clause must evaluate to false if there is no interrut assigned : otherwise the system will panic during boot as I experineced it. */ Ah, 0 is a *BOGUS* way of saying no interrupt assigned, per the PCI spec. However, lots of BIOSes use it, so its meaning must be defined in some other document I've never laid eyes on since more and more places are using it. 0 should be mapped in the i386 level. Try the following patch and let me know how it works for you. There is also some code now in dev/pci/pci.c that should be removed (since it is only a subset of this stuff): if (cfg->intpin > 0 && cfg->intline != 255 -#ifdef __i386__ - && cfg->intline != 0 -#endif ) { if you have a new enough kernel. Warner Index: pci_cfgreg.c =================================================================== RCS file: /cache/ncvs/src/sys/i386/pci/pci_cfgreg.c,v retrieving revision 1.83 diff -u -r1.83 pci_cfgreg.c --- pci_cfgreg.c 16 Mar 2002 23:02:41 -0000 1.83 +++ pci_cfgreg.c 12 Apr 2002 15:26:06 -0000 @@ -178,6 +178,7 @@ u_int32_t pci_cfgregread(int bus, int slot, int func, int reg, int bytes) { + uint32_t line, pin; #ifdef APIC_IO /* * If we are using the APIC, the contents of the intline register will probably @@ -186,7 +187,6 @@ * attempts to read them and translate to our private vector numbers. */ if ((reg == PCIR_INTLINE) && (bytes == 1)) { - int pin, line; pin = pci_do_cfgregread(bus, slot, func, PCIR_INTPIN, 1); line = pci_do_cfgregread(bus, slot, func, PCIR_INTLINE, 1); @@ -217,6 +217,18 @@ } return(line); } +#else + /* + * Some BIOS writers seem to want to ignore the spec and put + * 0 in the intline rather than 255 to indicate none. The rest of + * the code uses 255 as an invalid IRQ. + */ + if (reg == PCIR_INTLINE && bytes == 1) { + line = pci_do_cfgregread(bus, slot, func, PCIR_INTLINE, 1); + pin = pci_do_cfgregread(bus, slot, func, PCIR_INTPIN, 1); + if (pin != 0 && (line == 0 || line >= 128)) + return (255); + } #endif /* APIC_IO */ return(pci_do_cfgregread(bus, slot, func, reg, bytes)); } @@ -394,14 +406,6 @@ (pci_get_slot(*childp) == device) && (pci_get_intpin(*childp) == matchpin)) { irq = pci_get_irq(*childp); - /* - * Some BIOS writers seem to want to ignore the spec and put - * 0 in the intline rather than 255 to indicate none. Once - * we've found one that matches, we break because there can - * be no others (which is why test looks a little odd). - */ - if (irq == 0) - irq = 255; if (irq != 255) PRVERB(("pci_cfgintr_search: linked (%x) to configured irq %d at %d:%d:%d\n", pe->pe_intpin[pin - 1].link, irq, 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?20020412.092859.98363104.imp>