1178173Simp/* $NetBSD: idtpci.c,v 1.1 2007/03/20 08:52:02 dyoung Exp $ */ 2178173Simp 3178173Simp/*- 4178173Simp * Copyright (c) 2007 David Young. 5178173Simp * Copyright (c) 2007 Oleskandr Tymoshenko. All rights reserved. 6178173Simp * 7178173Simp * Redistribution and use in source and binary forms, with or 8178173Simp * without modification, are permitted provided that the following 9178173Simp * conditions are met: 10178173Simp * 1. Redistributions of source code must retain the above copyright 11178173Simp * notice, this list of conditions and the following disclaimer. 12178173Simp * 2. Redistributions in binary form must reproduce the above 13178173Simp * copyright notice, this list of conditions and the following 14178173Simp * disclaimer in the documentation and/or other materials provided 15178173Simp * with the distribution. 16178173Simp * 3. The name of the author may not be used to endorse or promote 17178173Simp * products derived from this software without specific prior 18178173Simp * written permission. 19178173Simp * 20178173Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 21178173Simp * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22178173Simp * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23178173Simp * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 24178173Simp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25178173Simp * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26178173Simp * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27178173Simp * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28178173Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 29178173Simp * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30178173Simp * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31178173Simp * OF SUCH DAMAGE. 32178173Simp */ 33178173Simp/*- 34178173Simp * Copyright (c) 2006 Itronix Inc. 35178173Simp * All rights reserved. 36178173Simp * 37178173Simp * Written by Garrett D'Amore for Itronix Inc. 38178173Simp * 39178173Simp * Redistribution and use in source and binary forms, with or without 40178173Simp * modification, are permitted provided that the following conditions 41178173Simp * are met: 42178173Simp * 1. Redistributions of source code must retain the above copyright 43178173Simp * notice, this list of conditions and the following disclaimer. 44178173Simp * 2. Redistributions in binary form must reproduce the above copyright 45178173Simp * notice, this list of conditions and the following disclaimer in the 46178173Simp * documentation and/or other materials provided with the distribution. 47178173Simp * 3. The name of Itronix Inc. may not be used to endorse 48178173Simp * or promote products derived from this software without specific 49178173Simp * prior written permission. 50178173Simp * 51178173Simp * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 52178173Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53178173Simp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54178173Simp * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 55178173Simp * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 56178173Simp * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57178173Simp * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 58178173Simp * ON ANY THEORY OF LIABILITY, WHETHER IN 59178173Simp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60178173Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61178173Simp * POSSIBILITY OF SUCH DAMAGE. 62178173Simp */ 63178173Simp 64178173Simp#include <sys/cdefs.h> 65178173Simp__FBSDID("$FreeBSD$"); 66178173Simp 67178173Simp#include <sys/param.h> 68178173Simp#include <sys/systm.h> 69178173Simp 70178173Simp#include <sys/bus.h> 71178173Simp#include <sys/interrupt.h> 72178173Simp#include <sys/malloc.h> 73178173Simp#include <sys/kernel.h> 74178173Simp#include <sys/module.h> 75178173Simp#include <sys/rman.h> 76178173Simp 77178173Simp#include <vm/vm.h> 78178173Simp#include <vm/pmap.h> 79178173Simp#include <vm/vm_extern.h> 80178173Simp 81178173Simp#include <machine/bus.h> 82178173Simp#include <machine/cpu.h> 83178173Simp 84178173Simp#include <dev/pci/pcivar.h> 85178173Simp#include <dev/pci/pcireg.h> 86178173Simp 87178173Simp#include <dev/pci/pcib_private.h> 88178173Simp#include "pcib_if.h" 89178173Simp 90182901Sgonzo#include <mips/idt/idtreg.h> 91178173Simp 92178173Simp#ifdef IDTPCI_DEBUG 93178173Simpint idtpci_debug = 1; 94178173Simp#define IDTPCI_DPRINTF(__fmt, ...) \ 95178173Simpdo { \ 96178173Simp if (idtpci_debug) \ 97178173Simp printf((__fmt), __VA_ARGS__); \ 98178173Simp} while (/*CONSTCOND*/0) 99178173Simp#else /* !IDTPCI_DEBUG */ 100178173Simp#define IDTPCI_DPRINTF(__fmt, ...) do { } while (/*CONSTCOND*/0) 101178173Simp#endif /* IDTPCI_DEBUG */ 102178173Simp 103178173Simp#define IDTPCI_TAG_BUS_MASK 0x007f0000 104178173Simp#define IDTPCI_TAG_DEVICE_MASK 0x00007800 105178173Simp#define IDTPCI_TAG_FUNCTION_MASK 0x00000300 106178173Simp#define IDTPCI_TAG_REGISTER_MASK 0x0000007c 107178173Simp 108178173Simp#define IDTPCI_MAX_DEVICE 109178173Simp 110178173Simp#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(IDT_BASE_PCI + (o))) 111178173Simp#define REG_WRITE(o,v) (REG_READ(o)) = (v) 112178173Simp 113178173Simpunsigned int korina_fixup[24] = { 114178173Simp 0x00000157, 0x00000000, 0x00003c04, 0x00000008, 0x18800001, 0x18000001, 115178173Simp 0x48000008, 0x00000000, 0x00000000, 0x00000000, 0x011d0214, 0x00000000, 116178173Simp 0x00000000, 0x00000000, 0x38080101, 0x00008080, 0x00000d6e, 0x00000000, 117178173Simp 0x00000051, 0x00000000, 0x00000055, 0x18000000, 0x00000000, 0x00000000 118178173Simp}; 119178173Simp 120178173Simpstruct idtpci_softc { 121178173Simp device_t sc_dev; 122178173Simp 123178173Simp int sc_busno; 124178173Simp struct rman sc_mem_rman[2]; 125178173Simp struct rman sc_io_rman[2]; 126178173Simp struct rman sc_irq_rman; 127178173Simp}; 128178173Simp 129178173Simpstatic uint32_t 130178173Simpidtpci_make_addr(int bus, int slot, int func, int reg) 131178173Simp{ 132178173Simp 133178173Simp return 0x80000000 | (bus << 16) | (slot << 11) | (func << 8) | reg; 134178173Simp} 135178173Simp 136178173Simpstatic int 137178173Simpidtpci_probe(device_t dev) 138178173Simp{ 139178173Simp 140178173Simp return (0); 141178173Simp} 142178173Simp 143178173Simpstatic int 144178173Simpidtpci_attach(device_t dev) 145178173Simp{ 146178173Simp int busno = 0; 147178173Simp struct idtpci_softc *sc = device_get_softc(dev); 148178173Simp unsigned int pci_data, force_endianess = 0; 149178173Simp int i; 150178173Simp bus_addr_t addr; 151178173Simp 152178173Simp sc->sc_dev = dev; 153178173Simp sc->sc_busno = busno; 154178173Simp 155178173Simp /* TODO: Check for host mode */ 156178173Simp 157178173Simp /* Enabled PCI, IG mode, EAP mode */ 158178173Simp REG_WRITE(IDT_PCI_CNTL, IDT_PCI_CNTL_IGM | IDT_PCI_CNTL_EAP | 159178173Simp IDT_PCI_CNTL_EN); 160178173Simp /* Wait while "Reset in progress bit" set */ 161178173Simp while(1) { 162178173Simp pci_data = REG_READ(IDT_PCI_STATUS); 163178173Simp if((pci_data & IDT_PCI_STATUS_RIP) == 0) 164178173Simp break; 165178173Simp } 166178173Simp 167178173Simp /* Reset status register */ 168178173Simp REG_WRITE(IDT_PCI_STATUS, 0); 169178173Simp /* Mask interrupts related to status register */ 170178173Simp REG_WRITE(IDT_PCI_STATUS_MASK, 0xffffffff); 171178173Simp 172178173Simp /* Disable PCI decoupled access */ 173178173Simp REG_WRITE(IDT_PCI_DAC, 0); 174178173Simp /* Zero status and mask DA interrupts */ 175178173Simp REG_WRITE(IDT_PCI_DAS, 0); 176178173Simp REG_WRITE(IDT_PCI_DASM, 0x7f); 177178173Simp 178178173Simp /* Init PCI messaging unit */ 179178173Simp /* Disable messaging interrupts */ 180178173Simp REG_WRITE(IDT_PCI_IIC, 0); 181178173Simp REG_WRITE(IDT_PCI_IIM, 0xffffffff); 182178173Simp REG_WRITE(IDT_PCI_OIC, 0); 183178173Simp REG_WRITE(IDT_PCI_OIM, 0); 184178173Simp 185178173Simp#ifdef __MIPSEB__ 186178173Simp force_endianess = IDT_PCI_LBA_FE; 187178173Simp#endif 188178173Simp 189178173Simp /* LBA0 -- memory window */ 190178173Simp REG_WRITE(IDT_PCI_LBA0, IDT_PCIMEM0_BASE); 191178173Simp REG_WRITE(IDT_PCI_LBA0_MAP, IDT_PCIMEM0_BASE); 192178173Simp REG_WRITE(IDT_PCI_LBA0_CNTL, IDT_PCI_LBA_SIZE_16MB | force_endianess); 193178173Simp pci_data = REG_READ(IDT_PCI_LBA0_CNTL); 194178173Simp 195178173Simp /* LBA1 -- memory window */ 196178173Simp REG_WRITE(IDT_PCI_LBA1, IDT_PCIMEM1_BASE); 197178173Simp REG_WRITE(IDT_PCI_LBA1_MAP, IDT_PCIMEM1_BASE); 198178173Simp REG_WRITE(IDT_PCI_LBA1_CNTL, IDT_PCI_LBA_SIZE_256MB | force_endianess); 199178173Simp pci_data = REG_READ(IDT_PCI_LBA1_CNTL); 200178173Simp 201178173Simp /* LBA2 -- IO window */ 202178173Simp REG_WRITE(IDT_PCI_LBA2, IDT_PCIMEM2_BASE); 203178173Simp REG_WRITE(IDT_PCI_LBA2_MAP, IDT_PCIMEM2_BASE); 204178173Simp REG_WRITE(IDT_PCI_LBA2_CNTL, IDT_PCI_LBA_SIZE_4MB | IDT_PCI_LBA_MSI | 205178173Simp force_endianess); 206178173Simp pci_data = REG_READ(IDT_PCI_LBA2_CNTL); 207178173Simp 208178173Simp /* LBA3 -- IO window */ 209178173Simp REG_WRITE(IDT_PCI_LBA3, IDT_PCIMEM3_BASE); 210178173Simp REG_WRITE(IDT_PCI_LBA3_MAP, IDT_PCIMEM3_BASE); 211178173Simp REG_WRITE(IDT_PCI_LBA3_CNTL, IDT_PCI_LBA_SIZE_1MB | IDT_PCI_LBA_MSI | 212178173Simp force_endianess); 213178173Simp pci_data = REG_READ(IDT_PCI_LBA3_CNTL); 214178173Simp 215178173Simp 216178173Simp pci_data = REG_READ(IDT_PCI_CNTL) & ~IDT_PCI_CNTL_TNR; 217178173Simp REG_WRITE(IDT_PCI_CNTL, pci_data); 218178173Simp pci_data = REG_READ(IDT_PCI_CNTL); 219178173Simp 220178173Simp /* Rewrite Target Control register with default values */ 221178173Simp REG_WRITE(IDT_PCI_TC, (IDT_PCI_TC_DTIMER << 8) | IDT_PCI_TC_RTIMER); 222178173Simp 223178173Simp /* Perform Korina fixup */ 224178173Simp addr = idtpci_make_addr(0, 0, 0, 4); 225178173Simp for (i = 0; i < 24; i++) { 226178173Simp 227178173Simp REG_WRITE(IDT_PCI_CFG_ADDR, addr); 228178173Simp REG_WRITE(IDT_PCI_CFG_DATA, korina_fixup[i]); 229178173Simp __asm__ volatile ("sync"); 230178173Simp 231178173Simp REG_WRITE(IDT_PCI_CFG_ADDR, 0); 232178173Simp REG_WRITE(IDT_PCI_CFG_DATA, 0); 233178173Simp addr += 4; 234178173Simp } 235178173Simp 236178173Simp /* Use KSEG1 to access IO ports for it is uncached */ 237178173Simp sc->sc_io_rman[0].rm_type = RMAN_ARRAY; 238178173Simp sc->sc_io_rman[0].rm_descr = "IDTPCI I/O Ports window 1"; 239178173Simp if (rman_init(&sc->sc_io_rman[0]) != 0 || 240178173Simp rman_manage_region(&sc->sc_io_rman[0], 241178173Simp IDT_PCIMEM2_BASE, IDT_PCIMEM2_BASE + IDT_PCIMEM2_SIZE - 1) != 0) { 242178173Simp panic("idtpci_attach: failed to set up I/O rman"); 243178173Simp } 244178173Simp 245178173Simp sc->sc_io_rman[1].rm_type = RMAN_ARRAY; 246178173Simp sc->sc_io_rman[1].rm_descr = "IDTPCI I/O Ports window 2"; 247178173Simp if (rman_init(&sc->sc_io_rman[1]) != 0 || 248178173Simp rman_manage_region(&sc->sc_io_rman[1], 249178173Simp IDT_PCIMEM3_BASE, IDT_PCIMEM3_BASE + IDT_PCIMEM3_SIZE - 1) != 0) { 250178173Simp panic("idtpci_attach: failed to set up I/O rman"); 251178173Simp } 252178173Simp 253178173Simp /* Use KSEG1 to access PCI memory for it is uncached */ 254178173Simp sc->sc_mem_rman[0].rm_type = RMAN_ARRAY; 255178173Simp sc->sc_mem_rman[0].rm_descr = "IDTPCI PCI Memory window 1"; 256178173Simp if (rman_init(&sc->sc_mem_rman[0]) != 0 || 257178173Simp rman_manage_region(&sc->sc_mem_rman[0], 258178173Simp IDT_PCIMEM0_BASE, IDT_PCIMEM0_BASE + IDT_PCIMEM0_SIZE) != 0) { 259178173Simp panic("idtpci_attach: failed to set up memory rman"); 260178173Simp } 261178173Simp 262178173Simp sc->sc_mem_rman[1].rm_type = RMAN_ARRAY; 263178173Simp sc->sc_mem_rman[1].rm_descr = "IDTPCI PCI Memory window 2"; 264178173Simp if (rman_init(&sc->sc_mem_rman[1]) != 0 || 265178173Simp rman_manage_region(&sc->sc_mem_rman[1], 266178173Simp IDT_PCIMEM1_BASE, IDT_PCIMEM1_BASE + IDT_PCIMEM1_SIZE) != 0) { 267178173Simp panic("idtpci_attach: failed to set up memory rman"); 268178173Simp } 269178173Simp 270178173Simp sc->sc_irq_rman.rm_type = RMAN_ARRAY; 271178173Simp sc->sc_irq_rman.rm_descr = "IDTPCI PCI IRQs"; 272178173Simp if (rman_init(&sc->sc_irq_rman) != 0 || 273178173Simp rman_manage_region(&sc->sc_irq_rman, PCI_IRQ_BASE, 274178173Simp PCI_IRQ_END) != 0) 275178173Simp panic("idtpci_attach: failed to set up IRQ rman"); 276178173Simp 277287882Szbb device_add_child(dev, "pci", -1); 278178173Simp return (bus_generic_attach(dev)); 279178173Simp} 280178173Simp 281178173Simpstatic int 282178173Simpidtpci_maxslots(device_t dev) 283178173Simp{ 284178173Simp 285178173Simp return (PCI_SLOTMAX); 286178173Simp} 287178173Simp 288178173Simpstatic uint32_t 289194343Sbzidtpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, 290178173Simp int bytes) 291178173Simp{ 292178173Simp uint32_t data; 293178173Simp uint32_t shift, mask; 294178173Simp bus_addr_t addr; 295178173Simp 296178173Simp IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, 297178173Simp bus, slot, func, reg, bytes); 298178173Simp 299178173Simp addr = idtpci_make_addr(bus, slot, func, reg); 300178173Simp 301178173Simp REG_WRITE(IDT_PCI_CFG_ADDR, addr); 302178173Simp data = REG_READ(IDT_PCI_CFG_DATA); 303178173Simp 304178173Simp switch (reg % 4) { 305178173Simp case 3: 306178173Simp shift = 24; 307178173Simp break; 308178173Simp case 2: 309178173Simp shift = 16; 310178173Simp break; 311178173Simp case 1: 312178173Simp shift = 8; 313178173Simp break; 314178173Simp default: 315178173Simp shift = 0; 316178173Simp break; 317178173Simp } 318178173Simp 319178173Simp switch (bytes) { 320178173Simp case 1: 321178173Simp mask = 0xff; 322178173Simp data = (data >> shift) & mask; 323178173Simp break; 324178173Simp case 2: 325178173Simp mask = 0xffff; 326178173Simp if (reg % 4 == 0) 327178173Simp data = data & mask; 328178173Simp else 329178173Simp data = (data >> 16) & mask; 330178173Simp break; 331178173Simp case 4: 332178173Simp break; 333178173Simp default: 334178173Simp panic("%s: wrong bytes count", __func__); 335178173Simp break; 336178173Simp } 337178173Simp 338178173Simp __asm__ volatile ("sync"); 339178173Simp IDTPCI_DPRINTF("%s: read 0x%x\n", __func__, data); 340178173Simp 341178173Simp return (data); 342178173Simp} 343178173Simp 344178173Simpstatic void 345194343Sbzidtpci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, 346178173Simp uint32_t data, int bytes) 347178173Simp{ 348178173Simp bus_addr_t addr; 349178173Simp uint32_t reg_data; 350178173Simp uint32_t shift, mask; 351178173Simp 352178173Simp IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d) data %08x\n", __func__, 353178173Simp bus, slot, func, reg, bytes, data); 354178173Simp 355178173Simp if (bytes != 4) { 356178173Simp reg_data = idtpci_read_config(dev, bus, slot, func, reg, 4); 357178173Simp 358178173Simp switch (reg % 4) { 359178173Simp case 3: 360178173Simp shift = 24; 361178173Simp break; 362178173Simp case 2: 363178173Simp shift = 16; 364178173Simp break; 365178173Simp case 1: 366178173Simp shift = 8; 367178173Simp break; 368178173Simp default: 369178173Simp shift = 0; 370178173Simp break; 371178173Simp } 372178173Simp 373178173Simp switch (bytes) { 374178173Simp case 1: 375178173Simp mask = 0xff; 376178173Simp data = (reg_data & ~ (mask << shift)) | (data << shift); 377178173Simp break; 378178173Simp case 2: 379178173Simp mask = 0xffff; 380178173Simp if (reg % 4 == 0) 381178173Simp data = (reg_data & ~mask) | data; 382178173Simp else 383178173Simp data = (reg_data & ~ (mask << shift)) | 384178173Simp (data << shift); 385178173Simp break; 386178173Simp case 4: 387178173Simp break; 388178173Simp default: 389178173Simp panic("%s: wrong bytes count", __func__); 390178173Simp break; 391178173Simp } 392178173Simp } 393178173Simp 394178173Simp addr = idtpci_make_addr(bus, slot, func, reg); 395178173Simp 396178173Simp 397178173Simp REG_WRITE(IDT_PCI_CFG_ADDR, addr); 398178173Simp REG_WRITE(IDT_PCI_CFG_DATA, data); 399178173Simp __asm__ volatile ("sync"); 400178173Simp 401178173Simp REG_WRITE(IDT_PCI_CFG_ADDR, 0); 402178173Simp REG_WRITE(IDT_PCI_CFG_DATA, 0); 403178173Simp} 404178173Simp 405178173Simpstatic int 406178173Simpidtpci_route_interrupt(device_t pcib, device_t device, int pin) 407178173Simp{ 408178173Simp static int idt_pci_table[2][12] = 409178173Simp { 410178173Simp { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 }, 411178173Simp { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 } 412178173Simp }; 413178173Simp int dev, bus, irq; 414178173Simp 415178173Simp dev = pci_get_slot(device); 416178173Simp bus = pci_get_bus(device); 417178173Simp if (bootverbose) 418178173Simp device_printf(pcib, "routing pin %d for %s\n", pin, 419178173Simp device_get_nameunit(device)); 420178173Simp if (bus >= 0 && bus <= 1 && 421178173Simp dev >= 0 && dev <= 11) { 422178173Simp irq = IP_IRQ(6, idt_pci_table[bus][dev] + 4); 423178173Simp if (bootverbose) 424178173Simp printf("idtpci: %d/%d/%d -> IRQ%d\n", 425178173Simp pci_get_bus(device), dev, pci_get_function(device), 426178173Simp irq); 427178173Simp return (irq); 428178173Simp } else 429178173Simp printf("idtpci: no mapping for %d/%d/%d\n", 430178173Simp pci_get_bus(device), dev, pci_get_function(device)); 431178173Simp 432178173Simp return (-1); 433178173Simp} 434178173Simp 435178173Simpstatic int 436178173Simpidtpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 437178173Simp{ 438178173Simp struct idtpci_softc *sc = device_get_softc(dev); 439178173Simp 440178173Simp switch (which) { 441178173Simp case PCIB_IVAR_DOMAIN: 442178173Simp *result = 0; 443178173Simp return (0); 444178173Simp case PCIB_IVAR_BUS: 445178173Simp *result = sc->sc_busno; 446178173Simp return (0); 447178173Simp } 448178173Simp 449178173Simp return (ENOENT); 450178173Simp} 451178173Simp 452178173Simpstatic int 453178173Simpidtpci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 454178173Simp{ 455178173Simp struct idtpci_softc * sc = device_get_softc(dev); 456178173Simp 457178173Simp switch (which) { 458178173Simp case PCIB_IVAR_BUS: 459178173Simp sc->sc_busno = result; 460178173Simp return (0); 461178173Simp } 462178173Simp return (ENOENT); 463178173Simp} 464178173Simp 465178173Simpstatic struct resource * 466178173Simpidtpci_alloc_resource(device_t bus, device_t child, int type, int *rid, 467294883Sjhibbits rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 468178173Simp{ 469178173Simp 470178173Simp struct idtpci_softc *sc = device_get_softc(bus); 471178173Simp struct resource *rv = NULL; 472178173Simp struct rman *rm1, *rm2; 473178173Simp 474178173Simp switch (type) { 475178173Simp case SYS_RES_IRQ: 476178173Simp rm1 = &sc->sc_irq_rman; 477178173Simp rm2 = NULL; 478178173Simp break; 479178173Simp case SYS_RES_MEMORY: 480178173Simp rm1 = &sc->sc_mem_rman[0]; 481178173Simp rm2 = &sc->sc_mem_rman[1]; 482178173Simp break; 483178173Simp case SYS_RES_IOPORT: 484178173Simp rm1 = &sc->sc_io_rman[0]; 485178173Simp rm2 = &sc->sc_io_rman[1]; 486178173Simp break; 487178173Simp default: 488178173Simp return (NULL); 489178173Simp } 490178173Simp 491178173Simp rv = rman_reserve_resource(rm1, start, end, count, flags, child); 492178173Simp 493178173Simp /* Try second window if it exists */ 494178173Simp if ((rv == NULL) && (rm2 != NULL)) 495178173Simp rv = rman_reserve_resource(rm2, start, end, count, flags, 496178173Simp child); 497178173Simp 498178173Simp if (rv == NULL) 499178173Simp return (NULL); 500178173Simp 501178173Simp rman_set_rid(rv, *rid); 502178173Simp 503178173Simp if (flags & RF_ACTIVE) { 504178173Simp if (bus_activate_resource(child, type, *rid, rv)) { 505178173Simp rman_release_resource(rv); 506178173Simp return (NULL); 507178173Simp } 508178173Simp } 509178173Simp 510178173Simp return (rv); 511178173Simp} 512178173Simp 513178173Simpstatic int 514178173Simpidtpci_teardown_intr(device_t dev, device_t child, struct resource *res, 515178173Simp void *cookie) 516178173Simp{ 517178173Simp 518178173Simp return (intr_event_remove_handler(cookie)); 519178173Simp} 520178173Simp 521178173Simpstatic device_method_t idtpci_methods[] = { 522178173Simp /* Device interface */ 523178173Simp DEVMETHOD(device_probe, idtpci_probe), 524178173Simp DEVMETHOD(device_attach, idtpci_attach), 525178173Simp DEVMETHOD(device_shutdown, bus_generic_shutdown), 526178173Simp DEVMETHOD(device_suspend, bus_generic_suspend), 527178173Simp DEVMETHOD(device_resume, bus_generic_resume), 528178173Simp 529178173Simp /* Bus interface */ 530178173Simp DEVMETHOD(bus_read_ivar, idtpci_read_ivar), 531178173Simp DEVMETHOD(bus_write_ivar, idtpci_write_ivar), 532178173Simp DEVMETHOD(bus_alloc_resource, idtpci_alloc_resource), 533178173Simp DEVMETHOD(bus_release_resource, bus_generic_release_resource), 534178173Simp DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 535178173Simp DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 536178173Simp DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 537178173Simp DEVMETHOD(bus_teardown_intr, idtpci_teardown_intr), 538178173Simp 539178173Simp /* pcib interface */ 540178173Simp DEVMETHOD(pcib_maxslots, idtpci_maxslots), 541178173Simp DEVMETHOD(pcib_read_config, idtpci_read_config), 542178173Simp DEVMETHOD(pcib_write_config, idtpci_write_config), 543178173Simp DEVMETHOD(pcib_route_interrupt, idtpci_route_interrupt), 544178173Simp 545227843Smarius DEVMETHOD_END 546178173Simp}; 547178173Simp 548178173Simpstatic driver_t idtpci_driver = { 549178173Simp "pcib", 550178173Simp idtpci_methods, 551178173Simp sizeof(struct idtpci_softc), 552178173Simp}; 553178173Simp 554178173Simpstatic devclass_t idtpci_devclass; 555178173Simp 556178173SimpDRIVER_MODULE(idtpci, obio, idtpci_driver, idtpci_devclass, 0, 0); 557