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/dev/cardbus/rbus_ppb.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 /*      $NetBSD: rbus_ppb.c,v 1.10 2003/11/24 06:11:56 lukem Exp $      */
    2 
    3 /*
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Michael Richardson <mcr@sandelman.ottawa.on.ca>
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * CardBus front-end for the Intel/Digital DECchip 21152 PCI-PCI bridge
   41  */
   42 
   43 #include <sys/cdefs.h>
   44 __KERNEL_RCSID(0, "$NetBSD: rbus_ppb.c,v 1.10 2003/11/24 06:11:56 lukem Exp $");
   45 
   46 #include <sys/param.h>
   47 #include <sys/systm.h>
   48 #include <sys/mbuf.h>
   49 #include <sys/malloc.h>
   50 #include <sys/kernel.h>
   51 #include <sys/socket.h>
   52 #include <sys/ioctl.h>
   53 #include <sys/errno.h>
   54 #include <sys/device.h>
   55 
   56 #if NRND > 0
   57 #include <sys/rnd.h>
   58 #endif
   59 
   60 #include <machine/endian.h>
   61 
   62 #include <machine/bus.h>
   63 #include <machine/intr.h>
   64 
   65 #include <dev/pci/pcivar.h>
   66 #include <dev/pci/pcireg.h>
   67 #include <dev/pci/pcidevs.h>
   68 #include <dev/pci/ppbreg.h>
   69 
   70 #include <dev/ic/i82365reg.h>
   71 #include <dev/ic/i82365var.h>
   72 
   73 #include <dev/pci/pccbbreg.h>
   74 #include <dev/pci/pccbbvar.h>
   75 
   76 #include <dev/cardbus/cardbusvar.h>
   77 #include <dev/cardbus/cardbusdevs.h>
   78 
   79 #include <i386/pci/pci_addr_fixup.h>
   80 #include <i386/pci/pci_bus_fixup.h>
   81 #include <i386/pci/pci_intr_fixup.h>
   82 #include <i386/pci/pcibios.h>
   83 
   84 struct ppb_softc;
   85 
   86 static int  ppb_cardbus_match   __P((struct device *, struct cfdata *, void *));
   87 static void ppb_cardbus_attach  __P((struct device *, struct device *, void *));
   88 static int  ppb_cardbus_detach  __P((struct device * self, int flags));
   89 /*static*/ void ppb_cardbus_setup   __P((struct ppb_softc * sc));
   90 /*static*/ int  ppb_cardbus_enable  __P((struct ppb_softc * sc));
   91 /*static*/ void ppb_cardbus_disable __P((struct ppb_softc * sc));
   92 static int  ppb_activate        __P((struct device *self, enum devact act));
   93 int rppbprint        __P((void *aux, const char *pnp));
   94 int rbus_intr_fixup  __P((pci_chipset_tag_t pc, int minbus,
   95                           int maxbus, int line));
   96 void rbus_do_header_fixup __P((pci_chipset_tag_t pc, pcitag_t tag,
   97                               void *context));
   98 
   99 static void rbus_pci_phys_allocate __P((pci_chipset_tag_t pc,
  100                                         pcitag_t          tag,
  101                                         void             *context));
  102 
  103 static int rbus_do_phys_allocate __P((pci_chipset_tag_t pc,
  104                                       pcitag_t     tag,
  105                                       int mapreg,
  106                                       void        *ctx,
  107                                       int type,
  108                                       bus_addr_t *addr,
  109                                       bus_size_t size));
  110 
  111 static void rbus_pci_phys_countspace __P((pci_chipset_tag_t pc,
  112                                           pcitag_t          tag,
  113                                           void             *context));
  114 
  115 static int rbus_do_phys_countspace __P((pci_chipset_tag_t pc,
  116                                         pcitag_t     tag,
  117                                         int mapreg,     
  118                                         void        *ctx,
  119                                         int type,
  120                                         bus_addr_t *addr,
  121                                         bus_size_t size));
  122 
  123 unsigned int rbus_round_up __P((unsigned int size, unsigned int min));
  124 
  125 
  126 struct ppb_cardbus_softc {
  127   struct device sc_dev;
  128   pcitag_t sc_tag;
  129   int foo;
  130 };
  131 
  132 CFATTACH_DECL(rbus_ppb, sizeof(struct ppb_cardbus_softc),
  133     ppb_cardbus_match, ppb_cardbus_attach, ppb_cardbus_detach, ppb_activate);
  134 
  135 #ifdef  CBB_DEBUG
  136 int rbus_ppb_debug = 0;   /* hack with kdb */
  137 #define DPRINTF(X) if(rbus_ppb_debug) printf X
  138 #else
  139 #define DPRINTF(X)
  140 #endif
  141 
  142 static int
  143 ppb_cardbus_match(parent, match, aux)
  144         struct device *parent;
  145         struct cfdata *match;
  146         void   *aux;
  147 {
  148         struct cardbus_attach_args *ca = aux;
  149 
  150         if (CARDBUS_VENDOR(ca->ca_id) ==  PCI_VENDOR_DEC &&
  151             CARDBUS_PRODUCT(ca->ca_id) == PCI_PRODUCT_DEC_21152)
  152                 return (1);
  153 
  154         if(PCI_CLASS(ca->ca_class) == PCI_CLASS_BRIDGE &&
  155            PCI_SUBCLASS(ca->ca_class) == PCI_SUBCLASS_BRIDGE_PCI) {
  156           /* XXX */
  157           printf("recognizing generic bridge chip\n");
  158         }
  159 
  160         return (0);
  161 }
  162 
  163 
  164 int
  165 rppbprint(aux, pnp)
  166         void *aux;
  167         const char *pnp;
  168 {
  169         struct pcibus_attach_args *pba = aux;
  170 
  171         /* only PCIs can attach to PPBs; easy. */
  172         if (pnp)
  173                 aprint_normal("pci at %s", pnp);
  174         aprint_normal(" bus %d (rbus)", pba->pba_bus);
  175         return (UNCONF);
  176 }
  177 
  178 int
  179 rbus_intr_fixup(pci_chipset_tag_t pc,
  180                 int minbus,
  181                 int maxbus,
  182                 int line)
  183 {
  184   pci_device_foreach_min(pc, minbus,
  185                          maxbus, rbus_do_header_fixup, (void *)&line);
  186   return 0;
  187 }
  188 
  189 void
  190 rbus_do_header_fixup(pc, tag, context)
  191         pci_chipset_tag_t pc;
  192         pcitag_t tag;
  193         void *context;
  194 {
  195   int pin, irq;
  196   int bus, device, function;
  197   pcireg_t intr, id;
  198   int *pline = (int *)context;
  199   int line = *pline;
  200 
  201   pci_decompose_tag(pc, tag, &bus, &device, &function);
  202   id = pci_conf_read(pc, tag, PCI_ID_REG);
  203 
  204   intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
  205   pin = PCI_INTERRUPT_PIN(intr);
  206   irq = PCI_INTERRUPT_LINE(intr);
  207 
  208 #if 0
  209   printf("do_header %02x:%02x:%02x pin=%d => line %d\n",
  210          bus, device, function, pin, line);
  211 #endif
  212 
  213   intr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT);
  214   intr |= (line << PCI_INTERRUPT_LINE_SHIFT);
  215   pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
  216 
  217 }
  218 
  219 /* 
  220  * This function takes a range of PCI bus numbers and
  221  * allocates space for all devices found in this space (the BARs) from
  222  * the rbus space maps (I/O and memory).
  223  *
  224  * It assumes that "rbus" is defined. The whole concept does.
  225  *
  226  * It uses pci_device_foreach_min() to call rbus_pci_phys_allocate.
  227  * This function is mostly stolen from
  228  *     pci_addr_fixup.c:pciaddr_resource_reserve. 
  229  *
  230  */
  231 struct rbus_pci_addr_fixup_context {
  232   struct ppb_cardbus_softc *csc;
  233   cardbus_chipset_tag_t ct;
  234   struct cardbus_softc *sc;
  235   struct cardbus_attach_args *caa;
  236   int    minbus;
  237   int    maxbus;
  238   bus_size_t  *bussize_ioreqs;
  239   bus_size_t  *bussize_memreqs;
  240   rbus_tag_t   *iobustags;
  241   rbus_tag_t   *membustags;
  242 };  
  243 
  244 unsigned int 
  245 rbus_round_up(unsigned int size, unsigned int min)
  246 {
  247   unsigned int power2;
  248 
  249   if(size == 0) {
  250     return 0;
  251   }
  252 
  253   power2=min;
  254 
  255   while(power2 < (1 << 31) &&
  256         power2 < size) {
  257     power2 = power2 << 1;
  258   }
  259   
  260   return power2;
  261 }
  262     
  263 static void
  264 rbus_pci_addr_fixup(struct ppb_cardbus_softc *csc,
  265                     cardbus_chipset_tag_t ct,
  266                     struct cardbus_softc *sc,
  267                     pci_chipset_tag_t     pc,
  268                     struct cardbus_attach_args *caa,
  269                     int minbus, int maxbus)
  270 {
  271         struct rbus_pci_addr_fixup_context rct;
  272         int    size, busnum;
  273         bus_addr_t start;
  274         bus_space_handle_t handle;
  275         u_int32_t reg;
  276 
  277         rct.csc=csc;
  278         rct.ct=ct;
  279         rct.sc=sc;
  280         rct.caa=caa;
  281         rct.minbus = minbus;
  282         rct.maxbus = maxbus;
  283         size = sizeof(bus_size_t)*(maxbus+1);
  284         rct.bussize_ioreqs  = alloca(size);
  285         rct.bussize_memreqs = alloca(size);
  286         rct.iobustags = alloca(maxbus * sizeof(rbus_tag_t));
  287         rct.membustags = alloca(maxbus * sizeof(rbus_tag_t));
  288 
  289         bzero(rct.bussize_ioreqs, size);
  290         bzero(rct.bussize_memreqs, size);
  291 
  292         printf("%s: sizing buses %d-%d\n",
  293                rct.csc->sc_dev.dv_xname,
  294                minbus, maxbus);
  295 
  296         pci_device_foreach_min(pc, minbus, maxbus,
  297                                rbus_pci_phys_countspace, &rct);
  298 
  299         /*
  300          * we need to determine amount of address space for each
  301          * bus. To do this, we have to roll up amounts and then
  302          * we need to divide up the cardbus's extent to allocate
  303          * some space to each bus.
  304          */
  305 
  306         for(busnum=maxbus; busnum > minbus; busnum--) {
  307           if(pci_bus_parent[busnum] != 0) {
  308             if(pci_bus_parent[busnum] < minbus ||
  309                pci_bus_parent[busnum] >= maxbus) {
  310               printf("%s: bus %d has illegal parent %d\n",
  311                      rct.csc->sc_dev.dv_xname,
  312                      busnum, pci_bus_parent[busnum]);
  313               continue;
  314             }
  315 
  316             /* first round amount of space up */
  317             rct.bussize_ioreqs[busnum] =
  318               rbus_round_up(rct.bussize_ioreqs[busnum],  PPB_IO_MIN);
  319             rct.bussize_ioreqs[pci_bus_parent[busnum]] +=
  320               rct.bussize_ioreqs[busnum];
  321 
  322             rct.bussize_memreqs[busnum] =
  323               rbus_round_up(rct.bussize_memreqs[busnum], PPB_MEM_MIN);
  324             rct.bussize_memreqs[pci_bus_parent[busnum]] +=
  325               rct.bussize_memreqs[busnum];
  326 
  327           }
  328         }
  329 
  330         rct.bussize_ioreqs[minbus] =
  331           rbus_round_up(rct.bussize_ioreqs[minbus], 4096);
  332         rct.bussize_memreqs[minbus] =
  333           rbus_round_up(rct.bussize_memreqs[minbus], 8);
  334 
  335         printf("%s: total needs IO %08lx and MEM %08lx\n",
  336                rct.csc->sc_dev.dv_xname,
  337                rct.bussize_ioreqs[minbus], rct.bussize_memreqs[minbus]);
  338 
  339         if(!caa->ca_rbus_iot) {
  340           panic("no iot bus");
  341         }
  342 
  343         if(rct.bussize_ioreqs[minbus]) {
  344           if(rbus_space_alloc(caa->ca_rbus_iot, 0,
  345                               rct.bussize_ioreqs[minbus],
  346                               rct.bussize_ioreqs[minbus]-1 /* mask  */,
  347                               rct.bussize_ioreqs[minbus] /* align */,
  348                               /* flags */ 0,
  349                               &start,
  350                               &handle) != 0) {
  351             panic("rbus_ppb: can not allocate %ld bytes in IO bus %d",
  352                   rct.bussize_ioreqs[minbus], minbus);
  353           }
  354           rct.iobustags[minbus]=rbus_new(caa->ca_rbus_iot,
  355                                          start, 
  356                                          rct.bussize_ioreqs[minbus],
  357                                          0 /* offset to add to physical address
  358                                               to make processor address */,
  359                                          RBUS_SPACE_DEDICATE);
  360         }
  361 
  362         if(rct.bussize_memreqs[minbus]) {
  363           if(rbus_space_alloc(caa->ca_rbus_memt, 0,
  364                               rct.bussize_memreqs[minbus],
  365                               rct.bussize_memreqs[minbus]-1 /* mask */,
  366                               rct.bussize_memreqs[minbus] /* align */,
  367                               /* flags */ 0,
  368                               &start,
  369                               &handle) != 0) {
  370             panic("%s: can not allocate %ld bytes in MEM bus %d",
  371                   rct.csc->sc_dev.dv_xname,
  372                   rct.bussize_memreqs[minbus], minbus);
  373           }
  374           rct.membustags[minbus]=rbus_new(caa->ca_rbus_memt,
  375                                           start,
  376                                           rct.bussize_memreqs[minbus],
  377                                           0 /* offset to add to physical
  378                                                address to make processor
  379                                                address */,
  380                                           RBUS_SPACE_DEDICATE);
  381         }
  382 
  383         for(busnum=minbus+1; busnum <= maxbus; busnum++) {
  384           int busparent;
  385 
  386           busparent = pci_bus_parent[busnum];
  387 
  388           printf("%s: bus %d (parent=%d) needs IO %08lx and MEM %08lx\n",
  389                  rct.csc->sc_dev.dv_xname,
  390                  busnum,
  391                  busparent,
  392                  rct.bussize_ioreqs[busnum],
  393                  rct.bussize_memreqs[busnum]);
  394 
  395           if(busparent > maxbus) {
  396             panic("rbus_ppb: illegal parent");
  397           }
  398 
  399           if(rct.bussize_ioreqs[busnum]) {
  400             if(rbus_space_alloc(rct.iobustags[busparent],
  401                                 0,
  402                                 rct.bussize_ioreqs[busnum],
  403                                 rct.bussize_ioreqs[busnum]-1 /*mask */,
  404                                 rct.bussize_ioreqs[busnum] /* align */,
  405                                 /* flags */ 0,
  406                                 &start,
  407                                 &handle) != 0) {
  408               panic("rbus_ppb: can not allocate %ld bytes in IO bus %d",
  409                     rct.bussize_ioreqs[busnum], busnum);
  410             }
  411             rct.iobustags[busnum]=rbus_new(rct.iobustags[busparent],
  412                                            start,
  413                                            rct.bussize_ioreqs[busnum],
  414                                            0 /* offset to add to physical
  415                                                 address
  416                                                 to make processor address */,
  417                                            RBUS_SPACE_DEDICATE);
  418 
  419             /* program the bridge */
  420             
  421             /* enable I/O space */
  422             reg = pci_conf_read(pc, pci_bus_tag[busnum],
  423                                 PCI_COMMAND_STATUS_REG);
  424             reg |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE;
  425             pci_conf_write(pc, pci_bus_tag[busnum],
  426                            PCI_COMMAND_STATUS_REG, reg);
  427 
  428             /* now init the limit register for I/O */
  429             pci_conf_write(pc, pci_bus_tag[busnum], PPB_REG_IOSTATUS,
  430                            (((start & 0xf000) >> 8) << PPB_IOBASE_SHIFT) |
  431                            ((((start +
  432                                rct.bussize_ioreqs[busnum] +
  433                                4095) & 0xf000) >> 8) << PPB_IOLIMIT_SHIFT));
  434           }
  435           
  436           if(rct.bussize_memreqs[busnum]) {
  437             if(rbus_space_alloc(rct.membustags[busparent],
  438                                 0,
  439                                 rct.bussize_memreqs[busnum] /* size  */, 
  440                                 rct.bussize_memreqs[busnum]-1 /*mask */, 
  441                                 rct.bussize_memreqs[busnum] /* align */,
  442                                 /* flags */ 0,
  443                                 &start,
  444                                 &handle) != 0) {
  445               panic("rbus_ppb: can not allocate %ld bytes in MEM bus %d",
  446                     rct.bussize_memreqs[busnum], busnum);
  447             }
  448             rct.membustags[busnum]=rbus_new(rct.membustags[busparent],
  449                                             start,
  450                                             rct.bussize_memreqs[busnum],
  451                                             0 /* offset to add to physical
  452                                                  address to make processor
  453                                                  address */,
  454                                             RBUS_SPACE_DEDICATE);
  455 
  456             /* program the bridge */
  457             /* enable memory space */
  458             reg = pci_conf_read(pc, pci_bus_tag[busnum],
  459                                 PCI_COMMAND_STATUS_REG);
  460             reg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
  461             pci_conf_write(pc, pci_bus_tag[busnum],
  462                            PCI_COMMAND_STATUS_REG, reg);
  463 
  464             /* now init the limit register for memory */
  465             pci_conf_write(pc, pci_bus_tag[busnum], PPB_REG_MEM,
  466                            ((start & PPB_MEM_MASK)
  467                             >> PPB_MEM_SHIFT) << PPB_MEMBASE_SHIFT |
  468                            (((start +
  469                              rct.bussize_memreqs[busnum] +
  470                               PPB_MEM_MIN-1) >> PPB_MEM_SHIFT)
  471                             << PPB_MEMLIMIT_SHIFT));
  472 
  473             /* and set the prefetchable limits as well */
  474             pci_conf_write(pc, pci_bus_tag[busnum], PPB_REG_PREFMEM,
  475                            ((start & PPB_MEM_MASK)
  476                             >> PPB_MEM_SHIFT) << PPB_MEMBASE_SHIFT |
  477                            (((start +
  478                              rct.bussize_memreqs[busnum] +
  479                               PPB_MEM_MIN-1) >> PPB_MEM_SHIFT)
  480                             << PPB_MEMLIMIT_SHIFT));
  481 
  482             /* pci_conf_print(pc, pci_bus_tag[busnum], NULL); */
  483           }
  484         }
  485 
  486         printf("%s: configuring buses %d-%d\n",
  487                 rct.csc->sc_dev.dv_xname,
  488                minbus, maxbus);
  489         pci_device_foreach_min(pc, minbus, maxbus,
  490                                rbus_pci_phys_allocate, &rct);
  491 }
  492 
  493 static void
  494 rbus_pci_phys_countspace(pc, tag, context)
  495         pci_chipset_tag_t pc;
  496         pcitag_t          tag;
  497         void             *context;
  498 {
  499         int bus, device, function;
  500         struct  rbus_pci_addr_fixup_context *rct =
  501           (struct  rbus_pci_addr_fixup_context *)context;
  502 
  503         pci_decompose_tag(pc, tag, &bus, &device, &function);
  504 
  505         printf("%s: configuring device %02x:%02x:%02x\n",
  506                rct->csc->sc_dev.dv_xname,
  507                bus, device, function);
  508 
  509         pciaddr_resource_manage(pc, tag,
  510                                 rbus_do_phys_countspace, context);
  511 }
  512 
  513   
  514 int
  515 rbus_do_phys_countspace(pc, tag, mapreg, ctx, type, addr, size)
  516         pci_chipset_tag_t pc;
  517         pcitag_t     tag;
  518         void        *ctx;
  519         int mapreg, type;
  520         bus_addr_t *addr;
  521         bus_size_t size;
  522 {
  523         struct  rbus_pci_addr_fixup_context *rct =
  524           (struct  rbus_pci_addr_fixup_context *)ctx;
  525         int bus, device, function;
  526 
  527         pci_decompose_tag(pc, tag, &bus, &device, &function);
  528 
  529         if(size > (1<<24)) {
  530           printf("%s: skipping huge space request of size=%08x\n",
  531                  rct->csc->sc_dev.dv_xname, (unsigned int)size);
  532           return 0;
  533         }
  534 
  535         if(PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) {
  536           rct->bussize_ioreqs[bus] += size;
  537         } else {
  538           rct->bussize_memreqs[bus]+= size;
  539         }
  540          
  541         return 0;
  542 }
  543 
  544 static void
  545 rbus_pci_phys_allocate(pc, tag, context)
  546         pci_chipset_tag_t pc;
  547         pcitag_t          tag;
  548         void             *context;
  549 {
  550         int bus, device, function, command;
  551         struct rbus_pci_addr_fixup_context *rct =
  552           (struct rbus_pci_addr_fixup_context *)context;
  553         //cardbus_chipset_tag_t ct = rct->ct;
  554         //      struct cardbus_softc *sc = rct->sc;
  555   
  556         pci_decompose_tag(pc, tag, &bus, &device, &function);
  557 
  558         printf("%s: configuring device %02x:%02x:%02x\n",
  559                rct->csc->sc_dev.dv_xname,
  560                bus, device, function);
  561 
  562         pciaddr_resource_manage(pc, tag,
  563                                 rbus_do_phys_allocate, context);
  564 
  565         /* now turn the device's memory and I/O on */
  566         command = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
  567         command |= PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE;
  568         pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, command);
  569 }
  570 
  571 int
  572 rbus_do_phys_allocate(pc, tag, mapreg, ctx, type, addr, size)
  573         pci_chipset_tag_t pc;
  574         pcitag_t     tag;
  575         void        *ctx;
  576         int mapreg, type;
  577         bus_addr_t *addr;
  578         bus_size_t size;
  579 {
  580         struct  rbus_pci_addr_fixup_context *rct =
  581           (struct  rbus_pci_addr_fixup_context *)ctx;
  582         cardbus_chipset_tag_t ct     = rct->ct;
  583         struct cardbus_softc *sc     = rct->sc;
  584         cardbus_function_t       *cf = sc->sc_cf;
  585         rbus_tag_t          rbustag;
  586         bus_space_tag_t     bustag;
  587         bus_addr_t mask = size -1;
  588         bus_addr_t base = 0;
  589         bus_space_handle_t handle;
  590         int busflags = 0;
  591         int flags    = 0;
  592         char *bustype;
  593         int bus, device, function;
  594 
  595         pci_decompose_tag(pc, tag, &bus, &device, &function);
  596 
  597         /*
  598          * some devices come up with garbage in them (Tulip?)
  599          * we are in charge here, so give them address
  600          * space anyway. 
  601          *
  602          * XXX this may be due to no secondary PCI reset!!!
  603          */
  604 #if 0
  605         if (*addr) {
  606                 printf("Already allocated space at %08x\n",
  607                        (unsigned int)*addr);
  608                 return (0);
  609         }
  610 #endif
  611 
  612         if(size > (1<<24)) {
  613           printf("%s: skipping huge space request of size=%08x\n",
  614                  rct->csc->sc_dev.dv_xname, (unsigned int)size);
  615           return 0;
  616         }
  617 
  618         if(PCI_MAPREG_TYPE(type) == PCI_MAPREG_TYPE_IO) {
  619           bustag  = sc->sc_iot;
  620           rbustag = rct->iobustags[bus];
  621           bustype = "io";
  622         } else {
  623           bustag  = sc->sc_memt;
  624           rbustag = rct->membustags[bus];
  625           bustype = "mem";
  626         }
  627 
  628         if((*cf->cardbus_space_alloc)(ct, rbustag, base, size,
  629                                       mask, size, busflags|flags,
  630                                       addr, &handle)) {
  631           printf("%s: no available resources (size=%08x) for bar %2d. fixup failed\n",
  632                  rct->csc->sc_dev.dv_xname, (unsigned int)size, mapreg);
  633 
  634           *addr = 0;
  635           pci_conf_write(pc, tag, mapreg, *addr);
  636           return (1);
  637         }
  638 
  639         printf("%s: alloc %s space of size %08x for %02d:%02d:%02d -> %08x\n",
  640                rct->csc->sc_dev.dv_xname,
  641                bustype, 
  642                (unsigned int)size,
  643                bus, device, function, (unsigned int)*addr);
  644 
  645         /* write new address to PCI device configuration header */
  646         pci_conf_write(pc, tag, mapreg, *addr);
  647 
  648         /* check */
  649         {
  650                 DPRINTF(("%s: pci_addr_fixup: ",
  651                          rct->csc->sc_dev.dv_xname));
  652 #ifdef  CBB_DEBUG
  653                 if(rbus_ppb_debug) { pciaddr_print_devid(pc, tag); }
  654 #endif
  655         }
  656 
  657         /* double check that the value got inserted correctly */
  658         if (pciaddr_ioaddr(pci_conf_read(pc, tag, mapreg)) != *addr) {
  659                 pci_conf_write(pc, tag, mapreg, 0); /* clear */
  660                 printf("%s: fixup failed. (new address=%#x)\n",
  661                        rct->csc->sc_dev.dv_xname,
  662                        (unsigned)*addr);
  663                 return (1);
  664         }
  665 
  666         DPRINTF(("new address 0x%08x\n",
  667                  (unsigned)*addr));
  668 
  669         return (0);
  670 }
  671 
  672 static void
  673 ppb_cardbus_attach(parent, self, aux)
  674         struct device *parent, *self;
  675         void *aux;
  676 {
  677         struct ppb_cardbus_softc *csc = (struct ppb_cardbus_softc *) self;
  678         struct cardbus_softc *parent_sc =
  679             (struct cardbus_softc *) csc->sc_dev.dv_parent;
  680         struct cardbus_attach_args *ca = aux;
  681         cardbus_devfunc_t ct = ca->ca_ct;
  682         cardbus_chipset_tag_t cc = ct->ct_cc;
  683         cardbus_function_tag_t cf = ct->ct_cf;
  684         struct pccbb_softc *psc = (struct pccbb_softc *)cc;
  685         struct pcibus_attach_args pba;
  686         char devinfo[256];
  687         pcireg_t busdata;
  688         int mybus, rv;
  689         u_int16_t pciirq;
  690         int minbus, maxbus;
  691 
  692         mybus = ct->ct_bus;
  693         pciirq = 0;
  694         rv = 0;
  695 
  696         /* shut up compiler */
  697         csc->foo=parent_sc->sc_intrline;
  698         
  699 
  700         pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo);
  701         printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(ca->ca_class));
  702 
  703         csc->sc_tag = ca->ca_tag;       /* XXX cardbustag_t == pcitag_t */
  704 
  705         busdata = cardbus_conf_read(cc, cf, ca->ca_tag, PPB_REG_BUSINFO);
  706         minbus = pcibios_max_bus;
  707         maxbus = minbus;                /* XXX; gcc */
  708 
  709         if (PPB_BUSINFO_SECONDARY(busdata) == 0) {
  710           printf("%s: not configured by system firmware calling pci_bus_fixup(%d)\n",
  711                  self->dv_xname, 0);
  712 
  713           /*
  714            * first, pull the reset wire on the secondary bridge
  715            * to clear all devices
  716            */
  717           busdata = cardbus_conf_read(cc, cf, ca->ca_tag,
  718                                       PPB_REG_BRIDGECONTROL);
  719           cardbus_conf_write(cc, cf, ca->ca_tag, PPB_REG_BRIDGECONTROL,
  720                              busdata | PPB_BC_SECONDARY_RESET);
  721           delay(1);
  722           cardbus_conf_write(cc, cf, ca->ca_tag, PPB_REG_BRIDGECONTROL,
  723                              busdata);
  724 
  725           /* then go initialize the bridge control registers */
  726           maxbus = pci_bus_fixup(psc->sc_pc, 0);
  727         }
  728 
  729         busdata = cardbus_conf_read(cc, cf, ca->ca_tag, PPB_REG_BUSINFO);
  730         if(PPB_BUSINFO_SECONDARY(busdata) == 0) {
  731           printf("%s: still not configured, not fixable.\n",
  732                  self->dv_xname);
  733           return;
  734         }
  735 
  736 #if 0     
  737         minbus = PPB_BUSINFO_SECONDARY(busdata);
  738         maxbus = PPB_BUSINFO_SUBORDINATE(busdata);
  739 #endif
  740         
  741         /* now, go and assign addresses for the new devices */
  742         rbus_pci_addr_fixup(csc, cc, parent_sc,
  743                             psc->sc_pc,
  744                             ca,
  745                             minbus, maxbus);
  746 
  747         /*
  748          * now configure all connected devices to the IRQ which
  749          * was assigned to this slot, as they will all arrive from
  750          * that IRQ.
  751          */
  752         rbus_intr_fixup(psc->sc_pc, minbus, maxbus, ca->ca_intrline);
  753 
  754         /* 
  755          * enable direct routing of interrupts. We do this because
  756          * we can not manage to get pccb_intr_establish() called until
  757          * PCI subsystem is merged with rbus. The major thing that this
  758          * routine does is avoid calling the driver's interrupt routine
  759          * when the card has been removed.
  760          *
  761          * The rbus_ppb.c can not cope with card desertions until the merging
  762          * anyway.
  763          */
  764         pccbb_intr_route(psc);
  765 
  766         /*
  767          * Attach the PCI bus than hangs off of it.
  768          *
  769          * XXX Don't pass-through Memory Read Multiple.  Should we?
  770          * XXX Consult the spec...
  771          */
  772         pba.pba_busname = "pci";        
  773         pba.pba_iot  = ca->ca_iot;
  774         pba.pba_memt = ca->ca_memt;
  775         pba.pba_dmat = ca->ca_dmat;
  776         pba.pba_pc   = psc->sc_pc;
  777         pba.pba_flags    = PCI_FLAGS_IO_ENABLED|PCI_FLAGS_MEM_ENABLED;
  778         pba.pba_bus      = PPB_BUSINFO_SECONDARY(busdata);
  779         pba.pba_bridgetag = &csc->sc_tag;
  780         /*pba.pba_intrswiz = parent_sc->sc_intrswiz; */
  781         pba.pba_intrtag  = psc->sc_pa.pa_intrtag;
  782 
  783         config_found(self, &pba, rppbprint);
  784 }
  785 
  786 void
  787 ppb_cardbus_setup(struct ppb_softc * sc)
  788 {
  789         struct ppb_cardbus_softc *csc = (struct ppb_cardbus_softc *) sc;
  790 #if 0
  791         cardbus_chipset_tag_t cc  = psc->sc_cc;
  792         cardbus_function_tag_t cf = psc->sc_cf;
  793 #endif
  794 
  795         /* shut up compiler */
  796         csc->foo=2;
  797 
  798         printf("ppb_cardbus_setup called\n");
  799 #if 0
  800         /* not sure what to do here */
  801         cardbustag_t tag = cardbus_make_tag(cc, cf, csc->ct->ct_bus,
  802             csc->ct->ct_dev, csc->ct->ct_func);
  803 
  804         command = Cardbus_conf_read(csc->ct, tag, CARDBUS_COMMAND_STATUS_REG);
  805         if (csc->base0_reg) {
  806                 Cardbus_conf_write(csc->ct, tag,
  807                     CARDBUS_BASE0_REG, csc->base0_reg);
  808                 (cf->cardbus_ctrl) (cc, CARDBUS_MEM_ENABLE);
  809                 command |= CARDBUS_COMMAND_MEM_ENABLE |
  810                     CARDBUS_COMMAND_MASTER_ENABLE;
  811         } else if (csc->base1_reg) {
  812                 Cardbus_conf_write(csc->ct, tag,
  813                     CARDBUS_BASE1_REG, csc->base1_reg);
  814                 (cf->cardbus_ctrl) (cc, CARDBUS_IO_ENABLE);
  815                 command |= (CARDBUS_COMMAND_IO_ENABLE |
  816                     CARDBUS_COMMAND_MASTER_ENABLE);
  817         }
  818 
  819         (cf->cardbus_ctrl) (cc, CARDBUS_BM_ENABLE);
  820 
  821         /* enable the card */
  822         Cardbus_conf_write(csc->ct, tag, CARDBUS_COMMAND_STATUS_REG, command);
  823 #endif
  824 }
  825 
  826 int
  827 ppb_cardbus_enable(struct ppb_softc * sc)
  828 {
  829 #if 0
  830         struct ppb_cardbus_softc *csc = (struct fxp_cardbus_softc *) sc;
  831         struct cardbus_softc *psc =
  832             (struct cardbus_softc *) sc->sc_dev.dv_parent;
  833         cardbus_chipset_tag_t cc = psc->sc_cc;
  834         cardbus_function_tag_t cf = psc->sc_cf;
  835 
  836         Cardbus_function_enable(csc->ct);
  837 
  838         fxp_cardbus_setup(sc);
  839 
  840         /* Map and establish the interrupt. */
  841 
  842         sc->sc_ih = cardbus_intr_establish(cc, cf, psc->sc_intrline, IPL_NET,
  843             fxp_intr, sc);
  844         if (NULL == sc->sc_ih) {
  845                 printf("%s: couldn't establish interrupt\n",
  846                     sc->sc_dev.dv_xname);
  847                 return 1;
  848         }
  849 
  850         printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname,
  851             psc->sc_intrline);
  852 
  853 #endif
  854         return 0;
  855 }
  856 
  857 void
  858 ppb_cardbus_disable(struct ppb_softc * sc)
  859 {
  860 #if 0
  861         struct cardbus_softc *psc =
  862             (struct cardbus_softc *) sc->sc_dev.dv_parent;
  863         cardbus_chipset_tag_t cc = psc->sc_cc;
  864         cardbus_function_tag_t cf = psc->sc_cf;
  865 
  866         /* Remove interrupt handler. */
  867         cardbus_intr_disestablish(cc, cf, sc->sc_ih);
  868 
  869         Cardbus_function_disable(((struct fxp_cardbus_softc *) sc)->ct);
  870 #endif
  871 }
  872 
  873 static int
  874 ppb_cardbus_detach(self, flags)
  875         struct device *self;
  876         int flags;
  877 {
  878   /* struct ppb_softc *sc = (struct ppb_softc *) self;*/
  879         struct ppb_cardbus_softc *csc = (struct ppb_cardbus_softc *) self;
  880 
  881 #if 0
  882         struct cardbus_devfunc *ct = csc->ct;
  883         int rv, reg;
  884 
  885 #ifdef DIAGNOSTIC
  886         if (ct == NULL)
  887                 panic("%s: data structure lacks", sc->sc_dev.dv_xname);
  888 #endif
  889 
  890         rv = fxp_detach(sc);
  891         if (rv == 0) {
  892                 /*
  893                  * Unhook the interrupt handler.
  894                  */
  895                 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih);
  896 
  897                 /*
  898                  * release bus space and close window
  899                  */
  900                 if (csc->base0_reg)
  901                         reg = CARDBUS_BASE0_REG;
  902                 else
  903                         reg = CARDBUS_BASE1_REG;
  904                 Cardbus_mapreg_unmap(ct, reg, sc->sc_st, sc->sc_sh, csc->size);
  905         }
  906         return (rv);
  907 
  908 #endif
  909         csc->foo=1;
  910         return 0;
  911 
  912 }
  913 
  914 int
  915 ppb_activate(self, act)
  916         struct device *self;
  917         enum devact act;
  918 {
  919   printf("ppb_activate called\n");
  920   return 0;
  921 }
  922 

Cache object: 96d8f37b3779d8f46fa94061f1c315fd


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