printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname); return; } if (pcibios_get_intr_routing(sc, pcibios_pir_table, &pcibios_pir_table_nentries, &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) { printf("%s: No PCI IRQ Routing information available.\n", sc->sc_dev.dv_xname); free(pcibios_pir_table, M_DEVBUF); pcibios_pir_table = NULL; pcibios_pir_table_nentries = 0; return; } printf("%s: PCI BIOS has %d Interrupt Routing table entries\n", sc->sc_dev.dv_xname, pcibios_pir_table_nentries);
pcibios_pir_table_nentries = 32; pcibios_pir_table = malloc(pcibios_pir_table_nentries * sizeof(*pcibios_pir_table), M_DEVBUF, M_NOWAIT); if (pcibios_pir_table == NULL) { printf("%s: no memory for $PIR\n", sc->sc_dev.dv_xname); return NULL; } if (pcibios_get_intr_routing(sc, pcibios_pir_table, &pcibios_pir_table_nentries, &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) { printf("%s: PCI IRQ Routing information unavailable.\n", sc->sc_dev.dv_xname); free(pcibios_pir_table, M_DEVBUF); pcibios_pir_table = NULL; pcibios_pir_table_nentries = 0; return NULL; } printf("%s: PCI BIOS has %d Interrupt Routing table entries\n", sc->sc_dev.dv_xname, pcibios_pir_table_nentries); }
pcibios_pir_init(sc)	struct pcibios_softc *sc;{	char devinfo[256];	paddr_t pa;	caddr_t p;	unsigned char cksum;	u_int16_t tablesize;	u_int8_t rev_maj, rev_min;	int i;	for (pa = PCI_IRQ_TABLE_START; pa < PCI_IRQ_TABLE_END; pa += 16) {		p = (caddr_t)ISA_HOLE_VADDR(pa);		if (*(int *)p != BIOS32_MAKESIG('$', 'P', 'I', 'R'))			continue;				rev_min = *(p + 4);		rev_maj = *(p + 5);		tablesize = *(u_int16_t *)(p + 6);		cksum = 0;		for (i = 0; i < tablesize; i++)			cksum += *(unsigned char *)(p + i);		printf("%s: PCI IRQ Routing Table rev. %d.%d found at 0x%lx, "		    "size %d bytes (%d entries)\n",		    sc->sc_dev.dv_xname, rev_maj, rev_min, pa,		    tablesize, (tablesize - 32) / 16);		if (cksum != 0) {			printf("%s: bad IRQ table checksum\n",			    sc->sc_dev.dv_xname);			continue;		}		if (tablesize < 32 || (tablesize % 16) != 0) {			printf("%s: bad IRQ table size\n",			    sc->sc_dev.dv_xname);			continue;		}		if (rev_maj != 1 || rev_min != 0) {			printf("%s: unsupported IRQ table version\n",			    sc->sc_dev.dv_xname);			continue;		}		/*		 * We can handle this table!  Make a copy of it.		 */		bcopy(p, &pcibios_pir_header, 32);		pcibios_pir_table = malloc(tablesize - 32, M_DEVBUF,		    M_NOWAIT);		if (pcibios_pir_table == NULL) {			printf("%s: no memory for $PIR\n",			    sc->sc_dev.dv_xname);			return;		}		bcopy(p + 32, pcibios_pir_table, tablesize - 32);		pcibios_pir_table_nentries = (tablesize - 32) / 16;		printf("%s: PCI Interrupt Router at %03d:%02d:%01d",		    sc->sc_dev.dv_xname, pcibios_pir_header.router_bus,		    PIR_DEVFUNC_DEVICE(pcibios_pir_header.router_devfunc),		    PIR_DEVFUNC_FUNCTION(pcibios_pir_header.router_devfunc));		if (pcibios_pir_header.compat_router != 0) {			pci_devinfo(pcibios_pir_header.compat_router, 0, 0,			    devinfo);			printf(" (%s)", devinfo);		}		printf("\n");		pcibios_print_exclirq(sc);#ifdef PCIINTR_DEBUG		pcibios_print_pir_table();#endif		return;	}	/*	 * If there was no PIR table found, try using the PCI BIOS	 * Get Interrupt Routing call.	 *	 * XXX The interface to this call sucks; just allocate enough	 * XXX room for 32 entries.	 */	pcibios_pir_table_nentries = 32;	pcibios_pir_table = malloc(pcibios_pir_table_nentries *	    sizeof(*pcibios_pir_table), M_DEVBUF, M_NOWAIT);	if (pcibios_pir_table == NULL) {		printf("%s: no memory for $PIR\n",		    sc->sc_dev.dv_xname);		return;	}	if (pcibios_get_intr_routing(sc, pcibios_pir_table,	    &pcibios_pir_table_nentries,	    &pcibios_pir_header.exclusive_irq) != PCIBIOS_SUCCESS) {		printf("%s: No PCI IRQ Routing information available.\n",		    sc->sc_dev.dv_xname);		free(pcibios_pir_table, M_DEVBUF);		pcibios_pir_table = NULL;		pcibios_pir_table_nentries = 0;		return;	}	printf("%s: PCI BIOS has %d Interrupt Routing table entries\n",	    sc->sc_dev.dv_xname, pcibios_pir_table_nentries);	pcibios_print_exclirq(sc);#ifdef PCIINTR_DEBUG	pcibios_print_pir_table();#endif}