i81342_pci.c revision 179745
1171626Scognet/*- 2171626Scognet * Copyright (c) 2006 Olivier Houchard 3171626Scognet * All rights reserved. 4171626Scognet * 5171626Scognet * Redistribution and use in source and binary forms, with or without 6171626Scognet * modification, are permitted provided that the following conditions 7171626Scognet * are met: 8171626Scognet * 1. Redistributions of source code must retain the above copyright 9171626Scognet * notice, this list of conditions and the following disclaimer. 10171626Scognet * 2. Redistributions in binary form must reproduce the above copyright 11171626Scognet * notice, this list of conditions and the following disclaimer in the 12171626Scognet * documentation and/or other materials provided with the distribution. 13171626Scognet * 14171626Scognet * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 15171626Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 16171626Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17171626Scognet * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 18171626Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19171626Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20171626Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21171626Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22171626Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23171626Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24171626Scognet * POSSIBILITY OF SUCH DAMAGE. 25171626Scognet */ 26171626Scognet 27171626Scognet#include <sys/cdefs.h> 28171626Scognet__FBSDID("$FreeBSD: head/sys/arm/xscale/i8134x/i81342_pci.c 179745 2008-06-12 01:46:06Z kevlo $"); 29171626Scognet 30171626Scognet#include <sys/param.h> 31171626Scognet#include <sys/systm.h> 32171626Scognet#include <sys/bus.h> 33171626Scognet#include <sys/kernel.h> 34171626Scognet#include <sys/module.h> 35171626Scognet#include <sys/types.h> 36171626Scognet#include <sys/rman.h> 37171626Scognet 38171626Scognet#include <machine/bus.h> 39171626Scognet#include <machine/cpu.h> 40171626Scognet#include <machine/pcb.h> 41171626Scognet#include <vm/vm.h> 42171626Scognet#include <vm/pmap.h> 43171626Scognet#include <vm/vm_extern.h> 44171626Scognet#include <machine/pmap.h> 45171626Scognet 46171626Scognet#include <arm/xscale/i8134x/i81342reg.h> 47171626Scognet#include <arm/xscale/i8134x/i81342var.h> 48171626Scognet 49171626Scognet#include <dev/pci/pcivar.h> 50171626Scognet#include <dev/pci/pcib_private.h> 51171626Scognet#include "pcib_if.h" 52171626Scognet 53171626Scognet#include <dev/pci/pcireg.h> 54171626Scognet 55171626Scognetstatic pcib_read_config_t i81342_pci_read_config; 56171626Scognetstatic pcib_write_config_t i81342_pci_write_config; 57171626Scognet 58171626Scognetstatic int 59171626Scogneti81342_pci_probe(device_t dev) 60171626Scognet{ 61171626Scognet struct i81342_pci_softc *sc; 62171626Scognet 63171626Scognet sc = device_get_softc(dev); 64171626Scognet if (device_get_unit(dev) == 0) { 65171626Scognet device_set_desc(dev, "i81342 PCI-X bus"); 66171626Scognet sc->sc_is_atux = 1; 67171626Scognet } else { 68171626Scognet device_set_desc(dev, "i81342 PCIe bus"); 69171626Scognet sc->sc_is_atux = 0; 70171626Scognet } 71171626Scognet return (0); 72171626Scognet} 73171626Scognet 74171626Scognet#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008 75171626Scognet#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004 76171626Scognet 77171626Scognetstatic int 78171626Scogneti81342_pci_attach(device_t dev) 79171626Scognet{ 80171626Scognet struct i81342_softc *parent_sc; 81171626Scognet struct i81342_pci_softc *sc; 82171626Scognet uint32_t memsize, memstart; 83171626Scognet uint32_t reg; 84171626Scognet int func; 85171626Scognet uint32_t busno; 86171626Scognet 87171626Scognet sc = device_get_softc(dev); 88171626Scognet parent_sc = device_get_softc(device_get_parent(dev)); 89171626Scognet sc->sc_atu_sh = sc->sc_is_atux ? parent_sc->sc_atux_sh : 90171626Scognet parent_sc->sc_atue_sh; 91171626Scognet sc->sc_st = parent_sc->sc_st; 92171626Scognet if (bus_space_read_4(sc->sc_st, parent_sc->sc_sh, IOP34X_ESSTSR0) 93171626Scognet & IOP34X_INT_SEL_PCIX) { 94171626Scognet if (sc->sc_is_atux) 95171626Scognet func = 5; 96171626Scognet else 97171626Scognet func = 0; 98171626Scognet } else { 99171626Scognet if (sc->sc_is_atux) 100171626Scognet func = 0; 101171626Scognet else 102171626Scognet func = 5; 103171626Scognet } 104171626Scognet i81342_io_bs_init(&sc->sc_pciio, sc); 105171626Scognet i81342_mem_bs_init(&sc->sc_pcimem, sc); 106171626Scognet i81342_sdram_bounds(sc->sc_st, IOP34X_VADDR, &memstart, &memsize); 107171626Scognet if (sc->sc_is_atux) { 108171626Scognet reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 109171626Scognet if (reg & ATUX_P_RSTOUT) { 110171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR, 111171626Scognet reg &~ ATUX_P_RSTOUT); 112171626Scognet DELAY(200); 113171626Scognet } 114171626Scognet } 115171626Scognet /* Setup the Inbound windows. */ 116171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR0, 0); 117171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR0, 0); 118171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, 0); 119171626Scognet 120171626Scognet /* Set the mapping Physical address <=> PCI address */ 121171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR1, 122171626Scognet memstart | PCI_MAPREG_MEM_PREFETCHABLE_MASK | 123171626Scognet PCI_MAPREG_MEM_TYPE_64BIT); 124171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR1, 0); 125171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, ~(memsize - 1) 126171626Scognet &~(0xfff)); 127171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR1, memstart); 128171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUTVR1, 0); 129171626Scognet 130171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR2, 0); 131171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR2, 0); 132171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, 0); 133171626Scognet 134171626Scognet /* Setup the Outbound IO Bar */ 135171626Scognet if (sc->sc_is_atux) 136171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR, 137171626Scognet (IOP34X_PCIX_OIOBAR >> 4) | func); 138171626Scognet else 139171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR, 140171626Scognet (IOP34X_PCIE_OIOBAR >> 4) | func); 141171626Scognet 142171626Scognet /* Setup the Outbound windows */ 143171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR0, 0); 144171626Scognet if (sc->sc_is_atux) 145171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1, 146171626Scognet (IOP34X_PCIX_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) | 147171626Scognet ATU_OUMBAR_EN); 148171626Scognet else 149171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1, 150171626Scognet (IOP34X_PCIE_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) | 151171626Scognet ATU_OUMBAR_EN); 152171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, 0); 153171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR2, 0); 154171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR3, 0); 155171626Scognet 156171626Scognet /* Enable the outbound windows. */ 157171626Scognet reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_CR); 158171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_CR, 159171626Scognet reg | ATU_CR_OUT_EN); 160171626Scognet 161171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, 162171626Scognet bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK); 163171626Scognet /* 164171626Scognet * Enable bus mastering, memory access, SERR, and parity 165171626Scognet * checking on the ATU. 166171626Scognet */ 167171626Scognet if (sc->sc_is_atux) { 168171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 169171626Scognet busno = PCIXSR_BUSNO(busno); 170171626Scognet } else { 171171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 172171626Scognet busno = PCIE_BUSNO(busno); 173171626Scognet } 174171626Scognet reg = bus_space_read_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD); 175171626Scognet reg |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN | 176171626Scognet PCIM_CMD_SERRESPEN; 177171626Scognet bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD, reg); 178171626Scognet sc->sc_busno = busno; 179171626Scognet /* Initialize memory and i/o rmans. */ 180171626Scognet sc->sc_io_rman.rm_type = RMAN_ARRAY; 181171626Scognet sc->sc_io_rman.rm_descr = "I81342 PCI I/O Ports"; 182171626Scognet if (rman_init(&sc->sc_io_rman) != 0 || 183171626Scognet rman_manage_region(&sc->sc_io_rman, 184171626Scognet sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 185171626Scognet IOP34X_PCIE_OIOBAR_VADDR, 186171626Scognet (sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 187171626Scognet IOP34X_PCIE_OIOBAR_VADDR) + IOP34X_OIOBAR_SIZE) != 0) { 188179745Skevlo panic("i81342_pci_probe: failed to set up I/O rman"); 189171626Scognet } 190171626Scognet sc->sc_mem_rman.rm_type = RMAN_ARRAY; 191171626Scognet sc->sc_mem_rman.rm_descr = "I81342 PCI Memory"; 192171626Scognet if (rman_init(&sc->sc_mem_rman) != 0 || 193171626Scognet rman_manage_region(&sc->sc_mem_rman, 194171626Scognet 0, 0xffffffff) != 0) { 195171626Scognet panic("i81342_pci_attach: failed to set up memory rman"); 196171626Scognet } 197171626Scognet sc->sc_irq_rman.rm_type = RMAN_ARRAY; 198171626Scognet sc->sc_irq_rman.rm_descr = "i81342 PCI IRQs"; 199171626Scognet if (sc->sc_is_atux) { 200171626Scognet if (rman_init(&sc->sc_irq_rman) != 0 || 201171626Scognet rman_manage_region(&sc->sc_irq_rman, ICU_INT_XINT0, 202171626Scognet ICU_INT_XINT3) != 0) 203171626Scognet panic("i83142_pci_attach: failed to set up IRQ rman"); 204171626Scognet } else { 205171626Scognet if (rman_init(&sc->sc_irq_rman) != 0 || 206171626Scognet rman_manage_region(&sc->sc_irq_rman, ICU_INT_ATUE_MA, 207171626Scognet ICU_INT_ATUE_MD) != 0) 208171626Scognet panic("i81342_pci_attach: failed to set up IRQ rman"); 209171626Scognet 210171626Scognet } 211171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, 212171626Scognet bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK); 213171626Scognet device_add_child(dev, "pci", busno); 214171626Scognet return (bus_generic_attach(dev)); 215171626Scognet} 216171626Scognet 217171626Scognetstatic int 218171626Scogneti81342_pci_maxslots(device_t dev) 219171626Scognet{ 220171626Scognet 221171626Scognet return (PCI_SLOTMAX); 222171626Scognet} 223171626Scognet 224171626Scognetstatic void 225171626Scogneti81342_pci_conf_setup(struct i81342_pci_softc *sc, int bus, int slot, int func, 226171626Scognet int reg, uint32_t *addr) 227171626Scognet{ 228171626Scognet uint32_t busno; 229171626Scognet 230171626Scognet if (sc->sc_is_atux) { 231171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 232171626Scognet busno = PCIXSR_BUSNO(busno); 233171626Scognet } else { 234171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 235171626Scognet busno = PCIE_BUSNO(busno); 236171626Scognet } 237171626Scognet bus &= 0xff; 238171626Scognet slot &= 0x1f; 239171626Scognet func &= 0x7; 240171626Scognet if (sc->sc_is_atux) { 241171626Scognet if (busno == bus) 242171626Scognet *addr = (1 << (slot + 16)) | (slot << 11) | 243171626Scognet (func << 8) | reg; 244171626Scognet else 245171626Scognet *addr = (bus << 16) | (slot << 11) | (func << 11) | 246171626Scognet reg | 1; 247171626Scognet } else { 248171626Scognet *addr = (bus << 24) | (slot << 19) | (func << 16) | reg; 249171626Scognet if (bus != busno) 250171626Scognet *addr |= 1; 251171626Scognet } 252171626Scognet} 253171626Scognet 254171626Scognetstatic u_int32_t 255171626Scogneti81342_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 256171626Scognet u_int reg, int bytes) 257171626Scognet{ 258171626Scognet struct i81342_pci_softc *sc = device_get_softc(dev); 259171626Scognet uint32_t addr; 260171626Scognet uint32_t ret = 0; 261171626Scognet uint32_t isr; 262171626Scognet int err = 0; 263171626Scognet vm_offset_t va; 264171626Scognet 265171626Scognet i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr); 266171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ? 267171626Scognet ATUX_OCCAR : ATUE_OCCAR, addr); 268171626Scognet if (sc->sc_is_atux) 269171626Scognet va = sc->sc_atu_sh + ATUX_OCCDR; 270171626Scognet else 271171626Scognet va = sc->sc_atu_sh + ATUE_OCCDR; 272171626Scognet switch (bytes) { 273171626Scognet case 1: 274171626Scognet err = badaddr_read((void*)(va + (reg & 3)), 1, &ret); 275171626Scognet break; 276171626Scognet case 2: 277171626Scognet err = badaddr_read((void*)(va + (reg & 3)), 2, &ret); 278171626Scognet break; 279171626Scognet case 4: 280171626Scognet err = badaddr_read((void *)(va) , 4, &ret); 281171626Scognet break; 282171626Scognet default: 283171626Scognet printf("i81342_read_config: invalid size %d\n", bytes); 284171626Scognet ret = -1; 285171626Scognet } 286171626Scognet if (err) { 287171626Scognet isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR); 288171626Scognet if (sc->sc_is_atux) 289171626Scognet isr &= ATUX_ISR_ERRMSK; 290171626Scognet else 291171626Scognet isr &= ATUE_ISR_ERRMSK; 292171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, isr); 293171626Scognet ret = -1; 294171626Scognet } 295171626Scognet 296171626Scognet return (ret); 297171626Scognet} 298171626Scognet 299171626Scognetstatic void 300171626Scogneti81342_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 301171626Scognet u_int reg, u_int32_t data, int bytes) 302171626Scognet{ 303171626Scognet struct i81342_pci_softc *sc = device_get_softc(dev); 304171626Scognet uint32_t addr; 305171626Scognet vm_offset_t va; 306171626Scognet 307171626Scognet i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr); 308171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ? 309171626Scognet ATUX_OCCAR : ATUE_OCCAR, addr); 310171626Scognet va = sc->sc_is_atux ? ATUX_OCCDR : ATUE_OCCDR; 311171626Scognet switch (bytes) { 312171626Scognet case 1: 313171626Scognet bus_space_write_1(sc->sc_st, sc->sc_atu_sh, va + (reg & 3) 314171626Scognet , data); 315171626Scognet break; 316171626Scognet case 2: 317171626Scognet bus_space_write_2(sc->sc_st, sc->sc_atu_sh, va + (reg & 3) 318171626Scognet , data); 319171626Scognet break; 320171626Scognet case 4: 321171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, va, data); 322171626Scognet break; 323171626Scognet default: 324171626Scognet printf("i81342_pci_write_config: Invalid size : %d\n", bytes); 325171626Scognet } 326171626Scognet 327171626Scognet 328171626Scognet} 329171626Scognet 330171626Scognetstatic struct resource * 331171626Scogneti81342_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 332171626Scognet u_long start, u_long end, u_long count, u_int flags) 333171626Scognet{ 334171626Scognet struct i81342_pci_softc *sc = device_get_softc(bus); 335171626Scognet struct resource *rv; 336171626Scognet struct rman *rm; 337171626Scognet bus_space_tag_t bt = NULL; 338171626Scognet bus_space_handle_t bh = 0; 339171626Scognet 340171626Scognet switch (type) { 341171626Scognet case SYS_RES_IRQ: 342171626Scognet rm = &sc->sc_irq_rman; 343171626Scognet break; 344171626Scognet case SYS_RES_MEMORY: 345171626Scognet rm = &sc->sc_mem_rman; 346171626Scognet bt = &sc->sc_pcimem; 347171626Scognet bh = 0; 348171626Scognet break; 349171626Scognet case SYS_RES_IOPORT: 350171626Scognet rm = &sc->sc_io_rman; 351171626Scognet bt = &sc->sc_pciio; 352171626Scognet bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 353171626Scognet IOP34X_PCIE_OIOBAR_VADDR; 354171626Scognet start += bh; 355171626Scognet end += bh; 356171626Scognet break; 357171626Scognet default: 358171626Scognet return (NULL); 359171626Scognet } 360171626Scognet 361171626Scognet rv = rman_reserve_resource(rm, start, end, count, flags, child); 362171626Scognet if (rv == NULL) 363171626Scognet return (NULL); 364171626Scognet rman_set_rid(rv, *rid); 365171626Scognet if (type != SYS_RES_IRQ) { 366171626Scognet if (type == SYS_RES_MEMORY) 367171626Scognet bh += (rman_get_start(rv)); 368171626Scognet rman_set_bustag(rv, bt); 369171626Scognet rman_set_bushandle(rv, bh); 370171626Scognet if (flags & RF_ACTIVE) { 371171626Scognet if (bus_activate_resource(child, type, *rid, rv)) { 372171626Scognet rman_release_resource(rv); 373171626Scognet return (NULL); 374171626Scognet } 375171626Scognet } 376171626Scognet } 377171626Scognet return (rv); 378171626Scognet 379171626Scognet 380171626Scognet return (NULL); 381171626Scognet} 382171626Scognet 383171626Scognetstatic int 384171626Scogneti81342_pci_activate_resource(device_t bus, device_t child, int type, int rid, 385171626Scognet struct resource *r) 386171626Scognet{ 387171626Scognet u_long p; 388171626Scognet int error; 389171626Scognet 390171626Scognet if (type == SYS_RES_MEMORY) { 391171626Scognet error = bus_space_map(rman_get_bustag(r), 392171626Scognet rman_get_bushandle(r), rman_get_size(r), 0, &p); 393171626Scognet if (error) 394171626Scognet return (error); 395171626Scognet rman_set_bushandle(r, p); 396171626Scognet 397171626Scognet } 398171626Scognet return (rman_activate_resource(r)); 399171626Scognet} 400171626Scognet 401171626Scognetstatic int 402171626Scogneti81342_pci_setup_intr(device_t dev, device_t child, struct resource *ires, 403171626Scognet int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, 404171626Scognet void **cookiep) 405171626Scognet{ 406171626Scognet 407171626Scognet return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, 408171626Scognet filt, intr, arg, cookiep)); 409171626Scognet} 410171626Scognet 411171626Scognet 412171626Scognet 413171626Scognetstatic int 414171626Scogneti81342_pci_teardown_intr(device_t dev, device_t child, struct resource *res, 415171626Scognet void *cookie) 416171626Scognet{ 417171626Scognet return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie)); 418171626Scognet} 419171626Scognet 420171626Scognetstatic int 421171626Scogneti81342_pci_route_interrupt(device_t pcib, device_t dev, int pin) 422171626Scognet{ 423171626Scognet struct i81342_pci_softc *sc; 424171626Scognet int device; 425171626Scognet 426171626Scognet device = pci_get_slot(dev); 427171626Scognet sc = device_get_softc(pcib); 428171626Scognet /* XXX: Is board specific */ 429171626Scognet if (sc->sc_is_atux) { 430171626Scognet /* PCI-X */ 431171626Scognet switch(device) { 432171626Scognet case 1: 433171626Scognet switch (pin) { 434171626Scognet case 1: 435171626Scognet return (ICU_INT_XINT1); 436171626Scognet case 2: 437171626Scognet return (ICU_INT_XINT2); 438171626Scognet case 3: 439171626Scognet return (ICU_INT_XINT3); 440171626Scognet case 4: 441171626Scognet return (ICU_INT_XINT0); 442171626Scognet default: 443171626Scognet break; 444171626Scognet } 445171626Scognet case 2: 446171626Scognet switch (pin) { 447171626Scognet case 1: 448171626Scognet return (ICU_INT_XINT2); 449171626Scognet case 2: 450171626Scognet return (ICU_INT_XINT3); 451171626Scognet case 3: 452171626Scognet return (ICU_INT_XINT2); 453171626Scognet case 4: 454171626Scognet return (ICU_INT_XINT3); 455171626Scognet default: 456171626Scognet break; 457171626Scognet } 458171626Scognet } 459171626Scognet 460171626Scognet } else { 461171626Scognet switch (pin) { 462171626Scognet case 1: 463171626Scognet return (ICU_INT_ATUE_MA); 464171626Scognet case 2: 465171626Scognet return (ICU_INT_ATUE_MB); 466171626Scognet case 3: 467171626Scognet return (ICU_INT_ATUE_MC); 468171626Scognet case 4: 469171626Scognet return (ICU_INT_ATUE_MD); 470171626Scognet default: 471171626Scognet break; 472171626Scognet } 473171626Scognet } 474171626Scognet printf("Warning: couldn't map %s IRQ for device %d pin %d\n", 475171626Scognet sc->sc_is_atux ? "PCI-X" : "PCIe", device, pin); 476171626Scognet return (-1); 477171626Scognet} 478171626Scognet 479171626Scognetstatic int 480171626Scogneti81342_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 481171626Scognet{ 482171626Scognet struct i81342_pci_softc *sc = device_get_softc(dev); 483171626Scognet switch (which) { 484172394Smarius case PCIB_IVAR_DOMAIN: 485172394Smarius *result = 0; 486172394Smarius return (0); 487171626Scognet case PCIB_IVAR_BUS: 488171626Scognet *result = sc->sc_busno; 489171626Scognet return (0); 490171626Scognet 491171626Scognet } 492171626Scognet return (ENOENT); 493171626Scognet} 494171626Scognet 495171626Scognetstatic int 496171626Scogneti81342_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 497171626Scognet{ 498171626Scognet struct i81342_pci_softc * sc = device_get_softc(dev); 499171626Scognet 500171626Scognet switch (which) { 501172394Smarius case PCIB_IVAR_DOMAIN: 502172394Smarius return (EINVAL); 503171626Scognet case PCIB_IVAR_BUS: 504171626Scognet sc->sc_busno = result; 505171626Scognet return (0); 506171626Scognet } 507171626Scognet return (ENOENT); 508171626Scognet} 509171626Scognet 510171626Scognetstatic device_method_t i81342_pci_methods[] = { 511171626Scognet /* Device interface */ 512171626Scognet DEVMETHOD(device_probe, i81342_pci_probe), 513171626Scognet DEVMETHOD(device_attach, i81342_pci_attach), 514171626Scognet DEVMETHOD(device_shutdown, bus_generic_shutdown), 515171626Scognet DEVMETHOD(device_suspend, bus_generic_suspend), 516171626Scognet DEVMETHOD(device_resume, bus_generic_resume), 517171626Scognet 518171626Scognet /* Bus interface */ 519171626Scognet DEVMETHOD(bus_print_child, bus_generic_print_child), 520171626Scognet DEVMETHOD(bus_read_ivar, i81342_read_ivar), 521171626Scognet DEVMETHOD(bus_write_ivar, i81342_write_ivar), 522171626Scognet DEVMETHOD(bus_alloc_resource, i81342_pci_alloc_resource), 523171626Scognet DEVMETHOD(bus_release_resource, bus_generic_release_resource), 524171626Scognet DEVMETHOD(bus_activate_resource, i81342_pci_activate_resource), 525171626Scognet DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 526171626Scognet DEVMETHOD(bus_setup_intr, i81342_pci_setup_intr), 527171626Scognet DEVMETHOD(bus_teardown_intr, i81342_pci_teardown_intr), 528171626Scognet 529171626Scognet /* pcib interface */ 530171626Scognet DEVMETHOD(pcib_maxslots, i81342_pci_maxslots), 531171626Scognet DEVMETHOD(pcib_read_config, i81342_pci_read_config), 532171626Scognet DEVMETHOD(pcib_write_config, i81342_pci_write_config), 533171626Scognet DEVMETHOD(pcib_route_interrupt, i81342_pci_route_interrupt), 534171626Scognet 535171626Scognet {0, 0} 536171626Scognet}; 537171626Scognet 538171626Scognetstatic driver_t i81342_pci_driver = { 539171626Scognet "pcib", 540171626Scognet i81342_pci_methods, 541171626Scognet sizeof(struct i81342_pci_softc), 542171626Scognet}; 543171626Scognet 544171626Scognetstatic devclass_t i81342_pci_devclass; 545171626Scognet 546171626ScognetDRIVER_MODULE(ipci, iq, i81342_pci_driver, i81342_pci_devclass, 0, 0); 547