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/atheros/ar71xx_pci.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice unmodified, this list of conditions, and the following
   10  *    disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 
   34 #include <sys/bus.h>
   35 #include <sys/interrupt.h>
   36 #include <sys/malloc.h>
   37 #include <sys/kernel.h>
   38 #include <sys/module.h>
   39 #include <sys/rman.h>
   40 
   41 #include <vm/vm.h>
   42 #include <vm/pmap.h>
   43 #include <vm/vm_extern.h>
   44 
   45 #include <machine/bus.h>
   46 #include <machine/cpu.h>
   47 #include <machine/intr_machdep.h>
   48 #include <machine/pmap.h>
   49 
   50 #include <dev/pci/pcivar.h>
   51 #include <dev/pci/pcireg.h>
   52 
   53 #include <dev/pci/pcib_private.h>
   54 #include "pcib_if.h"
   55 
   56 #include <mips/atheros/ar71xxreg.h>
   57 #include <mips/atheros/ar71xx_pci_bus_space.h>
   58 
   59 #include <mips/atheros/ar71xx_cpudef.h>
   60 
   61 #undef AR71XX_PCI_DEBUG
   62 #ifdef AR71XX_PCI_DEBUG
   63 #define dprintf printf
   64 #else
   65 #define dprintf(x, arg...)
   66 #endif
   67 
   68 struct ar71xx_pci_softc {
   69         device_t                sc_dev;
   70 
   71         int                     sc_busno;
   72         struct rman             sc_mem_rman;
   73         struct rman             sc_irq_rman;
   74 
   75         struct intr_event       *sc_eventstab[AR71XX_PCI_NIRQS];        
   76         mips_intrcnt_t          sc_intr_counter[AR71XX_PCI_NIRQS];      
   77         struct resource         *sc_irq;
   78         void                    *sc_ih;
   79 };
   80 
   81 static int ar71xx_pci_setup_intr(device_t, device_t, struct resource *, int, 
   82                     driver_filter_t *, driver_intr_t *, void *, void **);
   83 static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *,
   84                     void *);
   85 static int ar71xx_pci_intr(void *);
   86 
   87 static void 
   88 ar71xx_pci_mask_irq(void *source)
   89 {
   90         uint32_t reg;
   91         unsigned int irq = (unsigned int)source;
   92 
   93         reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
   94         /* flush */
   95         reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
   96         ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq));
   97 }
   98 
   99 static void 
  100 ar71xx_pci_unmask_irq(void *source)
  101 {
  102         uint32_t reg;
  103         unsigned int irq = (unsigned int)source;
  104 
  105         reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
  106         ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq));
  107         /* flush */
  108         reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
  109 }
  110 
  111 /* 
  112  * get bitmask for bytes of interest: 
  113  *   0 - we want this byte, 1 - ignore it. e.g: we read 1 byte 
  114  *   from register 7. Bitmask would be: 0111
  115  */
  116 static uint32_t
  117 ar71xx_get_bytes_to_read(int reg, int bytes)
  118 {
  119         uint32_t bytes_to_read = 0;
  120         if ((bytes % 4) == 0)
  121                 bytes_to_read = 0;
  122         else if ((bytes % 4) == 1)
  123                 bytes_to_read = (~(1 << (reg % 4))) & 0xf;
  124         else if ((bytes % 4) == 2)
  125                 bytes_to_read = (~(3 << (reg % 4))) & 0xf;
  126         else
  127                 panic("%s: wrong combination", __func__);
  128 
  129         return (bytes_to_read);
  130 }
  131 
  132 static int 
  133 ar71xx_pci_check_bus_error(void)
  134 {
  135         uint32_t error, addr, has_errors = 0;
  136         error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3;
  137         dprintf("%s: PCI error = %02x\n", __func__, error);
  138         if (error) {
  139                 addr = ATH_READ_REG(AR71XX_PCI_ERROR_ADDR);
  140 
  141                 /* Do not report it yet */
  142 #if 0
  143                 printf("PCI bus error %d at addr 0x%08x\n", error, addr);
  144 #endif
  145                 ATH_WRITE_REG(AR71XX_PCI_ERROR, error);
  146                 has_errors = 1;
  147         }
  148 
  149         error = ATH_READ_REG(AR71XX_PCI_AHB_ERROR) & 0x1;
  150         dprintf("%s: AHB error = %02x\n", __func__, error);
  151         if (error) {
  152                 addr = ATH_READ_REG(AR71XX_PCI_AHB_ERROR_ADDR);
  153                 /* Do not report it yet */
  154 #if 0
  155                 printf("AHB bus error %d at addr 0x%08x\n", error, addr);
  156 #endif
  157                 ATH_WRITE_REG(AR71XX_PCI_AHB_ERROR, error);
  158                 has_errors = 1;
  159         }
  160 
  161         return (has_errors);
  162 }
  163 
  164 static uint32_t
  165 ar71xx_pci_make_addr(int bus, int slot, int func, int reg)
  166 {
  167         if (bus == 0) {
  168                 return ((1 << slot) | (func << 8) | (reg & ~3));
  169         } else {
  170                 return ((bus << 16) | (slot << 11) | (func << 8) 
  171                     | (reg  & ~3) | 1);
  172         }
  173 }
  174 
  175 static int
  176 ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes, 
  177     uint32_t cmd)
  178 {
  179         uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3));
  180         cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4);
  181         
  182         ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr);
  183         ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd);
  184 
  185         dprintf("%s: tag (%x, %x, %x) %d/%d addr=%08x, cmd=%08x\n", __func__, 
  186             bus, slot, func, reg, bytes, addr, cmd);
  187 
  188         return ar71xx_pci_check_bus_error();
  189 }
  190 
  191 static uint32_t
  192 ar71xx_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 
  193     u_int reg, int bytes)
  194 {
  195         uint32_t data;
  196         uint32_t cmd, shift, mask;
  197 
  198         /* register access is 32-bit aligned */
  199         shift = (reg & 3) * 8;
  200         if (shift)
  201                 mask = (1 << shift) - 1;
  202         else
  203                 mask = 0xffffffff;
  204 
  205         dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 
  206             func, reg, bytes);
  207 
  208         if ((bus == 0) && (slot == 0) && (func == 0)) {
  209                 cmd = PCI_LCONF_CMD_READ | (reg & ~3);
  210                 ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd);
  211                 data = ATH_READ_REG(AR71XX_PCI_LCONF_READ_DATA);
  212         } else {
  213                  if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, 
  214                      PCI_CONF_CMD_READ) == 0)
  215                          data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA);
  216                  else
  217                          data = -1;
  218         }
  219 
  220         /* get request bytes from 32-bit word */
  221         data = (data >> shift) & mask;
  222 
  223         dprintf("%s: read 0x%x\n", __func__, data);
  224 
  225         return (data);
  226 }
  227 
  228 static void
  229 ar71xx_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 
  230     u_int reg, uint32_t data, int bytes)
  231 {
  232         uint32_t cmd;
  233 
  234         dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 
  235             func, reg, bytes);
  236 
  237         data = data << (8*(reg % 4));
  238 
  239         if ((bus == 0) && (slot == 0) && (func == 0)) {
  240                 cmd = PCI_LCONF_CMD_WRITE | (reg & ~3);
  241                 cmd |= ar71xx_get_bytes_to_read(reg, bytes) << 20;
  242                 ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd);
  243                 ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data);
  244         } else {
  245                  if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, 
  246                      PCI_CONF_CMD_WRITE) == 0)
  247                          ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data);
  248         }
  249 }
  250 
  251 static int
  252 ar71xx_pci_probe(device_t dev)
  253 {
  254 
  255         return (0);
  256 }
  257 
  258 static int
  259 ar71xx_pci_attach(device_t dev)
  260 {
  261         int busno = 0;
  262         int rid = 0;
  263         struct ar71xx_pci_softc *sc = device_get_softc(dev);
  264 
  265         sc->sc_mem_rman.rm_type = RMAN_ARRAY;
  266         sc->sc_mem_rman.rm_descr = "ar71xx PCI memory window";
  267         if (rman_init(&sc->sc_mem_rman) != 0 || 
  268             rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE, 
  269                 AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) {
  270                 panic("ar71xx_pci_attach: failed to set up I/O rman");
  271         }
  272 
  273         sc->sc_irq_rman.rm_type = RMAN_ARRAY;
  274         sc->sc_irq_rman.rm_descr = "ar71xx PCI IRQs";
  275         if (rman_init(&sc->sc_irq_rman) != 0 ||
  276             rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, 
  277                 AR71XX_PCI_IRQ_END) != 0)
  278                 panic("ar71xx_pci_attach: failed to set up IRQ rman");
  279 
  280 
  281         ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0);
  282         ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0);
  283 
  284         /* Hook up our interrupt handler. */
  285         if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  286             RF_SHAREABLE | RF_ACTIVE)) == NULL) {
  287                 device_printf(dev, "unable to allocate IRQ resource\n");
  288                 return ENXIO;
  289         }
  290 
  291         if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC,
  292                             ar71xx_pci_intr, NULL, sc, &sc->sc_ih))) {
  293                 device_printf(dev, 
  294                     "WARNING: unable to register interrupt handler\n");
  295                 return ENXIO;
  296         }
  297 
  298         /* reset PCI core and PCI bus */
  299         ar71xx_device_stop(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS);
  300         DELAY(100000);
  301 
  302         ar71xx_device_start(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS);
  303         DELAY(100000);
  304 
  305         /* Init PCI windows */
  306         ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR);
  307         ATH_WRITE_REG(AR71XX_PCI_WINDOW1, PCI_WINDOW1_ADDR);
  308         ATH_WRITE_REG(AR71XX_PCI_WINDOW2, PCI_WINDOW2_ADDR);
  309         ATH_WRITE_REG(AR71XX_PCI_WINDOW3, PCI_WINDOW3_ADDR);
  310         ATH_WRITE_REG(AR71XX_PCI_WINDOW4, PCI_WINDOW4_ADDR);
  311         ATH_WRITE_REG(AR71XX_PCI_WINDOW5, PCI_WINDOW5_ADDR);
  312         ATH_WRITE_REG(AR71XX_PCI_WINDOW6, PCI_WINDOW6_ADDR);
  313         ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR);
  314         DELAY(100000);
  315 
  316         ar71xx_pci_check_bus_error();
  317 
  318         /* Fixup internal PCI bridge */
  319         ar71xx_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, 
  320             PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN 
  321             | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK
  322             | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2);
  323 
  324         device_add_child(dev, "pci", busno);
  325         return (bus_generic_attach(dev));
  326 }
  327 
  328 static int
  329 ar71xx_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
  330 {
  331         struct ar71xx_pci_softc *sc = device_get_softc(dev);
  332 
  333         switch (which) {
  334         case PCIB_IVAR_DOMAIN:
  335                 *result = 0;
  336                 return (0);
  337         case PCIB_IVAR_BUS:
  338                 *result = sc->sc_busno;
  339                 return (0);
  340         }
  341 
  342         return (ENOENT);
  343 }
  344 
  345 static int
  346 ar71xx_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
  347 {
  348         struct ar71xx_pci_softc * sc = device_get_softc(dev);
  349 
  350         switch (which) {
  351         case PCIB_IVAR_BUS:
  352                 sc->sc_busno = result;
  353                 return (0);
  354         }
  355 
  356         return (ENOENT);
  357 }
  358 
  359 static struct resource *
  360 ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
  361     u_long start, u_long end, u_long count, u_int flags)
  362 {
  363 
  364         struct ar71xx_pci_softc *sc = device_get_softc(bus);    
  365         struct resource *rv;
  366         struct rman *rm;
  367 
  368         switch (type) {
  369         case SYS_RES_IRQ:
  370                 rm = &sc->sc_irq_rman;
  371                 break;
  372         case SYS_RES_MEMORY:
  373                 rm = &sc->sc_mem_rman;
  374                 break;
  375         default:
  376                 return (NULL);
  377         }
  378 
  379         rv = rman_reserve_resource(rm, start, end, count, flags, child);
  380 
  381         if (rv == NULL)
  382                 return (NULL);
  383 
  384         rman_set_rid(rv, *rid);
  385 
  386         if (flags & RF_ACTIVE) {
  387                 if (bus_activate_resource(child, type, *rid, rv)) {
  388                         rman_release_resource(rv);
  389                         return (NULL);
  390                 }
  391         } 
  392 
  393 
  394         return (rv);
  395 }
  396 
  397 
  398 static int
  399 ar71xx_pci_activate_resource(device_t bus, device_t child, int type, int rid,
  400     struct resource *r)
  401 {
  402         int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus),
  403             child, type, rid, r));
  404 
  405         if (!res) {
  406                 switch(type) {
  407                 case SYS_RES_MEMORY:
  408                 case SYS_RES_IOPORT:
  409                         rman_set_bustag(r, ar71xx_bus_space_pcimem);
  410                         break;
  411                 }
  412         }
  413 
  414         return (res);
  415 }
  416 
  417 
  418 
  419 static int
  420 ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires,
  421                 int flags, driver_filter_t *filt, driver_intr_t *handler,
  422                 void *arg, void **cookiep)
  423 {
  424         struct ar71xx_pci_softc *sc = device_get_softc(bus);
  425         struct intr_event *event;
  426         int irq, error;
  427 
  428         irq = rman_get_start(ires);
  429 
  430         if (irq > AR71XX_PCI_IRQ_END)
  431                 panic("%s: bad irq %d", __func__, irq);
  432 
  433         event = sc->sc_eventstab[irq];
  434         if (event == NULL) {
  435                 error = intr_event_create(&event, (void *)irq, 0, irq, 
  436                     ar71xx_pci_mask_irq, ar71xx_pci_unmask_irq, NULL, NULL,
  437                     "pci intr%d:", irq);
  438 
  439                 if (error == 0) {
  440                         sc->sc_eventstab[irq] = event;
  441                         sc->sc_intr_counter[irq] =
  442                             mips_intrcnt_create(event->ie_name);
  443                 }
  444                 else
  445                         return error;
  446         }
  447 
  448         intr_event_add_handler(event, device_get_nameunit(child), filt,
  449             handler, arg, intr_priority(flags), flags, cookiep);
  450         mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname);
  451 
  452         ar71xx_pci_unmask_irq((void*)irq);
  453 
  454         return (0);
  455 }
  456 
  457 static int
  458 ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires,
  459     void *cookie)
  460 {
  461         struct ar71xx_pci_softc *sc = device_get_softc(dev);
  462         int irq, result;
  463 
  464         irq = rman_get_start(ires);
  465         if (irq > AR71XX_PCI_IRQ_END)
  466                 panic("%s: bad irq %d", __func__, irq);
  467 
  468         if (sc->sc_eventstab[irq] == NULL)
  469                 panic("Trying to teardown unoccupied IRQ");
  470 
  471         ar71xx_pci_mask_irq((void*)irq);
  472 
  473         result = intr_event_remove_handler(cookie);
  474         if (!result)
  475                 sc->sc_eventstab[irq] = NULL;
  476 
  477         return (result);
  478 }
  479 
  480 static int
  481 ar71xx_pci_intr(void *arg)
  482 {
  483         struct ar71xx_pci_softc *sc = arg;
  484         struct intr_event *event;
  485         uint32_t reg, irq, mask;
  486 
  487         reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS);
  488         mask = ATH_READ_REG(AR71XX_PCI_INTR_MASK);
  489         /*
  490          * Handle only unmasked interrupts
  491          */
  492         reg &= mask;
  493         for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) {
  494                 if (reg & (1 << irq)) {
  495                         event = sc->sc_eventstab[irq];
  496                         if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
  497                                 /* Ignore timer interrupts */
  498                                 if (irq != 0)
  499                                         printf("Stray IRQ %d\n", irq);
  500                                 continue;
  501                         }
  502 
  503                         /* TODO: frame instead of NULL? */
  504                         intr_event_handle(event, NULL);
  505                         mips_intrcnt_inc(sc->sc_intr_counter[irq]);
  506                 }
  507         }
  508 
  509         return (FILTER_HANDLED);
  510 }
  511 
  512 static int
  513 ar71xx_pci_maxslots(device_t dev)
  514 {
  515 
  516         return (PCI_SLOTMAX);
  517 }
  518 
  519 static int
  520 ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin)
  521 {
  522         if (pci_get_slot(device) < AR71XX_PCI_BASE_SLOT)
  523                 panic("%s: PCI slot %d is less then AR71XX_PCI_BASE_SLOT",
  524                     __func__, pci_get_slot(device));
  525 
  526         return (pci_get_slot(device) - AR71XX_PCI_BASE_SLOT);
  527 }
  528 
  529 static device_method_t ar71xx_pci_methods[] = {
  530         /* Device interface */
  531         DEVMETHOD(device_probe,         ar71xx_pci_probe),
  532         DEVMETHOD(device_attach,        ar71xx_pci_attach),
  533         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
  534         DEVMETHOD(device_suspend,       bus_generic_suspend),
  535         DEVMETHOD(device_resume,        bus_generic_resume),
  536 
  537         /* Bus interface */
  538         DEVMETHOD(bus_read_ivar,        ar71xx_pci_read_ivar),
  539         DEVMETHOD(bus_write_ivar,       ar71xx_pci_write_ivar),
  540         DEVMETHOD(bus_alloc_resource,   ar71xx_pci_alloc_resource),
  541         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
  542         DEVMETHOD(bus_activate_resource, ar71xx_pci_activate_resource),
  543         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  544         DEVMETHOD(bus_setup_intr,       ar71xx_pci_setup_intr),
  545         DEVMETHOD(bus_teardown_intr,    ar71xx_pci_teardown_intr),
  546 
  547         /* pcib interface */
  548         DEVMETHOD(pcib_maxslots,        ar71xx_pci_maxslots),
  549         DEVMETHOD(pcib_read_config,     ar71xx_pci_read_config),
  550         DEVMETHOD(pcib_write_config,    ar71xx_pci_write_config),
  551         DEVMETHOD(pcib_route_interrupt, ar71xx_pci_route_interrupt),
  552 
  553         DEVMETHOD_END
  554 };
  555 
  556 static driver_t ar71xx_pci_driver = {
  557         "pcib",
  558         ar71xx_pci_methods,
  559         sizeof(struct ar71xx_pci_softc),
  560 };
  561 
  562 static devclass_t ar71xx_pci_devclass;
  563 
  564 DRIVER_MODULE(ar71xx_pci, nexus, ar71xx_pci_driver, ar71xx_pci_devclass, 0, 0);

Cache object: fba4ca3bfd5083d77412fc57caa08a60


[ 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.