Subject: Re: PCI mode probe [was Re: INSTALL kernel support ]
To: Jarkko Torppa , Manuel BOUYER <bouyer@antioche.lip6.fr>
From: Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de>
List: port-i386
Date: 12/10/1997 13:51:34
Here is the newest version of the "Compaq PCI configuration" patch.
Pleast try ASAP!

best regards
Matthias


Index: pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pci/pci_machdep.c,v
retrieving revision 1.28
diff -r1.28 pci_machdep.c
100a101
> #include <dev/pci/pcidevs.h>
110a112,130
> #define _m1tag(b, d, f) \
> 	(PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8))
> #define _id(v, p) \
> 	(((v) << PCI_VENDOR_SHIFT) | ((p) << PCI_PRODUCT_SHIFT))
> #define _qe(bus, dev, fcn, vend, prod) \
> 	{_m1tag(bus, dev, fcn), _id(vend, prod)}
> struct {
> 	u_int32_t tag;
> 	pcireg_t id;
> } pcim1_quirk_tbl[] = {
> 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
> 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
> 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
> 	{0, 0xffffffff} /* patchable */
> };
> #undef _m1tag
> #undef _id
> #undef _qe
> 
338a359,360
> 	u_int32_t sav, val;
> 
343,348c365,372
< 	 * We try to divine which configuration mode the host bridge wants.  We
< 	 * try mode 2 first, because our probe for mode 1 is likely to succeed
< 	 * for mode 2 also.
< 	 *
< 	 * XXX
< 	 * This should really be done using the PCI BIOS.
---
> 	 * We try to divine which configuration mode the host bridge wants.
> 	 */
> 
> 	sav = inl(PCI_MODE1_ADDRESS_REG);
> 	/*
> 	 * Check:
> 	 * 1. bit 31 ("enable") can be set
> 	 * 2. byte/word access does not affect register
349a374,401
> 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
> 	outb(PCI_MODE1_ADDRESS_REG + 3, 0);
> 	outw(PCI_MODE1_ADDRESS_REG + 2, 0);
> 	val = inl(PCI_MODE1_ADDRESS_REG);
> 	if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
> 		int i;
> 		pcireg_t idreg;
> /*#ifdef DEBUG*/
> 		printf("pci_mode_detect: mode 1 enable failed (%x)\n",
> 		       val);
> /*#endif*/
> 		pci_mode = 1; /* temporary assumption */
> 
> 		for (i = 0;
> 		     i < sizeof(pcim1_quirk_tbl) / sizeof(pcim1_quirk_tbl[0]);
> 		     i++) {
> 			if (!pcim1_quirk_tbl[i].tag)
> 				break;
> 			idreg = pci_conf_read(0, pcim1_quirk_tbl[i].tag,
> 					      PCI_ID_REG);
> 			if (idreg == pcim1_quirk_tbl[i].id) {
> /*#ifdef DEBUG*/
> 				printf("known broken PCI chipset (%08x)\n",
> 				       idreg);
> /*#endif*/
> 				return(pci_mode);
> 			}
> 		}
350a403,420
> 		pci_mode = -1; /* unneeded */
> 		goto not1;
> 	}
> 	outl(PCI_MODE1_ADDRESS_REG, 0);
> 	val = inl(PCI_MODE1_ADDRESS_REG);
> 	if ((val & 0x80fffffc) != 0)
> 		goto not1;
> 	return (pci_mode = 1);
> not1:
> 	outl(PCI_MODE1_ADDRESS_REG, sav);
> 
> 	/*
> 	 * This mode 2 check is quite weak (and known to give false
> 	 * positives on some Compaq machines).
> 	 * However, this doesn't matter, because this is the
> 	 * last test, and simply no PCI devices will be found if
> 	 * this happens.
> 	 */
357d426
< 
359,365d427
< 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
< 	if (inl(PCI_MODE1_ADDRESS_REG) != PCI_MODE1_ENABLE)
< 		goto not1;
< 	outl(PCI_MODE1_ADDRESS_REG, 0);
< 	if (inl(PCI_MODE1_ADDRESS_REG) != 0)
< 		goto not1;
< 	return (pci_mode = 1);
367d428
< not1: