The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/idt/idtpci.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: idtpci.c,v 1.1 2007/03/20 08:52:02 dyoung Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2007 David Young.
    5  * Copyright (c) 2007 Oleskandr Tymoshenko.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or
    8  * without modification, are permitted provided that the following
    9  * conditions are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above
   13  *    copyright notice, this list of conditions and the following
   14  *    disclaimer in the documentation and/or other materials provided
   15  *    with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote
   17  *    products derived from this software without specific prior
   18  *    written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
   21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   23  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
   25  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
   27  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
   29  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   30  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
   31  * OF SUCH DAMAGE.
   32  */
   33 /*-
   34  * Copyright (c) 2006 Itronix Inc.
   35  * All rights reserved.
   36  *
   37  * Written by Garrett D'Amore for Itronix Inc.
   38  *
   39  * Redistribution and use in source and binary forms, with or without
   40  * modification, are permitted provided that the following conditions
   41  * are met:
   42  * 1. Redistributions of source code must retain the above copyright
   43  *    notice, this list of conditions and the following disclaimer.
   44  * 2. Redistributions in binary form must reproduce the above copyright
   45  *    notice, this list of conditions and the following disclaimer in the
   46  *    documentation and/or other materials provided with the distribution.
   47  * 3. The name of Itronix Inc. may not be used to endorse
   48  *    or promote products derived from this software without specific
   49  *    prior written permission.
   50  *
   51  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
   52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   53  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   54  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
   55  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   56  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   57  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   58  * ON ANY THEORY OF LIABILITY, WHETHER IN
   59  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   60  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   61  * POSSIBILITY OF SUCH DAMAGE.
   62  */ 
   63 
   64 #include <sys/cdefs.h>
   65 __FBSDID("$FreeBSD: stable/8/sys/mips/idt/idtpci.c 230714 2012-01-29 01:22:48Z marius $");
   66 
   67 #include <sys/param.h>
   68 #include <sys/systm.h>
   69 
   70 #include <sys/bus.h>
   71 #include <sys/interrupt.h>
   72 #include <sys/malloc.h>
   73 #include <sys/kernel.h>
   74 #include <sys/module.h>
   75 #include <sys/rman.h>
   76 
   77 #include <vm/vm.h>
   78 #include <vm/pmap.h>
   79 #include <vm/vm_extern.h>
   80 
   81 #include <machine/bus.h>
   82 #include <machine/cpu.h>
   83 #include <machine/pmap.h>
   84 
   85 #include <dev/pci/pcivar.h>
   86 #include <dev/pci/pcireg.h>
   87 
   88 #include <dev/pci/pcib_private.h>
   89 #include "pcib_if.h"
   90 
   91 #include <mips/idt/idtreg.h>
   92 
   93 #ifdef IDTPCI_DEBUG
   94 int idtpci_debug = 1;
   95 #define IDTPCI_DPRINTF(__fmt, ...)              \
   96 do {                                            \
   97         if (idtpci_debug)                       \
   98                 printf((__fmt), __VA_ARGS__);   \
   99 } while (/*CONSTCOND*/0)
  100 #else /* !IDTPCI_DEBUG */
  101 #define IDTPCI_DPRINTF(__fmt, ...)      do { } while (/*CONSTCOND*/0)
  102 #endif /* IDTPCI_DEBUG */
  103 
  104 #define IDTPCI_TAG_BUS_MASK             0x007f0000
  105 #define IDTPCI_TAG_DEVICE_MASK          0x00007800
  106 #define IDTPCI_TAG_FUNCTION_MASK        0x00000300
  107 #define IDTPCI_TAG_REGISTER_MASK        0x0000007c
  108 
  109 #define IDTPCI_MAX_DEVICE
  110 
  111 #define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(IDT_BASE_PCI + (o)))
  112 #define REG_WRITE(o,v) (REG_READ(o)) = (v)
  113 
  114 unsigned int korina_fixup[24] = { 
  115         0x00000157, 0x00000000, 0x00003c04, 0x00000008, 0x18800001, 0x18000001,
  116         0x48000008, 0x00000000, 0x00000000, 0x00000000, 0x011d0214, 0x00000000,
  117         0x00000000, 0x00000000, 0x38080101, 0x00008080, 0x00000d6e, 0x00000000,
  118         0x00000051, 0x00000000, 0x00000055, 0x18000000, 0x00000000, 0x00000000 
  119 };
  120 
  121 struct idtpci_softc {
  122         device_t                sc_dev;
  123 
  124         int                     sc_busno;
  125         struct rman             sc_mem_rman[2];
  126         struct rman             sc_io_rman[2];
  127         struct rman             sc_irq_rman;
  128 };
  129 
  130 static uint32_t
  131 idtpci_make_addr(int bus, int slot, int func, int reg)
  132 {
  133 
  134         return 0x80000000 | (bus << 16) | (slot << 11) | (func << 8) | reg;
  135 }
  136 
  137 static int
  138 idtpci_probe(device_t dev)
  139 {
  140 
  141         return (0);
  142 }
  143 
  144 static int
  145 idtpci_attach(device_t dev)
  146 {
  147         int busno = 0;
  148         struct idtpci_softc *sc = device_get_softc(dev);
  149         unsigned int pci_data, force_endianess = 0;
  150         int             i;
  151         bus_addr_t      addr;
  152 
  153         sc->sc_dev = dev;
  154         sc->sc_busno = busno;
  155 
  156         /* TODO: Check for host mode */
  157 
  158         /* Enabled PCI, IG mode, EAP mode */
  159         REG_WRITE(IDT_PCI_CNTL, IDT_PCI_CNTL_IGM | IDT_PCI_CNTL_EAP |
  160             IDT_PCI_CNTL_EN);
  161         /* Wait while "Reset in progress bit" set */
  162         while(1) {
  163                 pci_data = REG_READ(IDT_PCI_STATUS);
  164                 if((pci_data & IDT_PCI_STATUS_RIP) == 0)
  165                         break;
  166         }
  167 
  168         /* Reset status register */
  169         REG_WRITE(IDT_PCI_STATUS, 0);
  170         /* Mask interrupts related to status register */
  171         REG_WRITE(IDT_PCI_STATUS_MASK, 0xffffffff);
  172 
  173         /* Disable PCI decoupled access */
  174         REG_WRITE(IDT_PCI_DAC, 0);
  175         /* Zero status and mask DA interrupts */
  176         REG_WRITE(IDT_PCI_DAS, 0);
  177         REG_WRITE(IDT_PCI_DASM, 0x7f);
  178 
  179         /* Init PCI messaging unit */
  180         /* Disable messaging interrupts */
  181         REG_WRITE(IDT_PCI_IIC, 0);
  182         REG_WRITE(IDT_PCI_IIM, 0xffffffff);
  183         REG_WRITE(IDT_PCI_OIC, 0);
  184         REG_WRITE(IDT_PCI_OIM, 0);
  185 
  186 #ifdef  __MIPSEB__
  187         force_endianess = IDT_PCI_LBA_FE;
  188 #endif
  189 
  190         /* LBA0 -- memory window */
  191         REG_WRITE(IDT_PCI_LBA0, IDT_PCIMEM0_BASE);
  192         REG_WRITE(IDT_PCI_LBA0_MAP, IDT_PCIMEM0_BASE);
  193         REG_WRITE(IDT_PCI_LBA0_CNTL, IDT_PCI_LBA_SIZE_16MB | force_endianess);
  194         pci_data = REG_READ(IDT_PCI_LBA0_CNTL); 
  195 
  196         /* LBA1 -- memory window */
  197         REG_WRITE(IDT_PCI_LBA1, IDT_PCIMEM1_BASE);
  198         REG_WRITE(IDT_PCI_LBA1_MAP, IDT_PCIMEM1_BASE);
  199         REG_WRITE(IDT_PCI_LBA1_CNTL, IDT_PCI_LBA_SIZE_256MB | force_endianess);
  200         pci_data = REG_READ(IDT_PCI_LBA1_CNTL); 
  201 
  202         /* LBA2 -- IO window */
  203         REG_WRITE(IDT_PCI_LBA2, IDT_PCIMEM2_BASE);
  204         REG_WRITE(IDT_PCI_LBA2_MAP, IDT_PCIMEM2_BASE);
  205         REG_WRITE(IDT_PCI_LBA2_CNTL, IDT_PCI_LBA_SIZE_4MB | IDT_PCI_LBA_MSI |
  206             force_endianess);
  207         pci_data = REG_READ(IDT_PCI_LBA2_CNTL); 
  208 
  209         /* LBA3 -- IO window */
  210         REG_WRITE(IDT_PCI_LBA3, IDT_PCIMEM3_BASE);
  211         REG_WRITE(IDT_PCI_LBA3_MAP, IDT_PCIMEM3_BASE);
  212         REG_WRITE(IDT_PCI_LBA3_CNTL, IDT_PCI_LBA_SIZE_1MB | IDT_PCI_LBA_MSI |
  213             force_endianess);
  214         pci_data = REG_READ(IDT_PCI_LBA3_CNTL); 
  215 
  216 
  217         pci_data = REG_READ(IDT_PCI_CNTL) & ~IDT_PCI_CNTL_TNR; 
  218         REG_WRITE(IDT_PCI_CNTL, pci_data);
  219         pci_data = REG_READ(IDT_PCI_CNTL);
  220 
  221         /* Rewrite Target Control register with default values */
  222         REG_WRITE(IDT_PCI_TC, (IDT_PCI_TC_DTIMER << 8) | IDT_PCI_TC_RTIMER);
  223 
  224         /* Perform Korina fixup */
  225         addr = idtpci_make_addr(0, 0, 0, 4);
  226         for (i = 0; i < 24; i++) {
  227 
  228                 REG_WRITE(IDT_PCI_CFG_ADDR, addr);
  229                 REG_WRITE(IDT_PCI_CFG_DATA, korina_fixup[i]);
  230                 __asm__ volatile ("sync");
  231 
  232                 REG_WRITE(IDT_PCI_CFG_ADDR, 0);
  233                 REG_WRITE(IDT_PCI_CFG_DATA, 0);
  234                 addr += 4;
  235         }
  236 
  237         /* Use KSEG1 to access IO ports for it is uncached */
  238         sc->sc_io_rman[0].rm_type = RMAN_ARRAY;
  239         sc->sc_io_rman[0].rm_descr = "IDTPCI I/O Ports window 1";
  240         if (rman_init(&sc->sc_io_rman[0]) != 0 ||
  241           rman_manage_region(&sc->sc_io_rman[0], 
  242               IDT_PCIMEM2_BASE, IDT_PCIMEM2_BASE + IDT_PCIMEM2_SIZE - 1) != 0) {
  243                 panic("idtpci_attach: failed to set up I/O rman");
  244         }
  245 
  246         sc->sc_io_rman[1].rm_type = RMAN_ARRAY;
  247         sc->sc_io_rman[1].rm_descr = "IDTPCI I/O Ports window 2";
  248         if (rman_init(&sc->sc_io_rman[1]) != 0 ||
  249           rman_manage_region(&sc->sc_io_rman[1], 
  250               IDT_PCIMEM3_BASE, IDT_PCIMEM3_BASE + IDT_PCIMEM3_SIZE - 1) != 0) {
  251                 panic("idtpci_attach: failed to set up I/O rman");
  252         }
  253 
  254         /* Use KSEG1 to access PCI memory for it is uncached */
  255         sc->sc_mem_rman[0].rm_type = RMAN_ARRAY;
  256         sc->sc_mem_rman[0].rm_descr = "IDTPCI PCI Memory window 1";
  257         if (rman_init(&sc->sc_mem_rman[0]) != 0 ||
  258             rman_manage_region(&sc->sc_mem_rman[0], 
  259             IDT_PCIMEM0_BASE, IDT_PCIMEM0_BASE + IDT_PCIMEM0_SIZE) != 0) {
  260                 panic("idtpci_attach: failed to set up memory rman");
  261         }
  262 
  263         sc->sc_mem_rman[1].rm_type = RMAN_ARRAY;
  264         sc->sc_mem_rman[1].rm_descr = "IDTPCI PCI Memory window 2";
  265         if (rman_init(&sc->sc_mem_rman[1]) != 0 ||
  266             rman_manage_region(&sc->sc_mem_rman[1], 
  267             IDT_PCIMEM1_BASE, IDT_PCIMEM1_BASE + IDT_PCIMEM1_SIZE) != 0) {
  268                 panic("idtpci_attach: failed to set up memory rman");
  269         }
  270 
  271         sc->sc_irq_rman.rm_type = RMAN_ARRAY;
  272         sc->sc_irq_rman.rm_descr = "IDTPCI PCI IRQs";
  273         if (rman_init(&sc->sc_irq_rman) != 0 ||
  274             rman_manage_region(&sc->sc_irq_rman, PCI_IRQ_BASE, 
  275                 PCI_IRQ_END) != 0)
  276                 panic("idtpci_attach: failed to set up IRQ rman");
  277 
  278         device_add_child(dev, "pci", busno);
  279         return (bus_generic_attach(dev));
  280 }
  281 
  282 static int
  283 idtpci_maxslots(device_t dev)
  284 {
  285 
  286         return (PCI_SLOTMAX);
  287 }
  288 
  289 static uint32_t
  290 idtpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
  291     int bytes)
  292 {
  293         uint32_t data;
  294         uint32_t shift, mask;
  295         bus_addr_t addr;
  296 
  297         IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, 
  298                         bus, slot, func, reg, bytes);
  299 
  300         addr = idtpci_make_addr(bus, slot, func, reg);
  301 
  302         REG_WRITE(IDT_PCI_CFG_ADDR, addr);
  303         data = REG_READ(IDT_PCI_CFG_DATA);
  304 
  305         switch (reg % 4) {
  306         case 3:
  307                 shift = 24;
  308                 break;
  309         case 2:
  310                 shift = 16;
  311                 break;
  312         case 1:
  313                 shift = 8;
  314                 break;
  315         default:
  316                 shift = 0;
  317                 break;
  318         }       
  319 
  320         switch (bytes) {
  321         case 1:
  322                 mask = 0xff;
  323                 data = (data >> shift) & mask;
  324                 break;
  325         case 2:
  326                 mask = 0xffff;
  327                 if (reg % 4 == 0)
  328                         data = data & mask;
  329                 else
  330                         data = (data >> 16) & mask;
  331                 break;
  332         case 4:
  333                 break;
  334         default:
  335                 panic("%s: wrong bytes count", __func__);
  336                 break;
  337         }
  338 
  339         __asm__ volatile ("sync");
  340         IDTPCI_DPRINTF("%s: read 0x%x\n", __func__, data);
  341 
  342         return (data);
  343 }
  344 
  345 static void
  346 idtpci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
  347     uint32_t data, int bytes)
  348 {
  349         bus_addr_t addr;
  350         uint32_t reg_data;
  351         uint32_t shift, mask;
  352 
  353         IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d) data %08x\n", __func__, 
  354                         bus, slot, func, reg, bytes, data);
  355 
  356         if (bytes != 4) {
  357                 reg_data = idtpci_read_config(dev, bus, slot, func, reg, 4);
  358 
  359                 switch (reg % 4) {
  360                 case 3:
  361                         shift = 24;
  362                         break;
  363                 case 2:
  364                         shift = 16;
  365                         break;
  366                 case 1:
  367                         shift = 8;
  368                         break;
  369                 default:
  370                         shift = 0;
  371                         break;
  372                 }       
  373 
  374                 switch (bytes) {
  375                 case 1:
  376                         mask = 0xff;
  377                         data = (reg_data & ~ (mask << shift)) | (data << shift);
  378                         break;
  379                 case 2:
  380                         mask = 0xffff;
  381                         if (reg % 4 == 0)
  382                                 data = (reg_data & ~mask) | data;
  383                         else
  384                                 data = (reg_data & ~ (mask << shift)) | 
  385                                     (data << shift);
  386                         break;
  387                 case 4:
  388                         break;
  389                 default:
  390                         panic("%s: wrong bytes count", __func__);
  391                         break;
  392                 }
  393         }
  394 
  395         addr = idtpci_make_addr(bus, slot, func, reg);
  396 
  397 
  398         REG_WRITE(IDT_PCI_CFG_ADDR, addr);
  399         REG_WRITE(IDT_PCI_CFG_DATA, data);
  400         __asm__ volatile ("sync");
  401 
  402         REG_WRITE(IDT_PCI_CFG_ADDR, 0);
  403         REG_WRITE(IDT_PCI_CFG_DATA, 0);
  404 }
  405 
  406 static int
  407 idtpci_route_interrupt(device_t pcib, device_t device, int pin)
  408 {
  409         static int idt_pci_table[2][12] =
  410         {
  411                 { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 },
  412                 { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 }
  413         };
  414         int dev, bus, irq;
  415         
  416         dev = pci_get_slot(device);
  417         bus = pci_get_bus(device);
  418         if (bootverbose)
  419                 device_printf(pcib, "routing pin %d for %s\n", pin,
  420                     device_get_nameunit(device));
  421         if (bus >= 0 && bus <= 1 &&
  422             dev >= 0 && dev <= 11) {
  423                 irq = IP_IRQ(6, idt_pci_table[bus][dev] + 4);
  424                 if (bootverbose)
  425                         printf("idtpci: %d/%d/%d -> IRQ%d\n",
  426                             pci_get_bus(device), dev, pci_get_function(device),
  427                             irq);
  428                 return (irq);
  429         } else
  430                 printf("idtpci: no mapping for %d/%d/%d\n",
  431                         pci_get_bus(device), dev, pci_get_function(device));
  432 
  433         return (-1);
  434 }
  435 
  436 static int
  437 idtpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
  438 {
  439         struct idtpci_softc *sc = device_get_softc(dev);
  440 
  441         switch (which) {
  442         case PCIB_IVAR_DOMAIN:
  443                 *result = 0;
  444                 return (0);
  445         case PCIB_IVAR_BUS:
  446                 *result = sc->sc_busno;
  447                 return (0);
  448         }
  449 
  450         return (ENOENT);
  451 }
  452 
  453 static int
  454 idtpci_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
  455 {
  456         struct idtpci_softc * sc = device_get_softc(dev);
  457 
  458         switch (which) {
  459         case PCIB_IVAR_BUS:
  460                 sc->sc_busno = result;
  461                 return (0);
  462         }
  463         return (ENOENT);
  464 }
  465 
  466 static struct resource *
  467 idtpci_alloc_resource(device_t bus, device_t child, int type, int *rid,
  468     u_long start, u_long end, u_long count, u_int flags)
  469 {
  470 
  471         struct idtpci_softc *sc = device_get_softc(bus);        
  472         struct resource *rv = NULL;
  473         struct rman *rm1, *rm2;
  474 
  475         switch (type) {
  476         case SYS_RES_IRQ:
  477                 rm1 = &sc->sc_irq_rman;
  478                 rm2 = NULL;
  479                 break;
  480         case SYS_RES_MEMORY:
  481                 rm1 = &sc->sc_mem_rman[0];
  482                 rm2 = &sc->sc_mem_rman[1];
  483                 break;
  484         case SYS_RES_IOPORT:
  485                 rm1 = &sc->sc_io_rman[0];
  486                 rm2 = &sc->sc_io_rman[1];
  487                 break;
  488         default:
  489                 return (NULL);
  490         }
  491 
  492         rv = rman_reserve_resource(rm1, start, end, count, flags, child);
  493 
  494         /* Try second window if it exists */
  495         if ((rv == NULL) && (rm2 != NULL))
  496                 rv = rman_reserve_resource(rm2, start, end, count, flags, 
  497                     child);
  498 
  499         if (rv == NULL)
  500                 return (NULL);
  501 
  502         rman_set_rid(rv, *rid);
  503 
  504         if (flags & RF_ACTIVE) {
  505                 if (bus_activate_resource(child, type, *rid, rv)) {
  506                         rman_release_resource(rv);
  507                         return (NULL);
  508                 }
  509         } 
  510 
  511         return (rv);
  512 }
  513 
  514 static int
  515 idtpci_teardown_intr(device_t dev, device_t child, struct resource *res,
  516     void *cookie)
  517 {
  518 
  519         return (intr_event_remove_handler(cookie));
  520 }
  521 
  522 static device_method_t idtpci_methods[] = {
  523         /* Device interface */
  524         DEVMETHOD(device_probe,         idtpci_probe),
  525         DEVMETHOD(device_attach,        idtpci_attach),
  526         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  527         DEVMETHOD(device_suspend,       bus_generic_suspend),
  528         DEVMETHOD(device_resume,        bus_generic_resume),
  529 
  530         /* Bus interface */
  531         DEVMETHOD(bus_read_ivar,        idtpci_read_ivar),
  532         DEVMETHOD(bus_write_ivar,       idtpci_write_ivar),
  533         DEVMETHOD(bus_alloc_resource,   idtpci_alloc_resource),
  534         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  535         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
  536         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  537         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
  538         DEVMETHOD(bus_teardown_intr,    idtpci_teardown_intr),
  539 
  540         /* pcib interface */
  541         DEVMETHOD(pcib_maxslots,        idtpci_maxslots),
  542         DEVMETHOD(pcib_read_config,     idtpci_read_config),
  543         DEVMETHOD(pcib_write_config,    idtpci_write_config),
  544         DEVMETHOD(pcib_route_interrupt, idtpci_route_interrupt),
  545 
  546         DEVMETHOD_END
  547 };
  548 
  549 static driver_t idtpci_driver = {
  550         "pcib",
  551         idtpci_methods,
  552         sizeof(struct idtpci_softc),
  553 };
  554 
  555 static devclass_t idtpci_devclass;
  556 
  557 DRIVER_MODULE(idtpci, obio, idtpci_driver, idtpci_devclass, 0, 0);

Cache object: 8619cb9afd781b1d3bb12f30dd728019


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.