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/isa/bt_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  * Product specific probe and attach routines for:
    3  *      Buslogic BT-54X and BT-445 cards
    4  *
    5  * Copyright (c) 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, this list of conditions, and the following disclaimer,
   13  *    without modification, immediately at the beginning of the file.
   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 <sys/param.h>
   33 #include <sys/systm.h>
   34 
   35 #include <machine/bus_pio.h>
   36 #include <machine/bus.h>
   37 
   38 #include <i386/isa/isa_device.h>
   39 #include <dev/buslogic/btreg.h>
   40 
   41 #include <cam/scsi/scsi_all.h>
   42 
   43 static  int bt_isa_probe __P((struct isa_device *dev));
   44 static  int bt_isa_attach __P((struct isa_device *dev));
   45 static  void bt_isa_intr __P((void *unit));
   46 
   47 static  bus_dma_filter_t btvlbouncefilter;
   48 static  bus_dmamap_callback_t btmapsensebuffers;
   49 
   50 struct isa_driver btdriver =
   51 {
   52     bt_isa_probe,
   53     bt_isa_attach,
   54     "bt"
   55 };
   56 
   57 /*
   58  * Check if the device can be found at the port given
   59  * and if so, set it up ready for further work
   60  * as an argument, takes the isa_device structure from
   61  * autoconf.c
   62  */
   63 static int
   64 bt_isa_probe(dev)
   65         struct isa_device *dev;
   66 {
   67         /*
   68          * find unit and check we have that many defined
   69          */
   70         struct  bt_softc *bt;
   71         int     port_index;
   72         int     max_port_index;
   73 
   74         /*
   75          * We ignore the unit number assigned by config to allow
   76          * consistant numbering between PCI/EISA/ISA devices.
   77          * This is a total kludge until we have a configuration
   78          * manager.
   79          */
   80         dev->id_unit = bt_unit;
   81 
   82         bt = NULL;
   83         port_index = 0;
   84         max_port_index = BT_NUM_ISAPORTS - 1;
   85         /*
   86          * Bound our board search if the user has
   87          * specified an exact port.
   88          */
   89         bt_find_probe_range(dev->id_iobase, &port_index, &max_port_index);
   90 
   91         if (port_index < 0)
   92                 return 0;
   93 
   94         /* Attempt to find an adapter */
   95         for (;port_index <= max_port_index; port_index++) {
   96                 struct bt_probe_info info;
   97                 u_int ioport;
   98 
   99                 ioport = bt_iop_from_bio(port_index);
  100 
  101                 /*
  102                  * Ensure this port has not already been claimed already
  103                  * by a PCI, EISA or ISA adapter.
  104                  */
  105                 if (bt_check_probed_iop(ioport) != 0)
  106                         continue;
  107                 dev->id_iobase = ioport;
  108                 if (haveseen_isadev(dev, CC_IOADDR | CC_QUIET))
  109                         continue;
  110 
  111                 /* Allocate a softc for use during probing */
  112                 bt = bt_alloc(dev->id_unit, I386_BUS_SPACE_IO, ioport);
  113 
  114                 if (bt == NULL)
  115                         break;
  116 
  117                 /* We're going to attempt to probe it now, so mark it probed */
  118                 bt_mark_probed_bio(port_index);
  119 
  120                 if (bt_port_probe(bt, &info) != 0) {
  121                         if (bootverbose)
  122                                 printf("bt_isa_probe: Probe failed for card at 0x%x\n", ioport);
  123                         bt_free(bt);
  124                         continue;
  125                 }
  126 
  127                 dev->id_drq = info.drq;
  128                 dev->id_irq = 0x1 << info.irq;
  129                 dev->id_intr = bt_isa_intr;
  130 
  131                 bt_unit++;
  132                 return (BT_NREGS);
  133         }
  134 
  135         return (0);
  136 }
  137 
  138 /*
  139  * Attach all the sub-devices we can find
  140  */
  141 static int
  142 bt_isa_attach(dev)
  143         struct isa_device *dev;
  144 {
  145         struct  bt_softc *bt;
  146         bus_dma_filter_t *filter;
  147         void             *filter_arg;
  148         bus_addr_t       lowaddr;
  149 
  150         bt = bt_softcs[dev->id_unit];
  151         if (dev->id_drq != -1)
  152                 isa_dmacascade(dev->id_drq);
  153 
  154         /* Allocate our parent dmatag */
  155         filter = NULL;
  156         filter_arg = NULL;
  157         lowaddr = BUS_SPACE_MAXADDR_24BIT;
  158         if (bt->model[0] == '4') {
  159                 /*
  160                  * This is a VL adapter.  Typically, VL devices have access
  161                  * to the full 32bit address space.  On BT-445S adapters
  162                  * prior to revision E, there is a hardware bug that causes
  163                  * corruption of transfers to/from addresses in the range of
  164                  * the BIOS modulo 16MB.  The only properly functioning
  165                  * BT-445S Host Adapters have firmware version 3.37.
  166                  * If we encounter one of these adapters and the BIOS is
  167                  * installed, install a filter function for our bus_dma_map
  168                  * that will catch these accesses and bounce them to a safe
  169                  * region of memory.
  170                  */
  171                 if (bt->bios_addr != 0
  172                  && strcmp(bt->model, "445S") == 0
  173                  && strcmp(bt->firmware_ver, "3.37") < 0) {
  174                         filter = btvlbouncefilter;
  175                         filter_arg = bt;
  176                 } else {
  177                         lowaddr = BUS_SPACE_MAXADDR_32BIT;
  178                 }
  179         }
  180                         
  181         /* XXX Should be a child of the ISA or VL bus dma tag */
  182         if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0,
  183                                lowaddr, /*highaddr*/BUS_SPACE_MAXADDR,
  184                                filter, filter_arg,
  185                                /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
  186                                /*nsegments*/BUS_SPACE_UNRESTRICTED,
  187                                /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  188                                /*flags*/0, &bt->parent_dmat) != 0) {
  189                 bt_free(bt);
  190                 return (-1);
  191         }                              
  192 
  193         if (bt_init(bt)) {
  194                 bt_free(bt);
  195                 return (-1);
  196         }
  197 
  198         if (lowaddr != BUS_SPACE_MAXADDR_32BIT) {
  199                 /* DMA tag for our sense buffers */
  200                 if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/1,
  201                                        /*boundary*/0,
  202                                        /*lowaddr*/BUS_SPACE_MAXADDR,
  203                                        /*highaddr*/BUS_SPACE_MAXADDR,
  204                                        /*filter*/NULL, /*filterarg*/NULL,
  205                                        bt->max_ccbs
  206                                            * sizeof(struct scsi_sense_data),
  207                                        /*nsegments*/1,
  208                                        /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  209                                        /*flags*/0, &bt->sense_dmat) != 0) {
  210                         bt_free(bt);
  211                         return (-1);
  212                 }
  213 
  214                 bt->init_level++;
  215 
  216                 /* Allocation of sense buffers */
  217                 if (bus_dmamem_alloc(bt->sense_dmat,
  218                                      (void **)&bt->sense_buffers,
  219                                      BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
  220                         bt_free(bt);
  221                         return (-1);
  222                 }
  223 
  224                 bt->init_level++;
  225 
  226                 /* And permanently map them */
  227                 bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap,
  228                                 bt->sense_buffers,
  229                                 bt->max_ccbs * sizeof(*bt->sense_buffers),
  230                                 btmapsensebuffers, bt, /*flags*/0);
  231 
  232                 bt->init_level++;
  233         }
  234 
  235         return (bt_attach(bt));
  236 }
  237 
  238 /*
  239  * Handle an ISA interrupt.
  240  * XXX should go away as soon as ISA interrupt handlers
  241  * take a (void *) arg.
  242  */
  243 static void
  244 bt_isa_intr(void *unit)
  245 {
  246         struct bt_softc* arg = bt_softcs[(int)unit];
  247         bt_intr((void *)arg);
  248 }
  249 
  250 #define BIOS_MAP_SIZE (16 * 1024)
  251 
  252 static int
  253 btvlbouncefilter(void *arg, bus_addr_t addr)
  254 {
  255         struct bt_softc *bt;
  256 
  257         bt = (struct bt_softc *)arg;
  258 
  259         addr &= BUS_SPACE_MAXADDR_24BIT;
  260 
  261         if (addr == 0
  262          || (addr >= bt->bios_addr
  263           && addr < (bt->bios_addr + BIOS_MAP_SIZE)))
  264                 return (1);
  265         return (0);
  266 }
  267 
  268 static void
  269 btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error)
  270 {
  271         struct bt_softc* bt;
  272 
  273         bt = (struct bt_softc*)arg;
  274         bt->sense_buffers_physbase = segs->ds_addr;
  275 }

Cache object: 9644e8887eb6b3a6ebf64cb5f4e9eb03


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