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/ex/if_ex_isa.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) 2000 Matthew N. Dodd
    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, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  *      $FreeBSD: releng/5.1/sys/dev/ex/if_ex_isa.c 112801 2003-03-29 15:38:53Z mdodd $
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/systm.h>
   31 #include <sys/kernel.h>
   32 #include <sys/socket.h>
   33 
   34 #include <sys/module.h>
   35 #include <sys/bus.h>
   36 
   37 #include <machine/bus.h>
   38 #include <machine/resource.h>
   39 #include <sys/rman.h>
   40 
   41 #include <net/if.h>
   42 #include <net/if_arp.h>
   43 #include <net/if_media.h> 
   44 
   45 
   46 #include <isa/isavar.h>
   47 #include <isa/pnpvar.h>
   48 
   49 #include <dev/ex/if_exreg.h>
   50 #include <dev/ex/if_exvar.h>
   51 
   52 /* Bus Front End Functions */
   53 static void     ex_isa_identify (driver_t *, device_t);
   54 static int      ex_isa_probe    (device_t);
   55 static int      ex_isa_attach   (device_t);
   56 
   57 #if 0
   58 static  void    ex_pnp_wakeup   (void *);
   59 
   60 SYSINIT(ex_pnpwakeup, SI_SUB_CPU, SI_ORDER_ANY, ex_pnp_wakeup, NULL);
   61 #endif
   62 
   63 static device_method_t ex_isa_methods[] = {
   64         /* Device interface */
   65         DEVMETHOD(device_identify,      ex_isa_identify),
   66         DEVMETHOD(device_probe,         ex_isa_probe),
   67         DEVMETHOD(device_attach,        ex_isa_attach),
   68         DEVMETHOD(device_detach,        ex_detach),
   69 
   70         { 0, 0 }
   71 };
   72 
   73 static driver_t ex_isa_driver = {
   74         "ex",
   75         ex_isa_methods,
   76         sizeof(struct ex_softc),
   77 };
   78 
   79 DRIVER_MODULE(ex, isa, ex_isa_driver, ex_devclass, 0, 0);
   80 
   81 static struct isa_pnp_id ex_ids[] = {
   82         { 0x3110d425,   NULL }, /* INT1031 */
   83         { 0x3010d425,   NULL }, /* INT1030 */
   84         { 0,            NULL },
   85 };
   86 
   87 #if 0
   88 #define EX_PNP_WAKE             0x279
   89 
   90 static u_int8_t ex_pnp_wake_seq[] =
   91                         { 0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,
   92                           0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,
   93                           0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,
   94                           0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43 };
   95 
   96 static void
   97 ex_pnp_wakeup (void * dummy)
   98 {
   99         int     tmp;
  100 
  101         if (bootverbose)
  102                 printf("ex_pnp_wakeup()\n");
  103 
  104         outb(EX_PNP_WAKE, 0);
  105         outb(EX_PNP_WAKE, 0);
  106         for (tmp = 0; tmp < 32; tmp++) {
  107                 outb(EX_PNP_WAKE, ex_pnp_wake_seq[tmp]);
  108         }
  109 }
  110 #endif
  111 
  112 /*
  113  * Non-destructive identify.
  114  */
  115 static void
  116 ex_isa_identify (driver_t *driver, device_t parent)
  117 {
  118         device_t        child;
  119         u_int32_t       ioport;
  120         u_char          enaddr[6];
  121         u_int           irq;
  122         int             tmp;
  123         const char *    desc;
  124 
  125         if (bootverbose)
  126                 printf("ex_isa_identify()\n");
  127 
  128         for (ioport = 0x200; ioport < 0x3a0; ioport += 0x10) {
  129 
  130                 /* No board found at address */
  131                 if (!look_for_card(ioport)) {
  132                         continue;
  133                 }
  134 
  135                 if (bootverbose)
  136                         printf("ex: Found card at 0x%03x!\n", ioport);
  137 
  138                 /* Board in PnP mode */
  139                 if (eeprom_read(ioport, EE_W0) & EE_W0_PNP) {
  140                         /* Reset the card. */
  141                         outb(ioport + CMD_REG, Reset_CMD);
  142                         DELAY(500);
  143                         if (bootverbose)
  144                                 printf("ex: card at 0x%03x in PnP mode!\n", ioport);
  145                         continue;
  146                 }
  147 
  148                 bzero(enaddr, sizeof(enaddr));
  149 
  150                 /* Reset the card. */
  151                 outb(ioport + CMD_REG, Reset_CMD);
  152                 DELAY(400);
  153 
  154                 ex_get_address(ioport, enaddr);
  155                 tmp = eeprom_read(ioport, EE_W1) & EE_W1_INT_SEL;
  156 
  157                 /* work out which set of irq <-> internal tables to use */
  158                 if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) {
  159                         irq  = plus_ee2irqmap[tmp];
  160                         desc = "Intel Pro/10+";
  161                 } else {
  162                         irq = ee2irqmap[tmp];
  163                         desc = "Intel Pro/10";
  164                 }
  165 
  166                 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1);
  167                 device_set_desc_copy(child, desc);
  168                 device_set_driver(child, driver);
  169                 bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1);
  170                 bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EX_IOSIZE);
  171 
  172                 if (bootverbose)
  173                         printf("ex: Adding board at 0x%03x, irq %d\n", ioport, irq);
  174         }
  175 
  176         return;
  177 }
  178 
  179 static int
  180 ex_isa_probe(device_t dev)
  181 {
  182         u_int           iobase;
  183         u_int           irq;
  184         char *          irq2ee;
  185         u_char *        ee2irq;
  186         u_char          enaddr[6];
  187         int             tmp;
  188         int             error;
  189 
  190         /* Check isapnp ids */
  191         error = ISA_PNP_PROBE(device_get_parent(dev), dev, ex_ids);
  192 
  193         /* If the card had a PnP ID that didn't match any we know about */
  194         if (error == ENXIO) {
  195                 return(error);
  196         }
  197 
  198         /* If we had some other problem. */
  199         if (!(error == 0 || error == ENOENT)) {
  200                 return(error);
  201         }
  202 
  203         iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0);
  204         if (!iobase) {
  205                 printf("ex: no iobase?\n");
  206                 return(ENXIO);
  207         }
  208 
  209         if (!look_for_card(iobase)) {
  210                 printf("ex: no card found at 0x%03x\n", iobase);
  211                 return(ENXIO);
  212         }
  213 
  214         if (bootverbose)
  215                 printf("ex: ex_isa_probe() found card at 0x%03x\n", iobase);
  216 
  217         /*
  218          * Reset the card.
  219          */
  220         outb(iobase + CMD_REG, Reset_CMD);
  221         DELAY(800);
  222 
  223         ex_get_address(iobase, enaddr);
  224 
  225         /* work out which set of irq <-> internal tables to use */
  226         if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) {
  227                 irq2ee = plus_irq2eemap;
  228                 ee2irq = plus_ee2irqmap;
  229         } else {
  230                 irq2ee = irq2eemap;
  231                 ee2irq = ee2irqmap;
  232         }
  233 
  234         tmp = eeprom_read(iobase, EE_W1) & EE_W1_INT_SEL;
  235         irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0);
  236 
  237         if (irq > 0) {
  238                 /* This will happen if board is in PnP mode. */
  239                 if (ee2irq[tmp] != irq) {
  240                         printf("ex: WARNING: board's EEPROM is configured"
  241                                 " for IRQ %d, using %d\n",
  242                                 ee2irq[tmp], irq);
  243                 }
  244         } else {
  245                 irq = ee2irq[tmp];
  246                 bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
  247         }
  248 
  249         if (irq == 0) {
  250                 printf("ex: invalid IRQ.\n");
  251                 return(ENXIO);
  252         }
  253 
  254         return(0);
  255 }
  256 
  257 static int
  258 ex_isa_attach(device_t dev)
  259 {
  260         struct ex_softc *       sc = device_get_softc(dev);
  261         int                     error = 0;
  262         u_int16_t               temp;
  263 
  264         sc->dev = dev;
  265         sc->ioport_rid = 0;
  266         sc->irq_rid = 0;
  267 
  268         if ((error = ex_alloc_resources(dev)) != 0) {
  269                 device_printf(dev, "ex_alloc_resources() failed!\n");
  270                 goto bad;
  271         }
  272 
  273         /*
  274          * Fill in several fields of the softc structure:
  275          *      - I/O base address.
  276          *      - Hardware Ethernet address.
  277          *      - IRQ number (if not supplied in config file, read it from EEPROM).
  278          *      - Connector type.
  279          */
  280         sc->iobase = rman_get_start(sc->ioport);
  281         sc->irq_no = rman_get_start(sc->irq);
  282 
  283         ex_get_address(sc->iobase, sc->arpcom.ac_enaddr);
  284 
  285         temp = eeprom_read(sc->iobase, EE_W0);
  286         device_printf(sc->dev, "%s config, %s bus, ",
  287                 (temp & EE_W0_PNP) ? "PnP" : "Manual",
  288                 (temp & EE_W0_BUS16) ? "16-bit" : "8-bit");
  289 
  290         temp = eeprom_read(sc->iobase, EE_W6);
  291         printf("board id 0x%03x, stepping 0x%01x\n",
  292                 (temp & EE_W6_BOARD_MASK) >> EE_W6_BOARD_SHIFT,
  293                 temp & EE_W6_STEP_MASK);
  294 
  295         if ((error = ex_attach(dev)) != 0) {
  296                 device_printf(dev, "ex_attach() failed!\n");
  297                 goto bad;
  298         }
  299 
  300         error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
  301                                 ex_intr, (void *)sc, &sc->ih);
  302         if (error) {
  303                 device_printf(dev, "bus_setup_intr() failed!\n");
  304                 goto bad;
  305         }
  306 
  307         return(0);
  308 bad:
  309         ex_release_resources(dev);
  310         return (error);
  311 }

Cache object: 2117dccada9d0f7ea17de35988726e0b


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