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/lnc/if_lnc_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) 1994-2000
    3  *      Paul Richards. 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, this list of conditions and the following disclaimer,
   10  *    verbatim and that no modifications are made prior to this
   11  *    point in the file.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name Paul Richards may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY PAUL RICHARDS ``AS IS'' AND
   19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   21  * ARE DISCLAIMED.  IN NO EVENT SHALL PAUL RICHARDS BE LIABLE
   22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   28  * SUCH DAMAGE.
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 __FBSDID("$FreeBSD$");
   33 
   34 #include <sys/param.h>
   35 #include <sys/systm.h>
   36 #include <sys/socket.h>
   37 #include <sys/malloc.h>
   38 #include <sys/kernel.h>
   39 #include <sys/module.h>
   40 
   41 #include <machine/bus.h>
   42 #include <machine/resource.h>
   43 #include <sys/bus.h>
   44 #include <sys/rman.h>
   45 
   46 #include <net/ethernet.h>
   47 #include <net/if.h>
   48 #include <net/if_arp.h>
   49 
   50 #include <dev/pci/pcireg.h>
   51 #include <dev/pci/pcivar.h>
   52 
   53 #include <dev/lnc/if_lncreg.h>
   54 #include <dev/lnc/if_lncvar.h>
   55 
   56 #define AMD_VENDOR_ID 0x1022
   57 #define PCI_DEVICE_ID_PCNet_PCI 0x2000
   58 #define PCI_DEVICE_ID_PCHome_PCI 0x2001
   59 
   60 #define LNC_PROBE_PRIORITY -1
   61 
   62 static int
   63 lnc_pci_probe(device_t dev)
   64 {
   65         if (pci_get_vendor(dev) != AMD_VENDOR_ID)
   66                 return (ENXIO);
   67 
   68         switch(pci_get_device(dev)) {
   69         case PCI_DEVICE_ID_PCNet_PCI:
   70                 device_set_desc(dev, "PCNet/PCI Ethernet adapter");
   71                 return(LNC_PROBE_PRIORITY);
   72                 break;
   73         case PCI_DEVICE_ID_PCHome_PCI:
   74                 device_set_desc(dev, "PCHome/PCI Ethernet adapter");
   75                 return(LNC_PROBE_PRIORITY);
   76                 break;
   77         default:
   78                 return (ENXIO);
   79                 break;
   80         }
   81         return (ENXIO);
   82 }
   83 
   84 static void
   85 lnc_alloc_callback(void *arg, bus_dma_segment_t *seg, int nseg, int error)
   86 {
   87         /* Do nothing */
   88         return;
   89 }
   90 
   91 static int
   92 lnc_pci_attach(device_t dev)
   93 {
   94         lnc_softc_t *sc = device_get_softc(dev);
   95         unsigned command;
   96         int err = 0;
   97         bus_size_t lnc_mem_size;
   98 
   99         device_printf(dev, "Attaching %s\n", device_get_desc(dev));
  100 
  101         command = pci_read_config(dev, PCIR_COMMAND, 4);
  102         command |= PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN;
  103         pci_write_config(dev, PCIR_COMMAND, command, 4);
  104 
  105         sc->portrid = PCIR_BAR(0);
  106         sc->portres = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->portrid,
  107                                              RF_ACTIVE);
  108 
  109         if (! sc->portres) {
  110                 device_printf(dev, "Cannot allocate I/O ports\n");
  111                 lnc_release_resources(dev);
  112                 return (ENXIO);
  113         }
  114         
  115         sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqrid,
  116                                             RF_ACTIVE|RF_SHAREABLE);
  117 
  118         if (! sc->irqres) {
  119                 device_printf(dev, "Cannot allocate irq\n");
  120                 lnc_release_resources(dev);
  121                 return (ENXIO);
  122         }
  123         err = bus_setup_intr(dev, sc->irqres, INTR_TYPE_NET, lncintr,
  124                              sc, &sc->intrhand);
  125         if (err) {
  126                 device_printf(dev, "Cannot setup irq handler\n");
  127                 lnc_release_resources(dev);
  128                 return (ENXIO);
  129         }
  130         sc->lnc_btag = rman_get_bustag(sc->portres);
  131         sc->lnc_bhandle = rman_get_bushandle(sc->portres);
  132 
  133         /* XXX temp setting for nic */
  134         sc->nic.ic = PCnet_PCI;
  135         sc->nic.ident = NE2100;
  136         sc->nic.mem_mode = DMA_FIXED;
  137         sc->nrdre  = NRDRE;
  138         sc->ntdre  = NTDRE;
  139         sc->rap = PCNET_RAP;
  140         sc->rdp = PCNET_RDP;
  141         sc->bdp = PCNET_BDP;
  142 
  143         /* Create a DMA tag describing the ring memory we need */
  144 
  145         lnc_mem_size = ((NDESC(sc->nrdre) + NDESC(sc->ntdre)) *
  146                          sizeof(struct host_ring_entry));
  147 
  148         lnc_mem_size += sizeof(struct init_block) + (sizeof(struct mds) *
  149                         (NDESC(sc->nrdre) + NDESC(sc->ntdre))) + MEM_SLEW;
  150 
  151         lnc_mem_size += (NDESC(sc->nrdre) * RECVBUFSIZE) +
  152                         (NDESC(sc->ntdre) * TRANSBUFSIZE);
  153 
  154         err = bus_dma_tag_create(NULL,                  /* parent */
  155                                  1,                     /* alignement */
  156                                  0,                     /* boundary */
  157                                  BUS_SPACE_MAXADDR_24BIT,       /* lowaddr */
  158                                  BUS_SPACE_MAXADDR,     /* highaddr */
  159                                  NULL, NULL,            /* filter, filterarg */
  160                                  lnc_mem_size,          /* segsize */
  161                                  1,                     /* nsegments */
  162                                  BUS_SPACE_MAXSIZE_32BIT,       /* maxsegsize */
  163                                  0,                     /* flags */
  164                                  busdma_lock_mutex,     /* lockfunc */
  165                                  &Giant,                /* lockarg */
  166                                  &sc->dmat);
  167 
  168         if (err) {
  169                 device_printf(dev, "Can't create DMA tag\n");
  170                 lnc_release_resources(dev);
  171                 return (ENOMEM);
  172         }
  173 
  174         err = bus_dmamem_alloc(sc->dmat, (void **)&sc->recv_ring,
  175                                BUS_DMA_NOWAIT, &sc->dmamap);
  176 
  177         if (err) {
  178                 device_printf(dev, "Couldn't allocate memory\n");
  179                 lnc_release_resources(dev);
  180                 return (ENOMEM);
  181         }
  182 
  183         bus_dmamap_load(sc->dmat, sc->dmamap, sc->recv_ring, lnc_mem_size,
  184                         lnc_alloc_callback, sc->recv_ring, BUS_DMA_NOWAIT);
  185 
  186         /* Call generic attach code */
  187         if (! lnc_attach_common(dev)) {
  188                 device_printf(dev, "Generic attach code failed\n");
  189                 lnc_release_resources(dev);
  190                 return (ENXIO);
  191         }
  192         return (0);
  193 }
  194 
  195 static int
  196 lnc_pci_detach(device_t dev)
  197 {
  198         lnc_softc_t *sc = device_get_softc(dev);
  199         int s = splimp();
  200 
  201         ether_ifdetach(&sc->arpcom.ac_if);
  202 
  203         lnc_stop(sc);
  204         bus_teardown_intr(dev, sc->irqres, sc->intrhand);
  205         bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irqres);
  206         bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->portres);
  207 
  208         bus_dmamap_unload(sc->dmat, sc->dmamap);
  209         bus_dmamem_free(sc->dmat, sc->recv_ring, sc->dmamap);
  210         bus_dma_tag_destroy(sc->dmat);
  211 
  212         splx(s);
  213         return (0);
  214 }
  215 
  216 static device_method_t lnc_pci_methods[] = {
  217         DEVMETHOD(device_probe,         lnc_pci_probe),
  218         DEVMETHOD(device_attach,        lnc_pci_attach),
  219         DEVMETHOD(device_detach,        lnc_pci_detach),
  220 #ifdef notyet
  221         DEVMETHOD(device_suspend,       lnc_pci_suspend),
  222         DEVMETHOD(device_resume,        lnc_pci_resume),
  223         DEVMETHOD(device_shutdown,      lnc_pci_shutdown),
  224 #endif
  225         { 0, 0 }
  226 };
  227 
  228 static driver_t lnc_pci_driver = {
  229         "lnc",
  230         lnc_pci_methods,
  231         sizeof(struct lnc_softc),
  232 };
  233 
  234 DRIVER_MODULE(lnc, pci, lnc_pci_driver, lnc_devclass, 0, 0);
  235 MODULE_DEPEND(lnc, pci, 1, 1, 1);
  236 MODULE_DEPEND(lnc, ether, 1, 1, 1);

Cache object: c779273ec105735c9ae7f4d7fc583297


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