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/i386/eisa/bt_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  *      Buslogic BT74x SCSI controllers
    4  *
    5  * Copyright (c) 1995, 1998, 1999 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. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * $FreeBSD$
   30  */
   31 
   32 #include "eisa.h"
   33 #if NEISA > 0
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/kernel.h>
   38 
   39 #include <machine/bus_pio.h>
   40 #include <machine/bus.h>
   41 
   42 #include <i386/eisa/eisaconf.h>
   43 
   44 #include <dev/buslogic/btreg.h>
   45 
   46 #define EISA_DEVICE_ID_BUSLOGIC_74X_B   0x0ab34201
   47 #define EISA_DEVICE_ID_BUSLOGIC_74X_C   0x0ab34202
   48 #define EISA_DEVICE_ID_SDC3222F         0x0ab34781
   49 #define EISA_DEVICE_ID_AMI_4801         0x05a94801
   50 
   51 #define BT_IOSIZE               0x04            /* Move to central header */
   52 #define BT_EISA_IOSIZE          0x100
   53 #define BT_EISA_SLOT_OFFSET     0xc00
   54 
   55 #define EISA_IOCONF                     0x08C
   56 #define         PORTADDR                0x07
   57 #define                 PORT_330        0x00
   58 #define                 PORT_334        0x01
   59 #define                 PORT_230        0x02
   60 #define                 PORT_234        0x03
   61 #define                 PORT_130        0x04
   62 #define                 PORT_134        0x05
   63 #define         IRQ_CHANNEL             0xe0
   64 #define                 INT_11          0x40
   65 #define                 INT_10          0x20
   66 #define                 INT_15          0xa0
   67 #define                 INT_12          0x60
   68 #define                 INT_14          0x80
   69 #define                 INT_9           0x00
   70 
   71 #define EISA_IRQ_TYPE                   0x08D
   72 #define       LEVEL                     0x40
   73 
   74 /* Definitions for the AMI Series 48 controler */
   75 #define AMI_EISA_IOSIZE                 0x500   /* Two separate ranges?? */
   76 #define AMI_EISA_SLOT_OFFSET            0x800
   77 #define AMI_EISA_IOCONF                 0x000
   78 #define         AMI_DMA_CHANNEL         0x03
   79 #define         AMI_IRQ_CHANNEL         0x1c
   80 #define                 AMI_INT_15      0x14
   81 #define                 AMI_INT_14      0x10
   82 #define                 AMI_INT_12      0x0c
   83 #define                 AMI_INT_11      0x00
   84 #define                 AMI_INT_10      0x08
   85 #define                 AMI_INT_9       0x04
   86 #define         AMI_BIOS_ADDR           0xe0
   87 
   88 #define AMI_EISA_IOCONF1                0x001
   89 #define         AMI_PORTADDR            0x0e
   90 #define                 AMI_PORT_334    0x08
   91 #define                 AMI_PORT_330    0x00
   92 #define                 AMI_PORT_234    0x0c
   93 #define                 AMI_PORT_230    0x04
   94 #define                 AMI_PORT_134    0x0a
   95 #define                 AMI_PORT_130    0x02
   96 #define         AMI_IRQ_LEVEL           0x01
   97 
   98 
   99 #define AMI_MISC2_OPTIONS               0x49E
  100 #define         AMI_ENABLE_ISA_DMA      0x08
  101 
  102 static int      bt_eisa_probe(void);
  103 static int      bt_eisa_attach(struct eisa_device *e_dev);
  104 
  105 static struct eisa_driver bt_eisa_driver = {
  106         "bt",
  107         bt_eisa_probe,
  108         bt_eisa_attach,
  109         /*shutdown*/NULL,
  110         &bt_unit
  111 };
  112 
  113 DATA_SET (eisadriver_set, bt_eisa_driver);
  114 
  115 static const char *bt_match(eisa_id_t type);
  116 
  117 static const char*
  118 bt_match(eisa_id_t type)
  119 {
  120         switch(type) {
  121                 case EISA_DEVICE_ID_BUSLOGIC_74X_B:
  122                         return ("Buslogic 74xB SCSI host adapter");
  123                         break;
  124                 case EISA_DEVICE_ID_BUSLOGIC_74X_C:
  125                         return ("Buslogic 74xC SCSI host adapter");
  126                         break;
  127                 case EISA_DEVICE_ID_SDC3222F:
  128                         return ("Storage Dimensions SDC3222F SCSI host adapter");
  129                         break;
  130                 case EISA_DEVICE_ID_AMI_4801:
  131                         return ("AMI Series 48 SCSI host adapter");
  132                         break;
  133                 default:
  134                         break;
  135         }
  136         return (NULL);
  137 }
  138 
  139 static int
  140 bt_eisa_probe(void)
  141 {
  142         u_long iobase;
  143         struct eisa_device *e_dev = NULL;
  144         int count;
  145 
  146         count = 0;
  147         while ((e_dev = eisa_match_dev(e_dev, bt_match))) {
  148                 struct bt_softc *bt;
  149                 struct bt_probe_info info;
  150                 u_long port;
  151                 u_long iosize;
  152                 u_int  ioconf;
  153 
  154                 iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE); 
  155                 if (e_dev->id == EISA_DEVICE_ID_AMI_4801) {
  156                         u_int ioconf1;
  157 
  158                         iobase += AMI_EISA_SLOT_OFFSET;
  159                         iosize = AMI_EISA_IOSIZE;
  160                         ioconf1 = inb(iobase + AMI_EISA_IOCONF1);
  161                         /* Determine "ISA" I/O port */
  162                         switch (ioconf1 & AMI_PORTADDR) {
  163                                 case AMI_PORT_330:
  164                                         port = 0x330;
  165                                         break;
  166                                 case AMI_PORT_334:
  167                                         port = 0x334;
  168                                         break;
  169                                 case AMI_PORT_230:
  170                                         port = 0x230;
  171                                         break;
  172                                 case AMI_PORT_234:
  173                                         port = 0x234;
  174                                         break;
  175                                 case AMI_PORT_134:
  176                                         port = 0x134;
  177                                         break;
  178                                 case AMI_PORT_130:
  179                                         port = 0x130;
  180                                         break;
  181                                 default:
  182                                         /* Disabled */
  183                                         printf("bt: AMI EISA Adapter at "
  184                                                "slot %d has a disabled I/O "
  185                                                "port.  Cannot attach.\n",
  186                                                e_dev->ioconf.slot);
  187                                         continue;
  188                         }
  189                 } else {
  190                         iobase += BT_EISA_SLOT_OFFSET;
  191                         iosize = BT_EISA_IOSIZE;
  192 
  193                         ioconf = inb(iobase + EISA_IOCONF);
  194                         /* Determine "ISA" I/O port */
  195                         switch (ioconf & PORTADDR) {
  196                                 case PORT_330:
  197                                         port = 0x330;
  198                                         break;
  199                                 case PORT_334:
  200                                         port = 0x334;
  201                                         break;
  202                                 case PORT_230:
  203                                         port = 0x230;
  204                                         break;
  205                                 case PORT_234:
  206                                         port = 0x234;
  207                                         break;
  208                                 case PORT_130:
  209                                         port = 0x130;
  210                                         break;
  211                                 case PORT_134:
  212                                         port = 0x134;
  213                                         break;
  214                                 default:
  215                                         /* Disabled */
  216                                         printf("bt: Buslogic EISA Adapter at "
  217                                                "slot %d has a disabled I/O "
  218                                                "port.  Cannot attach.\n",
  219                                                e_dev->ioconf.slot);
  220                                         continue;
  221                         }
  222                 }
  223                 bt_mark_probed_iop(port);
  224 
  225                 /* Allocate a softc for use during probing */
  226                 bt = bt_alloc(BT_TEMP_UNIT, I386_BUS_SPACE_IO, port);
  227 
  228                 if (bt == NULL) {
  229                         printf("bt_eisa_probe: Could not allocate softc for "
  230                                "card at slot 0x%x\n", e_dev->ioconf.slot);
  231                         continue;
  232                 }
  233 
  234                 if (bt_port_probe(bt, &info) != 0) {
  235                         printf("bt_eisa_probe: Probe failed for "
  236                                "card at slot 0x%x\n", e_dev->ioconf.slot);
  237                 } else {
  238                         eisa_add_iospace(e_dev, iobase, iosize, RESVADDR_NONE);
  239                         eisa_add_iospace(e_dev, port, BT_IOSIZE, RESVADDR_NONE);
  240                         eisa_add_intr(e_dev, info.irq);
  241 
  242                         eisa_registerdev(e_dev, &bt_eisa_driver);
  243 
  244                         count++;
  245                 }
  246                 bt_free(bt);
  247         }
  248         return count;
  249 }
  250 
  251 static int
  252 bt_eisa_attach(struct eisa_device *e_dev)
  253 {
  254         struct bt_softc *bt;
  255         int unit = e_dev->unit;
  256         int irq;
  257         resvaddr_t *ioport;
  258         resvaddr_t *eisa_ioport;
  259 
  260         if (TAILQ_FIRST(&e_dev->ioconf.irqs) == NULL)
  261                 return (-1);
  262 
  263         irq = TAILQ_FIRST(&e_dev->ioconf.irqs)->irq_no;
  264 
  265         /*
  266          * The addresses are sorted in increasing order
  267          * so we know the port to pass to the core bt
  268          * driver comes first.
  269          */
  270         ioport = e_dev->ioconf.ioaddrs.lh_first;
  271 
  272         if (ioport == NULL)
  273                 return -1;
  274 
  275         eisa_ioport = ioport->links.le_next;
  276 
  277         if (eisa_ioport == NULL)
  278                 return -1;
  279 
  280         eisa_reg_start(e_dev);
  281         if (eisa_reg_iospace(e_dev, ioport))
  282                 return -1;
  283 
  284         if (eisa_reg_iospace(e_dev, eisa_ioport))
  285                 return -1;
  286 
  287         if ((bt = bt_alloc(unit, I386_BUS_SPACE_IO, ioport->addr)) == NULL)
  288                 return -1;
  289 
  290         /* Allocate a dmatag for our SCB DMA maps */
  291         /* XXX Should be a child of the PCI bus dma tag */
  292         if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, /*boundary*/0,
  293                                /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
  294                                /*highaddr*/BUS_SPACE_MAXADDR,
  295                                /*filter*/NULL, /*filterarg*/NULL,
  296                                /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
  297                                /*nsegments*/BUS_SPACE_UNRESTRICTED,
  298                                /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  299                                /*flags*/0, &bt->parent_dmat) != 0) {
  300                 bt_free(bt);
  301                 return -1;
  302         }
  303 
  304         if (eisa_reg_intr(e_dev, irq, bt_intr, (void *)bt, &cam_imask,
  305                           /*shared ==*/bt->level_trigger_ints ? 1 : 0)) {
  306                 bt_free(bt);
  307                 return -1;
  308         }
  309         eisa_reg_end(e_dev);
  310 
  311         /*
  312          * Now that we know we own the resources we need, do the full
  313          * card initialization.
  314          */
  315         if (bt_probe(bt) || bt_fetch_adapter_info(bt) || bt_init(bt)) {
  316                 bt_free(bt);
  317                 /*
  318                  * The board's IRQ line will not be left enabled
  319                  * if we can't intialize correctly, so its safe
  320                  * to release the irq.
  321                  */
  322                 eisa_release_intr(e_dev, irq, bt_intr);
  323                 return -1;
  324         }
  325 
  326         /* Attach sub-devices - always succeeds */
  327         bt_attach(bt);
  328 
  329         if (eisa_enable_intr(e_dev, irq)) {
  330                 bt_free(bt);
  331                 eisa_release_intr(e_dev, irq, bt_intr);
  332                 return -1;
  333         }
  334 
  335         return 0;
  336 }
  337 
  338 #endif /* NEISA > 0 */

Cache object: 96edbe255f722485daa6c04b59617bb0


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