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$"); 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 45171626Scognet#include <arm/xscale/i8134x/i81342reg.h> 46171626Scognet#include <arm/xscale/i8134x/i81342var.h> 47171626Scognet 48171626Scognet#include <dev/pci/pcivar.h> 49171626Scognet#include <dev/pci/pcib_private.h> 50171626Scognet#include "pcib_if.h" 51171626Scognet 52171626Scognet#include <dev/pci/pcireg.h> 53171626Scognet 54171626Scognetstatic pcib_read_config_t i81342_pci_read_config; 55171626Scognetstatic pcib_write_config_t i81342_pci_write_config; 56171626Scognet 57171626Scognetstatic int 58171626Scogneti81342_pci_probe(device_t dev) 59171626Scognet{ 60171626Scognet struct i81342_pci_softc *sc; 61171626Scognet 62171626Scognet sc = device_get_softc(dev); 63171626Scognet if (device_get_unit(dev) == 0) { 64171626Scognet device_set_desc(dev, "i81342 PCI-X bus"); 65171626Scognet sc->sc_is_atux = 1; 66171626Scognet } else { 67171626Scognet device_set_desc(dev, "i81342 PCIe bus"); 68171626Scognet sc->sc_is_atux = 0; 69171626Scognet } 70171626Scognet return (0); 71171626Scognet} 72171626Scognet 73171626Scognet#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008 74171626Scognet#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004 75171626Scognet 76171626Scognetstatic int 77171626Scogneti81342_pci_attach(device_t dev) 78171626Scognet{ 79171626Scognet struct i81342_softc *parent_sc; 80171626Scognet struct i81342_pci_softc *sc; 81171626Scognet uint32_t memsize, memstart; 82171626Scognet uint32_t reg; 83171626Scognet int func; 84171626Scognet uint32_t busno; 85171626Scognet 86171626Scognet sc = device_get_softc(dev); 87171626Scognet parent_sc = device_get_softc(device_get_parent(dev)); 88171626Scognet sc->sc_atu_sh = sc->sc_is_atux ? parent_sc->sc_atux_sh : 89171626Scognet parent_sc->sc_atue_sh; 90171626Scognet sc->sc_st = parent_sc->sc_st; 91171626Scognet if (bus_space_read_4(sc->sc_st, parent_sc->sc_sh, IOP34X_ESSTSR0) 92171626Scognet & IOP34X_INT_SEL_PCIX) { 93171626Scognet if (sc->sc_is_atux) 94171626Scognet func = 5; 95171626Scognet else 96171626Scognet func = 0; 97171626Scognet } else { 98171626Scognet if (sc->sc_is_atux) 99171626Scognet func = 0; 100171626Scognet else 101171626Scognet func = 5; 102171626Scognet } 103171626Scognet i81342_io_bs_init(&sc->sc_pciio, sc); 104171626Scognet i81342_mem_bs_init(&sc->sc_pcimem, sc); 105171626Scognet i81342_sdram_bounds(sc->sc_st, IOP34X_VADDR, &memstart, &memsize); 106171626Scognet if (sc->sc_is_atux) { 107171626Scognet reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 108171626Scognet if (reg & ATUX_P_RSTOUT) { 109171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR, 110171626Scognet reg &~ ATUX_P_RSTOUT); 111171626Scognet DELAY(200); 112171626Scognet } 113171626Scognet } 114171626Scognet /* Setup the Inbound windows. */ 115171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR0, 0); 116171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR0, 0); 117171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, 0); 118171626Scognet 119171626Scognet /* Set the mapping Physical address <=> PCI address */ 120171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR1, 121171626Scognet memstart | PCI_MAPREG_MEM_PREFETCHABLE_MASK | 122171626Scognet PCI_MAPREG_MEM_TYPE_64BIT); 123171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR1, 0); 124171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, ~(memsize - 1) 125171626Scognet &~(0xfff)); 126171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR1, memstart); 127171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUTVR1, 0); 128171626Scognet 129171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR2, 0); 130171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR2, 0); 131171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, 0); 132171626Scognet 133171626Scognet /* Setup the Outbound IO Bar */ 134171626Scognet if (sc->sc_is_atux) 135171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR, 136171626Scognet (IOP34X_PCIX_OIOBAR >> 4) | func); 137171626Scognet else 138171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR, 139171626Scognet (IOP34X_PCIE_OIOBAR >> 4) | func); 140171626Scognet 141171626Scognet /* Setup the Outbound windows */ 142171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR0, 0); 143171626Scognet if (sc->sc_is_atux) 144171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1, 145171626Scognet (IOP34X_PCIX_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) | 146171626Scognet ATU_OUMBAR_EN); 147171626Scognet else 148171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1, 149171626Scognet (IOP34X_PCIE_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) | 150171626Scognet ATU_OUMBAR_EN); 151171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, 0); 152171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR2, 0); 153171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR3, 0); 154171626Scognet 155171626Scognet /* Enable the outbound windows. */ 156171626Scognet reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_CR); 157171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_CR, 158171626Scognet reg | ATU_CR_OUT_EN); 159171626Scognet 160171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, 161171626Scognet bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK); 162171626Scognet /* 163171626Scognet * Enable bus mastering, memory access, SERR, and parity 164171626Scognet * checking on the ATU. 165171626Scognet */ 166171626Scognet if (sc->sc_is_atux) { 167171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 168171626Scognet busno = PCIXSR_BUSNO(busno); 169171626Scognet } else { 170171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 171171626Scognet busno = PCIE_BUSNO(busno); 172171626Scognet } 173171626Scognet reg = bus_space_read_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD); 174171626Scognet reg |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN | 175171626Scognet PCIM_CMD_SERRESPEN; 176171626Scognet bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD, reg); 177171626Scognet sc->sc_busno = busno; 178171626Scognet /* Initialize memory and i/o rmans. */ 179171626Scognet sc->sc_io_rman.rm_type = RMAN_ARRAY; 180171626Scognet sc->sc_io_rman.rm_descr = "I81342 PCI I/O Ports"; 181171626Scognet if (rman_init(&sc->sc_io_rman) != 0 || 182236987Simp rman_manage_region(&sc->sc_io_rman, 183171626Scognet sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 184171626Scognet IOP34X_PCIE_OIOBAR_VADDR, 185171626Scognet (sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 186171626Scognet IOP34X_PCIE_OIOBAR_VADDR) + IOP34X_OIOBAR_SIZE) != 0) { 187179745Skevlo panic("i81342_pci_probe: failed to set up I/O rman"); 188171626Scognet } 189171626Scognet sc->sc_mem_rman.rm_type = RMAN_ARRAY; 190171626Scognet sc->sc_mem_rman.rm_descr = "I81342 PCI Memory"; 191171626Scognet if (rman_init(&sc->sc_mem_rman) != 0 || 192236987Simp rman_manage_region(&sc->sc_mem_rman, 193171626Scognet 0, 0xffffffff) != 0) { 194171626Scognet panic("i81342_pci_attach: failed to set up memory rman"); 195171626Scognet } 196171626Scognet sc->sc_irq_rman.rm_type = RMAN_ARRAY; 197171626Scognet sc->sc_irq_rman.rm_descr = "i81342 PCI IRQs"; 198171626Scognet if (sc->sc_is_atux) { 199171626Scognet if (rman_init(&sc->sc_irq_rman) != 0 || 200236987Simp rman_manage_region(&sc->sc_irq_rman, ICU_INT_XINT0, 201171626Scognet ICU_INT_XINT3) != 0) 202171626Scognet panic("i83142_pci_attach: failed to set up IRQ rman"); 203171626Scognet } else { 204171626Scognet if (rman_init(&sc->sc_irq_rman) != 0 || 205236987Simp rman_manage_region(&sc->sc_irq_rman, ICU_INT_ATUE_MA, 206171626Scognet ICU_INT_ATUE_MD) != 0) 207171626Scognet panic("i81342_pci_attach: failed to set up IRQ rman"); 208171626Scognet 209171626Scognet } 210171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, 211171626Scognet bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK); 212171626Scognet device_add_child(dev, "pci", busno); 213171626Scognet return (bus_generic_attach(dev)); 214171626Scognet} 215171626Scognet 216171626Scognetstatic int 217171626Scogneti81342_pci_maxslots(device_t dev) 218171626Scognet{ 219171626Scognet 220171626Scognet return (PCI_SLOTMAX); 221171626Scognet} 222171626Scognet 223171626Scognetstatic void 224171626Scogneti81342_pci_conf_setup(struct i81342_pci_softc *sc, int bus, int slot, int func, 225171626Scognet int reg, uint32_t *addr) 226171626Scognet{ 227171626Scognet uint32_t busno; 228171626Scognet 229171626Scognet if (sc->sc_is_atux) { 230171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 231171626Scognet busno = PCIXSR_BUSNO(busno); 232171626Scognet } else { 233171626Scognet busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 234171626Scognet busno = PCIE_BUSNO(busno); 235171626Scognet } 236171626Scognet bus &= 0xff; 237171626Scognet slot &= 0x1f; 238171626Scognet func &= 0x7; 239171626Scognet if (sc->sc_is_atux) { 240171626Scognet if (busno == bus) 241171626Scognet *addr = (1 << (slot + 16)) | (slot << 11) | 242171626Scognet (func << 8) | reg; 243171626Scognet else 244236987Simp *addr = (bus << 16) | (slot << 11) | (func << 11) | 245171626Scognet reg | 1; 246171626Scognet } else { 247171626Scognet *addr = (bus << 24) | (slot << 19) | (func << 16) | reg; 248171626Scognet if (bus != busno) 249171626Scognet *addr |= 1; 250171626Scognet } 251171626Scognet} 252171626Scognet 253171626Scognetstatic u_int32_t 254171626Scogneti81342_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 255171626Scognet u_int reg, int bytes) 256171626Scognet{ 257171626Scognet struct i81342_pci_softc *sc = device_get_softc(dev); 258171626Scognet uint32_t addr; 259171626Scognet uint32_t ret = 0; 260171626Scognet uint32_t isr; 261171626Scognet int err = 0; 262171626Scognet vm_offset_t va; 263171626Scognet 264171626Scognet i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr); 265171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ? 266171626Scognet ATUX_OCCAR : ATUE_OCCAR, addr); 267171626Scognet if (sc->sc_is_atux) 268171626Scognet va = sc->sc_atu_sh + ATUX_OCCDR; 269171626Scognet else 270171626Scognet va = sc->sc_atu_sh + ATUE_OCCDR; 271171626Scognet switch (bytes) { 272171626Scognet case 1: 273171626Scognet err = badaddr_read((void*)(va + (reg & 3)), 1, &ret); 274171626Scognet break; 275171626Scognet case 2: 276171626Scognet err = badaddr_read((void*)(va + (reg & 3)), 2, &ret); 277171626Scognet break; 278171626Scognet case 4: 279171626Scognet err = badaddr_read((void *)(va) , 4, &ret); 280171626Scognet break; 281171626Scognet default: 282171626Scognet printf("i81342_read_config: invalid size %d\n", bytes); 283171626Scognet ret = -1; 284171626Scognet } 285171626Scognet if (err) { 286171626Scognet isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR); 287171626Scognet if (sc->sc_is_atux) 288171626Scognet isr &= ATUX_ISR_ERRMSK; 289171626Scognet else 290171626Scognet isr &= ATUE_ISR_ERRMSK; 291171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, isr); 292171626Scognet ret = -1; 293171626Scognet } 294171626Scognet 295171626Scognet return (ret); 296171626Scognet} 297171626Scognet 298171626Scognetstatic void 299236987Simpi81342_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 300171626Scognet u_int reg, u_int32_t data, int bytes) 301171626Scognet{ 302171626Scognet struct i81342_pci_softc *sc = device_get_softc(dev); 303171626Scognet uint32_t addr; 304171626Scognet vm_offset_t va; 305171626Scognet 306171626Scognet i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr); 307171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ? 308171626Scognet ATUX_OCCAR : ATUE_OCCAR, addr); 309171626Scognet va = sc->sc_is_atux ? ATUX_OCCDR : ATUE_OCCDR; 310171626Scognet switch (bytes) { 311171626Scognet case 1: 312171626Scognet bus_space_write_1(sc->sc_st, sc->sc_atu_sh, va + (reg & 3) 313171626Scognet , data); 314171626Scognet break; 315171626Scognet case 2: 316171626Scognet bus_space_write_2(sc->sc_st, sc->sc_atu_sh, va + (reg & 3) 317171626Scognet , data); 318171626Scognet break; 319171626Scognet case 4: 320171626Scognet bus_space_write_4(sc->sc_st, sc->sc_atu_sh, va, data); 321171626Scognet break; 322171626Scognet default: 323171626Scognet printf("i81342_pci_write_config: Invalid size : %d\n", bytes); 324171626Scognet } 325171626Scognet 326171626Scognet 327171626Scognet} 328171626Scognet 329171626Scognetstatic struct resource * 330171626Scogneti81342_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 331171626Scognet u_long start, u_long end, u_long count, u_int flags) 332171626Scognet{ 333171626Scognet struct i81342_pci_softc *sc = device_get_softc(bus); 334171626Scognet struct resource *rv; 335171626Scognet struct rman *rm; 336171626Scognet bus_space_tag_t bt = NULL; 337171626Scognet bus_space_handle_t bh = 0; 338171626Scognet 339171626Scognet switch (type) { 340171626Scognet case SYS_RES_IRQ: 341171626Scognet rm = &sc->sc_irq_rman; 342171626Scognet break; 343171626Scognet case SYS_RES_MEMORY: 344171626Scognet rm = &sc->sc_mem_rman; 345171626Scognet bt = &sc->sc_pcimem; 346171626Scognet bh = 0; 347171626Scognet break; 348171626Scognet case SYS_RES_IOPORT: 349171626Scognet rm = &sc->sc_io_rman; 350171626Scognet bt = &sc->sc_pciio; 351171626Scognet bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 352171626Scognet IOP34X_PCIE_OIOBAR_VADDR; 353171626Scognet start += bh; 354171626Scognet end += bh; 355171626Scognet break; 356171626Scognet default: 357171626Scognet return (NULL); 358171626Scognet } 359171626Scognet 360171626Scognet rv = rman_reserve_resource(rm, start, end, count, flags, child); 361171626Scognet if (rv == NULL) 362171626Scognet return (NULL); 363171626Scognet rman_set_rid(rv, *rid); 364171626Scognet if (type != SYS_RES_IRQ) { 365171626Scognet if (type == SYS_RES_MEMORY) 366171626Scognet bh += (rman_get_start(rv)); 367171626Scognet rman_set_bustag(rv, bt); 368171626Scognet rman_set_bushandle(rv, bh); 369171626Scognet if (flags & RF_ACTIVE) { 370171626Scognet if (bus_activate_resource(child, type, *rid, rv)) { 371171626Scognet rman_release_resource(rv); 372171626Scognet return (NULL); 373171626Scognet } 374236987Simp } 375171626Scognet } 376171626Scognet return (rv); 377171626Scognet 378171626Scognet 379171626Scognet return (NULL); 380171626Scognet} 381171626Scognet 382171626Scognetstatic int 383171626Scogneti81342_pci_activate_resource(device_t bus, device_t child, int type, int rid, 384171626Scognet struct resource *r) 385171626Scognet{ 386171626Scognet u_long p; 387171626Scognet int error; 388171626Scognet 389171626Scognet if (type == SYS_RES_MEMORY) { 390171626Scognet error = bus_space_map(rman_get_bustag(r), 391171626Scognet rman_get_bushandle(r), rman_get_size(r), 0, &p); 392171626Scognet if (error) 393171626Scognet return (error); 394171626Scognet rman_set_bushandle(r, p); 395171626Scognet 396171626Scognet } 397171626Scognet return (rman_activate_resource(r)); 398171626Scognet} 399171626Scognet 400171626Scognetstatic int 401171626Scogneti81342_pci_setup_intr(device_t dev, device_t child, struct resource *ires, 402171626Scognet int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, 403171626Scognet void **cookiep) 404171626Scognet{ 405171626Scognet 406171626Scognet return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, 407171626Scognet filt, intr, arg, cookiep)); 408171626Scognet} 409171626Scognet 410171626Scognet 411171626Scognet 412171626Scognetstatic int 413171626Scogneti81342_pci_teardown_intr(device_t dev, device_t child, struct resource *res, 414171626Scognet void *cookie) 415171626Scognet{ 416171626Scognet return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie)); 417171626Scognet} 418171626Scognet 419171626Scognetstatic int 420171626Scogneti81342_pci_route_interrupt(device_t pcib, device_t dev, int pin) 421171626Scognet{ 422171626Scognet struct i81342_pci_softc *sc; 423171626Scognet int device; 424171626Scognet 425171626Scognet device = pci_get_slot(dev); 426171626Scognet sc = device_get_softc(pcib); 427171626Scognet /* XXX: Is board specific */ 428171626Scognet if (sc->sc_is_atux) { 429171626Scognet /* PCI-X */ 430171626Scognet switch(device) { 431171626Scognet case 1: 432171626Scognet switch (pin) { 433171626Scognet case 1: 434171626Scognet return (ICU_INT_XINT1); 435171626Scognet case 2: 436171626Scognet return (ICU_INT_XINT2); 437171626Scognet case 3: 438171626Scognet return (ICU_INT_XINT3); 439171626Scognet case 4: 440171626Scognet return (ICU_INT_XINT0); 441171626Scognet default: 442171626Scognet break; 443171626Scognet } 444171626Scognet case 2: 445171626Scognet switch (pin) { 446171626Scognet case 1: 447171626Scognet return (ICU_INT_XINT2); 448171626Scognet case 2: 449171626Scognet return (ICU_INT_XINT3); 450171626Scognet case 3: 451171626Scognet return (ICU_INT_XINT2); 452171626Scognet case 4: 453171626Scognet return (ICU_INT_XINT3); 454171626Scognet default: 455171626Scognet break; 456171626Scognet } 457171626Scognet } 458171626Scognet 459171626Scognet } else { 460171626Scognet switch (pin) { 461171626Scognet case 1: 462171626Scognet return (ICU_INT_ATUE_MA); 463171626Scognet case 2: 464171626Scognet return (ICU_INT_ATUE_MB); 465171626Scognet case 3: 466171626Scognet return (ICU_INT_ATUE_MC); 467171626Scognet case 4: 468171626Scognet return (ICU_INT_ATUE_MD); 469171626Scognet default: 470171626Scognet break; 471171626Scognet } 472171626Scognet } 473171626Scognet printf("Warning: couldn't map %s IRQ for device %d pin %d\n", 474171626Scognet sc->sc_is_atux ? "PCI-X" : "PCIe", device, pin); 475171626Scognet return (-1); 476171626Scognet} 477171626Scognet 478171626Scognetstatic int 479171626Scogneti81342_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 480171626Scognet{ 481171626Scognet struct i81342_pci_softc *sc = device_get_softc(dev); 482171626Scognet switch (which) { 483172394Smarius case PCIB_IVAR_DOMAIN: 484172394Smarius *result = 0; 485172394Smarius return (0); 486171626Scognet case PCIB_IVAR_BUS: 487171626Scognet *result = sc->sc_busno; 488171626Scognet return (0); 489171626Scognet 490171626Scognet } 491171626Scognet return (ENOENT); 492171626Scognet} 493171626Scognet 494171626Scognetstatic int 495171626Scogneti81342_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 496171626Scognet{ 497171626Scognet struct i81342_pci_softc * sc = device_get_softc(dev); 498171626Scognet 499171626Scognet switch (which) { 500172394Smarius case PCIB_IVAR_DOMAIN: 501172394Smarius return (EINVAL); 502171626Scognet case PCIB_IVAR_BUS: 503171626Scognet sc->sc_busno = result; 504171626Scognet return (0); 505171626Scognet } 506171626Scognet return (ENOENT); 507171626Scognet} 508171626Scognet 509171626Scognetstatic device_method_t i81342_pci_methods[] = { 510171626Scognet /* Device interface */ 511171626Scognet DEVMETHOD(device_probe, i81342_pci_probe), 512171626Scognet DEVMETHOD(device_attach, i81342_pci_attach), 513171626Scognet DEVMETHOD(device_shutdown, bus_generic_shutdown), 514171626Scognet DEVMETHOD(device_suspend, bus_generic_suspend), 515171626Scognet DEVMETHOD(device_resume, bus_generic_resume), 516171626Scognet 517171626Scognet /* Bus interface */ 518171626Scognet DEVMETHOD(bus_read_ivar, i81342_read_ivar), 519171626Scognet DEVMETHOD(bus_write_ivar, i81342_write_ivar), 520171626Scognet DEVMETHOD(bus_alloc_resource, i81342_pci_alloc_resource), 521171626Scognet DEVMETHOD(bus_release_resource, bus_generic_release_resource), 522171626Scognet DEVMETHOD(bus_activate_resource, i81342_pci_activate_resource), 523171626Scognet DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 524171626Scognet DEVMETHOD(bus_setup_intr, i81342_pci_setup_intr), 525171626Scognet DEVMETHOD(bus_teardown_intr, i81342_pci_teardown_intr), 526171626Scognet 527171626Scognet /* pcib interface */ 528171626Scognet DEVMETHOD(pcib_maxslots, i81342_pci_maxslots), 529171626Scognet DEVMETHOD(pcib_read_config, i81342_pci_read_config), 530171626Scognet DEVMETHOD(pcib_write_config, i81342_pci_write_config), 531171626Scognet DEVMETHOD(pcib_route_interrupt, i81342_pci_route_interrupt), 532171626Scognet 533227843Smarius DEVMETHOD_END 534171626Scognet}; 535171626Scognet 536171626Scognetstatic driver_t i81342_pci_driver = { 537171626Scognet "pcib", 538171626Scognet i81342_pci_methods, 539171626Scognet sizeof(struct i81342_pci_softc), 540171626Scognet}; 541171626Scognet 542171626Scognetstatic devclass_t i81342_pci_devclass; 543171626Scognet 544171626ScognetDRIVER_MODULE(ipci, iq, i81342_pci_driver, i81342_pci_devclass, 0, 0); 545