Home | History | Annotate | Line # | Download | only in pci
bandit.c revision 1.8.2.2
      1  1.8.2.2   perry /*	$NetBSD: bandit.c,v 1.8.2.2 1999/05/06 19:38:49 perry Exp $	*/
      2  1.8.2.1   perry 
      3  1.8.2.1   perry /*-
      4  1.8.2.1   perry  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  1.8.2.1   perry  * All rights reserved.
      6  1.8.2.1   perry  *
      7  1.8.2.1   perry  * This code is derived from software contributed to The NetBSD Foundation
      8  1.8.2.1   perry  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  1.8.2.1   perry  * NASA Ames Research Center.
     10  1.8.2.1   perry  *
     11  1.8.2.1   perry  * Redistribution and use in source and binary forms, with or without
     12  1.8.2.1   perry  * modification, are permitted provided that the following conditions
     13  1.8.2.1   perry  * are met:
     14  1.8.2.1   perry  * 1. Redistributions of source code must retain the above copyright
     15  1.8.2.1   perry  *    notice, this list of conditions and the following disclaimer.
     16  1.8.2.1   perry  * 2. Redistributions in binary form must reproduce the above copyright
     17  1.8.2.1   perry  *    notice, this list of conditions and the following disclaimer in the
     18  1.8.2.1   perry  *    documentation and/or other materials provided with the distribution.
     19  1.8.2.1   perry  * 3. All advertising materials mentioning features or use of this software
     20  1.8.2.1   perry  *    must display the following acknowledgement:
     21  1.8.2.1   perry  *	This product includes software developed by the NetBSD
     22  1.8.2.1   perry  *	Foundation, Inc. and its contributors.
     23  1.8.2.1   perry  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24  1.8.2.1   perry  *    contributors may be used to endorse or promote products derived
     25  1.8.2.1   perry  *    from this software without specific prior written permission.
     26  1.8.2.1   perry  *
     27  1.8.2.1   perry  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28  1.8.2.1   perry  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29  1.8.2.1   perry  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30  1.8.2.1   perry  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31  1.8.2.1   perry  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  1.8.2.1   perry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  1.8.2.1   perry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  1.8.2.1   perry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  1.8.2.1   perry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  1.8.2.1   perry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  1.8.2.1   perry  * POSSIBILITY OF SUCH DAMAGE.
     38  1.8.2.1   perry  */
     39      1.1  tsubai 
     40      1.1  tsubai /*
     41      1.3  tsubai  * Copyright 1991-1998 by Open Software Foundation, Inc.
     42      1.1  tsubai  *              All Rights Reserved
     43      1.1  tsubai  *
     44      1.1  tsubai  * Permission to use, copy, modify, and distribute this software and
     45      1.1  tsubai  * its documentation for any purpose and without fee is hereby granted,
     46      1.1  tsubai  * provided that the above copyright notice appears in all copies and
     47      1.1  tsubai  * that both the copyright notice and this permission notice appear in
     48      1.1  tsubai  * supporting documentation.
     49      1.1  tsubai  *
     50      1.1  tsubai  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
     51      1.1  tsubai  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     52      1.1  tsubai  * FOR A PARTICULAR PURPOSE.
     53      1.1  tsubai  *
     54      1.1  tsubai  * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
     55      1.1  tsubai  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     56      1.1  tsubai  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
     57      1.1  tsubai  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     58      1.1  tsubai  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     59      1.1  tsubai  */
     60      1.1  tsubai /*
     61      1.3  tsubai  * Copyright 1991-1998 by Apple Computer, Inc.
     62      1.1  tsubai  *              All Rights Reserved
     63      1.1  tsubai  *
     64      1.1  tsubai  * Permission to use, copy, modify, and distribute this software and
     65      1.1  tsubai  * its documentation for any purpose and without fee is hereby granted,
     66      1.1  tsubai  * provided that the above copyright notice appears in all copies and
     67      1.1  tsubai  * that both the copyright notice and this permission notice appear in
     68      1.1  tsubai  * supporting documentation.
     69      1.1  tsubai  *
     70      1.1  tsubai  * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
     71      1.1  tsubai  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     72      1.1  tsubai  * FOR A PARTICULAR PURPOSE.
     73      1.1  tsubai  *
     74      1.1  tsubai  * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
     75      1.1  tsubai  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     76      1.1  tsubai  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
     77      1.1  tsubai  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     78      1.1  tsubai  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     79      1.1  tsubai  */
     80      1.1  tsubai 
     81      1.1  tsubai #include <sys/param.h>
     82      1.1  tsubai #include <sys/device.h>
     83      1.5  tsubai #include <sys/systm.h>
     84      1.1  tsubai 
     85      1.1  tsubai #include <dev/pci/pcireg.h>
     86      1.1  tsubai #include <dev/pci/pcivar.h>
     87      1.1  tsubai #include <dev/ofw/openfirm.h>
     88  1.8.2.1   perry #include <dev/ofw/ofw_pci.h>
     89      1.1  tsubai 
     90      1.1  tsubai #include <machine/bus.h>
     91      1.1  tsubai 
     92      1.1  tsubai #define	PCI_BANDIT		11
     93      1.1  tsubai 
     94      1.1  tsubai #define	PCI_REG_BANDIT_CFG	0x40
     95      1.1  tsubai #define	PCI_REG_ADDR_MASK	0x48
     96      1.1  tsubai #define	PCI_REG_MODE_SELECT	0x50
     97      1.1  tsubai #define	PCI_REG_ARBUS_HOLDOFF	0x58
     98      1.1  tsubai 
     99      1.1  tsubai #define	PCI_MS_BYTESWAP		0x001	/* Enable Big Endian mode. (R/W)*/
    100      1.1  tsubai #define	PCI_MS_PASSATOMIC	0x002	/* PCI Bus to ARBus Lock are always allowed (R)*/
    101      1.1  tsubai #define	PCI_MS_NUMBER_MASK	0x00C	/* PCI Bus Number (R) */
    102      1.1  tsubai #define	PCI_MS_IS_SYNC		0x010	/* Is Synchronous (1) or Async (0) ? (R)*/
    103      1.1  tsubai #define	PCI_MS_VGA_SPACE	0x020	/* Map VGA I/O space  (R/W) */
    104      1.1  tsubai #define	PCI_MS_IO_COHERENT	0x040	/* I/O Coherent (R/W) */
    105      1.1  tsubai #define	PCI_MS_INT_ENABLE	0x080	/* Allow TEA or PCI Abort INT to pass to Grand Central (R/W) */
    106      1.1  tsubai 
    107      1.3  tsubai #define	BANDIT_SPECIAL_CYCLE	0xe00000	/* Special Cycle offset */
    108      1.3  tsubai 
    109      1.1  tsubai static void bandit_init __P((pci_chipset_tag_t));
    110  1.8.2.2   perry static void scan_pci_devs __P((int));
    111      1.7  tsubai static void config_slot __P((int, pci_chipset_tag_t, int));
    112      1.1  tsubai 
    113      1.1  tsubai void
    114  1.8.2.2   perry pci_init(canmap)
    115  1.8.2.2   perry 	int canmap;
    116      1.1  tsubai {
    117  1.8.2.1   perry 
    118  1.8.2.2   perry 	scan_pci_devs(canmap);
    119      1.1  tsubai }
    120      1.1  tsubai 
    121  1.8.2.1   perry static void
    122      1.1  tsubai bandit_init(pc)
    123      1.1  tsubai 	pci_chipset_tag_t pc;
    124      1.1  tsubai {
    125      1.1  tsubai 	u_int status;
    126      1.1  tsubai 	pcitag_t tag;
    127      1.1  tsubai 
    128      1.1  tsubai 	tag = pci_make_tag(pc, 0, PCI_BANDIT, 0);
    129      1.1  tsubai 	if ((pci_conf_read(pc, tag, PCI_ID_REG) & 0xffff) == 0xffff)
    130      1.1  tsubai 		return;
    131      1.1  tsubai 
    132  1.8.2.1   perry 	status = pci_conf_read(pc, tag, PCI_REG_MODE_SELECT);
    133      1.1  tsubai 
    134      1.1  tsubai 	if ((status & PCI_MS_IO_COHERENT) == 0) {
    135      1.1  tsubai 		status |= PCI_MS_IO_COHERENT;
    136      1.1  tsubai 		pci_conf_write(pc, tag, PCI_REG_MODE_SELECT, status);
    137      1.1  tsubai 	}
    138      1.1  tsubai }
    139      1.1  tsubai 
    140      1.1  tsubai 
    141  1.8.2.1   perry static void
    142  1.8.2.2   perry scan_pci_devs(canmap)
    143  1.8.2.2   perry 	int canmap;
    144      1.1  tsubai {
    145  1.8.2.1   perry 	int reglen, node, child, n, is_bandit, is_mpc106;
    146      1.1  tsubai 	char name[64];
    147  1.8.2.1   perry 	u_int32_t *p, reg[36];
    148      1.1  tsubai 
    149      1.2  tsubai 	bzero(pci_bridges, sizeof(pci_bridges));
    150      1.1  tsubai 
    151      1.1  tsubai 	node = OF_peer(0);
    152      1.1  tsubai 	node = OF_child(node);
    153      1.1  tsubai 
    154  1.8.2.1   perry 	for (n = 0; node != 0; node = OF_peer(node)) {
    155      1.1  tsubai 		if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
    156      1.1  tsubai 			continue;
    157      1.1  tsubai 
    158  1.8.2.1   perry 		is_bandit = (strcmp(name, "bandit") == 0 ||
    159  1.8.2.1   perry 			     strcmp(name, "chaos") == 0) ? 1 : 0;
    160      1.1  tsubai 
    161  1.8.2.1   perry 		/* XXX for now */
    162  1.8.2.1   perry 		is_mpc106 = (strcmp(name, "pci") == 0) ? 1 : 0;
    163      1.5  tsubai 
    164  1.8.2.1   perry 		if (is_bandit == 0 && is_mpc106 == 0)
    165  1.8.2.1   perry 			continue;
    166      1.5  tsubai 
    167  1.8.2.1   perry 		/*
    168  1.8.2.1   perry 		 * Get the "ranges" property.  We're expecting 6 32-bit
    169  1.8.2.1   perry 		 * values for each address space:
    170  1.8.2.1   perry 		 *
    171  1.8.2.1   perry 		 *	phys.hi phys.mid phys.lo host size.hi size.lo
    172  1.8.2.1   perry 		 *
    173  1.8.2.1   perry 		 * Note that the MPC106 maps PCI memory space into
    174  1.8.2.1   perry 		 * two regions, one of which has a 24-bit addressing
    175  1.8.2.1   perry 		 * mode.  We don't know the order of the "ranges"
    176  1.8.2.1   perry 		 * property, but both Address Map modes of the MPC106
    177  1.8.2.1   perry 		 * map the 32-bit memory range at a lower host address
    178  1.8.2.1   perry 		 * than the 24-bit range.  We always pick the lower
    179  1.8.2.1   perry 		 * of the memory ranges for this reason.
    180  1.8.2.1   perry 		 */
    181  1.8.2.1   perry 
    182  1.8.2.1   perry 		pci_bridges[n].memt = (bus_space_tag_t) 0xffffffff;
    183  1.8.2.1   perry 
    184  1.8.2.1   perry 		reglen = OF_getproplen(node, "ranges");
    185  1.8.2.1   perry 		if (reglen > sizeof(reg) || reglen <= 0 ||
    186  1.8.2.1   perry 		    reglen % (6 * sizeof(u_int32_t)) != 0)
    187  1.8.2.1   perry 			continue;	/* eek */
    188  1.8.2.1   perry 
    189  1.8.2.1   perry 		reglen = OF_getprop(node, "ranges", reg, sizeof(reg));
    190  1.8.2.1   perry 
    191  1.8.2.1   perry 		for (p = reg; reglen > 0;
    192  1.8.2.1   perry 		     reglen -= (6 * sizeof(u_int32_t)), p += 6) {
    193  1.8.2.1   perry 			switch (p[0] & OFW_PCI_PHYS_HI_SPACEMASK) {
    194  1.8.2.1   perry 			case OFW_PCI_PHYS_HI_SPACE_IO:
    195  1.8.2.1   perry 				pci_bridges[n].iot =
    196  1.8.2.1   perry 				    (bus_space_tag_t) p[3];
    197  1.8.2.1   perry 				break;
    198  1.8.2.1   perry 
    199  1.8.2.1   perry 			case OFW_PCI_PHYS_HI_SPACE_MEM32:
    200  1.8.2.1   perry #if 0	/* XXX XXX XXX */
    201  1.8.2.1   perry 				if (pci_bridges[n].memt >
    202  1.8.2.1   perry 				    (bus_space_tag_t)p[3])
    203  1.8.2.1   perry 					pci_bridges[n].memt =
    204  1.8.2.1   perry 					    (bus_space_tag_t) p[3];
    205  1.8.2.1   perry #else
    206  1.8.2.1   perry 				/*
    207  1.8.2.1   perry 				 * XXX The Power Mac firmware seems to
    208  1.8.2.1   perry 				 * XXX include the PCI memory space base
    209  1.8.2.1   perry 				 * XXX in the device's BARs.  We can remove
    210  1.8.2.1   perry 				 * XXX this kludge from here once we
    211  1.8.2.1   perry 				 * XXX fix the bus_space(9) implelentation.
    212  1.8.2.1   perry 				 */
    213  1.8.2.1   perry 				pci_bridges[n].memt = (bus_space_tag_t) 0;
    214  1.8.2.1   perry #endif
    215  1.8.2.1   perry 				break;
    216      1.1  tsubai 
    217  1.8.2.1   perry 			/* XXX What about OFW_PCI_PHYS_HI_SPACE_MEM64? */
    218      1.1  tsubai 			}
    219      1.1  tsubai 		}
    220      1.2  tsubai 
    221  1.8.2.1   perry 		/*
    222  1.8.2.1   perry 		 * The "bus-range" property tells us our PCI bus number.
    223  1.8.2.1   perry 		 */
    224  1.8.2.1   perry 		if (OF_getprop(node, "bus-range", reg, sizeof(reg)) != 8)
    225  1.8.2.1   perry 			continue;
    226      1.2  tsubai 
    227  1.8.2.1   perry 		pci_bridges[n].bus = reg[0];
    228  1.8.2.2   perry 		pci_bridges[n].present = 1;
    229      1.4  tsubai 
    230  1.8.2.1   perry 		/*
    231  1.8.2.1   perry 		 * Map the PCI configuration space access registers,
    232  1.8.2.1   perry 		 * and perform any PCI-Host bridge initialization.
    233  1.8.2.1   perry 		 */
    234  1.8.2.1   perry 		if (is_bandit) {
    235  1.8.2.1   perry 			/* XXX magic numbers */
    236  1.8.2.1   perry 			pci_bridges[n].pc = n;
    237  1.8.2.2   perry 			if (canmap) {
    238  1.8.2.2   perry 				if (OF_getprop(node, "reg", reg,
    239  1.8.2.2   perry 				    sizeof(reg)) != 8)
    240  1.8.2.2   perry 					continue;
    241  1.8.2.2   perry 				pci_bridges[n].addr =
    242  1.8.2.2   perry 				    mapiodev(reg[0] + 0x800000, 4);
    243  1.8.2.2   perry 				pci_bridges[n].data =
    244  1.8.2.2   perry 				    mapiodev(reg[0] + 0xc00000, 4);
    245  1.8.2.2   perry 				bandit_init(n);
    246  1.8.2.2   perry 			}
    247  1.8.2.1   perry 		} else if (is_mpc106) {
    248  1.8.2.1   perry 			/* XXX magic numbers */
    249  1.8.2.1   perry 			pci_bridges[n].pc = PCI_CHIPSET_MPC106; /* for now */
    250  1.8.2.2   perry 			if (canmap) {
    251  1.8.2.2   perry 				pci_bridges[n].addr = mapiodev(0xfec00000, 4);
    252  1.8.2.2   perry 				pci_bridges[n].data = mapiodev(0xfee00000, 4);
    253  1.8.2.2   perry 			}
    254  1.8.2.1   perry 		}
    255      1.5  tsubai 
    256  1.8.2.2   perry 		if (canmap) {
    257  1.8.2.2   perry 			/*
    258  1.8.2.2   perry 			 * Configure all of the PCI devices attached to this
    259  1.8.2.2   perry 			 * PCI-Host bridge.
    260  1.8.2.2   perry 			 */
    261  1.8.2.2   perry 			child = OF_child(node);
    262  1.8.2.2   perry 			while (child) {
    263  1.8.2.2   perry 				config_slot(child, pci_bridges[n].pc, -1);
    264  1.8.2.2   perry 				child = OF_peer(child);
    265  1.8.2.2   perry 			}
    266      1.2  tsubai 		}
    267      1.2  tsubai 
    268  1.8.2.1   perry 		/* Bridge found, increment bridge instance. */
    269  1.8.2.1   perry 		n++;
    270      1.1  tsubai 	}
    271      1.1  tsubai }
    272      1.1  tsubai 
    273  1.8.2.1   perry static void
    274      1.7  tsubai config_slot(node, pc, irq)
    275      1.1  tsubai 	int node;
    276      1.3  tsubai 	pci_chipset_tag_t pc;
    277      1.7  tsubai 	int irq;
    278      1.1  tsubai {
    279      1.1  tsubai 	pcitag_t tag;
    280  1.8.2.1   perry 	pcireg_t csr, intr;
    281  1.8.2.1   perry 	int i, sz;
    282      1.3  tsubai 	int bus, dev, func;
    283  1.8.2.1   perry 	u_int32_t reg[40], *rp;
    284      1.7  tsubai 	char name[16];
    285      1.8  tsubai 	struct {
    286  1.8.2.1   perry 		u_int32_t device;
    287  1.8.2.1   perry 		u_int32_t junk[3];
    288  1.8.2.1   perry 		u_int32_t intrnode;
    289  1.8.2.1   perry 		u_int32_t interrupt;
    290      1.8  tsubai 	} imap[16];
    291      1.7  tsubai 
    292      1.7  tsubai 	bzero(name, sizeof(name));
    293      1.7  tsubai 	OF_getprop(node, "name", name, sizeof(name));
    294      1.7  tsubai 	if (strcmp(name, "pci-bridge") == 0) {
    295      1.7  tsubai 		if (irq == -1)
    296      1.7  tsubai 			OF_getprop(node, "AAPL,interrupts", &irq, sizeof(irq));
    297      1.7  tsubai 
    298      1.7  tsubai 		node = OF_child(node);
    299      1.7  tsubai 		while (node) {
    300      1.7  tsubai 			config_slot(node, pc, irq);
    301      1.7  tsubai 			node = OF_peer(node);
    302      1.7  tsubai 		}
    303      1.7  tsubai 		return;
    304      1.7  tsubai 	}
    305      1.1  tsubai 
    306      1.3  tsubai 	sz = OF_getprop(node, "assigned-addresses", reg, sizeof(reg));
    307      1.3  tsubai 	if (sz < 4)
    308      1.1  tsubai 		return;
    309      1.1  tsubai 
    310  1.8.2.1   perry 	rp = reg;
    311  1.8.2.1   perry 	bus = (rp[0] & OFW_PCI_PHYS_HI_BUSMASK) >>
    312  1.8.2.1   perry 	    OFW_PCI_PHYS_HI_BUSSHIFT;
    313  1.8.2.1   perry 	dev = (rp[0] & OFW_PCI_PHYS_HI_DEVICEMASK) >>
    314  1.8.2.1   perry 	    OFW_PCI_PHYS_HI_DEVICESHIFT;
    315  1.8.2.1   perry 	func = (rp[0] & OFW_PCI_PHYS_HI_FUNCTIONMASK) >>
    316  1.8.2.1   perry 	    OFW_PCI_PHYS_HI_FUNCTIONSHIFT;
    317      1.3  tsubai 
    318      1.3  tsubai 	tag = pci_make_tag(pc, bus, dev, func);
    319  1.8.2.1   perry 	csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
    320      1.3  tsubai 
    321  1.8.2.1   perry 	/*
    322  1.8.2.1   perry 	 * Make sure the IO and MEM enable bits are set in the CSR.
    323  1.8.2.1   perry 	 */
    324  1.8.2.1   perry 	csr &= ~(PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE);
    325  1.8.2.1   perry 	for (; sz > 0; sz -= 5 * sizeof(u_int32_t), rp += 5) {
    326  1.8.2.1   perry 		switch (rp[0] & OFW_PCI_PHYS_HI_SPACEMASK) {
    327  1.8.2.1   perry 		case OFW_PCI_PHYS_HI_SPACE_IO:
    328      1.3  tsubai 			csr |= PCI_COMMAND_IO_ENABLE;
    329  1.8.2.1   perry 			break;
    330  1.8.2.1   perry 
    331  1.8.2.1   perry 		case OFW_PCI_PHYS_HI_SPACE_MEM32:
    332      1.3  tsubai 			csr |= PCI_COMMAND_MEM_ENABLE;
    333  1.8.2.1   perry 			break;
    334  1.8.2.1   perry 		}
    335      1.3  tsubai 	}
    336      1.3  tsubai 
    337      1.3  tsubai 	pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
    338      1.1  tsubai 
    339  1.8.2.1   perry 	/*
    340  1.8.2.1   perry 	 * Make sure the line register is programmed with the interrupt
    341  1.8.2.1   perry 	 * mapping.
    342  1.8.2.1   perry 	 */
    343      1.7  tsubai 	if (irq == -1 &&
    344      1.7  tsubai 	    OF_getprop(node, "AAPL,interrupts", &irq, sizeof(irq)) == -1 &&
    345      1.7  tsubai 	    OF_getprop(node, "interrupts", &irq, sizeof(irq)) == -1)
    346      1.7  tsubai 		return;
    347      1.1  tsubai 
    348      1.8  tsubai 	if (irq == 1) {		/* XXX */
    349      1.8  tsubai 		sz = OF_getprop(OF_parent(node), "interrupt-map",
    350  1.8.2.1   perry 		    imap, sizeof(imap));
    351      1.8  tsubai 		if (sz != -1) {
    352      1.8  tsubai 			for (i = 0; i < sz / sizeof(*imap); i++) {
    353      1.8  tsubai 				/* XXX should use interrupt-map-mask */
    354  1.8.2.1   perry 				if (((imap[i].device &
    355  1.8.2.1   perry 				      OFW_PCI_PHYS_HI_DEVICEMASK) >>
    356  1.8.2.1   perry 				     OFW_PCI_PHYS_HI_DEVICESHIFT) == dev) {
    357      1.8  tsubai 					irq = imap[i].interrupt;
    358      1.8  tsubai 					break;
    359      1.8  tsubai 				}
    360      1.8  tsubai 			}
    361      1.8  tsubai 		}
    362      1.8  tsubai 	}
    363      1.7  tsubai 
    364      1.7  tsubai 	intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
    365  1.8.2.1   perry 	intr = (intr & ~PCI_INTERRUPT_LINE_MASK) |
    366  1.8.2.1   perry 	    (irq & PCI_INTERRUPT_LINE_MASK);
    367      1.7  tsubai 	pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
    368      1.1  tsubai }
    369