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/ep/if_ep_eisa.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  * Product specific probe and attach routines for:
    3  *      3COM 3C579 and 3C509(in eisa config mode) ethernet controllers
    4  *
    5  * Copyright (c) 1996 Justin T. Gibbs
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice immediately at the beginning of the file, without modification,
   13  *    this list of conditions, and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. Absolutely no warranty of function or purpose is made by the author
   18  *    Justin T. Gibbs.
   19  * 4. Modifications may be freely made to this file if the above conditions
   20  *    are met.
   21  */
   22 
   23 #include <sys/cdefs.h>
   24 __FBSDID("$FreeBSD: releng/8.4/sys/dev/ep/if_ep_eisa.c 166901 2007-02-23 12:19:07Z piso $");
   25 
   26 #include <sys/param.h>
   27 #include <sys/systm.h>
   28 #include <sys/kernel.h>
   29 #include <sys/socket.h>
   30 #include <sys/module.h>
   31 #include <sys/bus.h>
   32 
   33 #include <machine/bus.h>
   34 #include <machine/resource.h>
   35 #include <sys/rman.h>
   36 
   37 #include <net/if.h>
   38 #include <net/if_arp.h>
   39 #include <net/if_media.h>
   40 
   41 #include <dev/eisa/eisaconf.h>
   42 
   43 #include <dev/ep/if_epreg.h>
   44 #include <dev/ep/if_epvar.h>
   45 
   46 #define EISA_DEVICE_ID_3COM_3C509_TP    0x506d5090
   47 #define EISA_DEVICE_ID_3COM_3C509_BNC   0x506d5091
   48 #define EISA_DEVICE_ID_3COM_3C579_TP    0x506d5092
   49 #define EISA_DEVICE_ID_3COM_3C579_BNC   0x506d5093
   50 #define EISA_DEVICE_ID_3COM_3C509_COMBO 0x506d5094
   51 #define EISA_DEVICE_ID_3COM_3C509_TPO   0x506d5095
   52 
   53 #define EP_EISA_SLOT_OFFSET             0x0c80
   54 #define EP_EISA_IOSIZE                  0x000a
   55 
   56 #define EISA_IOCONF                     0x0008
   57 #define         IRQ_CHANNEL             0xf000
   58 #define                 INT_3           0x3000
   59 #define                 INT_5           0x5000
   60 #define                 INT_7           0x7000
   61 #define                 INT_9           0x9000
   62 #define                 INT_10          0xa000
   63 #define                 INT_11          0xb000
   64 #define                 INT_12          0xc000
   65 #define                 INT_15          0xf000
   66 #define EISA_BPROM_MEDIA_CONF           0x0006
   67 #define         TRANS_TYPE              0xc000
   68 #define                 TRANS_TP        0x0000
   69 #define                 TRANS_AUI       0x4000
   70 #define                 TRANS_BNC       0xc000
   71 
   72 static const char *ep_match(eisa_id_t type);
   73 
   74 static const char *
   75 ep_match(eisa_id_t type)
   76 {
   77         switch (type) {
   78         case EISA_DEVICE_ID_3COM_3C509_TP:
   79                 return ("3Com 3C509-TP");
   80         case EISA_DEVICE_ID_3COM_3C509_BNC:
   81                 return ("3Com 3C509-BNC");
   82         case EISA_DEVICE_ID_3COM_3C579_TP:
   83                 return ("3Com 3C579-TP");
   84         case EISA_DEVICE_ID_3COM_3C579_BNC:
   85                 return ("3Com 3C579-BNC");
   86         case EISA_DEVICE_ID_3COM_3C509_COMBO:
   87                 return ("3Com 3C509-Combo");
   88         case EISA_DEVICE_ID_3COM_3C509_TPO:
   89                 return ("3Com 3C509-TPO");
   90         default:
   91                 return (NULL);
   92         }
   93 }
   94 
   95 static int
   96 ep_eisa_probe(device_t dev)
   97 {
   98         const char *desc;
   99         u_long iobase;
  100         u_short conf;
  101         u_long port;
  102         int irq;
  103         int int_trig;
  104 
  105         desc = ep_match(eisa_get_id(dev));
  106         if (!desc)
  107                 return (ENXIO);
  108         device_set_desc(dev, desc);
  109 
  110         port = (eisa_get_slot(dev) * EISA_SLOT_SIZE);
  111         iobase = port + EP_EISA_SLOT_OFFSET;
  112 
  113         /* We must be in EISA configuration mode */
  114         if ((inw(iobase + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
  115                 return (ENXIO);
  116 
  117         eisa_add_iospace(dev, iobase, EP_EISA_IOSIZE, RESVADDR_NONE);
  118         eisa_add_iospace(dev, port, EP_IOSIZE, RESVADDR_NONE);
  119 
  120         conf = inw(iobase + EISA_IOCONF);
  121         /* Determine our IRQ */
  122         switch (conf & IRQ_CHANNEL) {
  123         case INT_3:
  124                 irq = 3;
  125                 break;
  126         case INT_5:
  127                 irq = 5;
  128                 break;
  129         case INT_7:
  130                 irq = 7;
  131                 break;
  132         case INT_9:
  133                 irq = 9;
  134                 break;
  135         case INT_10:
  136                 irq = 10;
  137                 break;
  138         case INT_11:
  139                 irq = 11;
  140                 break;
  141         case INT_12:
  142                 irq = 12;
  143                 break;
  144         case INT_15:
  145                 irq = 15;
  146                 break;
  147         default:
  148                 /* Disabled */
  149                 printf("ep: 3COM Network Adapter at "
  150                     "slot %d has its IRQ disabled. "
  151                     "Probe failed.\n",
  152                     eisa_get_slot(dev));
  153                 return (ENXIO);
  154         }
  155 
  156         switch (eisa_get_id(dev)) {
  157         case EISA_DEVICE_ID_3COM_3C579_BNC:
  158         case EISA_DEVICE_ID_3COM_3C579_TP:
  159                 int_trig = EISA_TRIGGER_LEVEL;
  160                 break;
  161         default:
  162                 int_trig = EISA_TRIGGER_EDGE;
  163                 break;
  164         }
  165 
  166         eisa_add_intr(dev, irq, int_trig);
  167 
  168         return (0);
  169 }
  170 
  171 static int
  172 ep_eisa_attach(device_t dev)
  173 {
  174         struct ep_softc *sc = device_get_softc(dev);
  175         struct resource *eisa_io = NULL;
  176         uint32_t eisa_iobase;
  177         int irq;
  178         int error = 0;
  179         int rid;
  180 
  181         rid = 1;
  182         eisa_io = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
  183         if (!eisa_io) {
  184                 device_printf(dev, "No I/O space?!\n");
  185                 error = ENXIO;
  186                 goto bad;
  187         }
  188         eisa_iobase = rman_get_start(eisa_io);
  189 
  190         /* Reset and Enable the card */
  191         outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_RESET_ADAPTER);
  192         DELAY(1000);            /* we must wait at least 1 ms */
  193         outb(eisa_iobase + EP_W0_CONFIG_CTRL, W0_P4_CMD_ENABLE_ADAPTER);
  194         /* Now the registers are availible through the lower ioport */
  195 
  196         if ((error = ep_alloc(dev))) {
  197                 device_printf(dev, "ep_alloc() failed! (%d)\n", error);
  198                 goto bad;
  199         }
  200         switch (eisa_get_id(dev)) {
  201         case EISA_DEVICE_ID_3COM_3C579_BNC:
  202         case EISA_DEVICE_ID_3COM_3C579_TP:
  203                 sc->stat = F_ACCESS_32_BITS;
  204                 break;
  205         }
  206 
  207         ep_get_media(sc);
  208 
  209         irq = rman_get_start(sc->irq);
  210         if (irq == 9)
  211                 irq = 2;
  212 
  213         GO_WINDOW(sc, 0);
  214         SET_IRQ(sc, irq);
  215 
  216         if ((error = ep_attach(sc))) {
  217                 device_printf(dev, "ep_attach() failed! (%d)\n", error);
  218                 goto bad;
  219         }
  220         if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, 
  221             NULL, ep_intr, sc, &sc->ep_intrhand))) {
  222                 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error);
  223                 goto bad;
  224         }
  225         return (0);
  226 
  227 bad:
  228         if (eisa_io)
  229                 bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io);
  230 
  231         ep_free(dev);
  232         return (error);
  233 }
  234 
  235 static device_method_t ep_eisa_methods[] = {
  236         /* Device interface */
  237         DEVMETHOD(device_probe, ep_eisa_probe),
  238         DEVMETHOD(device_attach, ep_eisa_attach),
  239         DEVMETHOD(device_detach, ep_detach),
  240 
  241         {0, 0}
  242 };
  243 
  244 static driver_t ep_eisa_driver = {
  245         "ep",
  246         ep_eisa_methods,
  247         sizeof(struct ep_softc),
  248 };
  249 
  250 extern devclass_t ep_devclass;
  251 
  252 DRIVER_MODULE(ep, eisa, ep_eisa_driver, ep_devclass, 0, 0);

Cache object: e928f347bb137e254e15318746605b0e


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