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/buslogic/bt_mca.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) 1999 Matthew N. Dodd <winter@jurai.net>
    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.0/sys/dev/buslogic/bt_mca.c 104710 2002-10-09 08:54:32Z peter $
   27  */
   28 
   29 /*
   30  * Written using the bt_isa/bt_pci code as a reference.
   31  *
   32  * Thanks to Andy Farkas <andyf@speednet.com.au> for
   33  * testing and feedback.
   34  */
   35 
   36 #include <sys/types.h>
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 
   41 #include <machine/cpufunc.h>
   42 #include <machine/md_var.h>
   43 
   44 #include <sys/module.h>
   45 #include <sys/bus.h>
   46 
   47 #include <machine/bus.h>
   48 #include <machine/resource.h>
   49 #include <sys/rman.h>
   50 
   51 #include <dev/mca/mca_busreg.h>
   52 #include <dev/mca/mca_busvar.h>
   53 
   54 #include <i386/isa/isa_dma.h>
   55 
   56 #include <dev/buslogic/btreg.h>
   57 
   58 #include <cam/scsi/scsi_all.h>
   59 
   60 static struct mca_ident bt_mca_devs[] = {
   61         { 0x0708, "BusLogic 32 Bit Bus Master MCA-to-SCSI Host Adapter" },
   62         { 0x0708, "BusTek BT-640A Micro Channel to SCSI Host Adapter" },
   63         { 0x0708, "Storage Dimensions SDC3211B 32-bit SCSI Host Adapter" },
   64         { 0x0709, "Storage Dimensions SDC3211F 32-bit FAST SCSI Host Adapter" },
   65         { 0, NULL },
   66 };
   67 
   68 #define BT_MCA_IOPORT_POS1              MCA_ADP_POS(MCA_POS0)
   69 #define BT_MCA_IOPORT_POS2              MCA_ADP_POS(MCA_POS1)
   70 #define BT_MCA_IOPORT_MASK1             0x10
   71 #define BT_MCA_IOPORT_MASK2             0x03
   72 #define BT_MCA_IOPORT_SIZE              0x03
   73 #define BT_MCA_IOPORT(pos)              (0x30 + \
   74                                         (((u_int32_t)pos &\
   75                                                 BT_MCA_IOPORT_MASK2) << 8) + \
   76                                         (((u_int32_t)pos &\
   77                                                 BT_MCA_IOPORT_MASK1) >> 2))
   78 
   79 #define BT_MCA_IRQ_POS                  MCA_ADP_POS(MCA_POS0)
   80 #define BT_MCA_IRQ_MASK                 0x0e
   81 #define BT_MCA_IRQ(pos)                 (((pos & BT_MCA_IRQ_MASK) >> 1) + 8)
   82 
   83 #define BT_MCA_DRQ_POS                  MCA_ADP_POS(MCA_POS3)
   84 #define BT_MCA_DRQ_MASK                 0x0f
   85 #define BT_MCA_DRQ(pos)                 (pos & BT_MCA_DRQ_MASK)
   86 
   87 #define BT_MCA_SCSIID_POS               MCA_ADP_POS(MCA_POS2)
   88 #define BT_MCA_SCSIID_MASK              0xe0
   89 #define BT_MCA_SCSIID(pos)              ((pos & BT_MCA_SCSIID_MASK) >> 5)
   90 
   91 static  bus_dma_filter_t        btvlbouncefilter;
   92 static  bus_dmamap_callback_t   btmapsensebuffers;
   93 
   94 static void
   95 bt_mca_release_resources (device_t dev)
   96 {
   97         struct  bt_softc *      bt = device_get_softc(dev);
   98 
   99         if (bt->port)
  100                 bus_release_resource(dev, SYS_RES_IOPORT, 0, bt->port);
  101         if (bt->irq)
  102                 bus_release_resource(dev, SYS_RES_IRQ, 0, bt->irq);
  103         if (bt->drq)
  104                 bus_release_resource(dev, SYS_RES_DRQ, 0, bt->drq);
  105 
  106         bt_free_softc(dev);
  107 }
  108 
  109 #define BT_MCA_PROBE    0
  110 #define BT_MCA_ATTACH   1
  111 
  112 static int
  113 bt_mca_alloc_resources(device_t dev, int mode)
  114 {
  115         struct resource *       io = NULL;
  116         struct resource *       irq = NULL;
  117         struct resource *       drq = NULL;
  118         int                     rid;
  119 
  120         rid = 0;
  121         io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
  122                                 0, ~0, 1, RF_ACTIVE);
  123         if (io == NULL) {
  124                 printf("bt_mca_alloc_resources() failed to allocate IOPORT\n");
  125                 return (ENOMEM);
  126         }
  127 
  128         if (mode == BT_MCA_ATTACH) {
  129 
  130                 rid = 0;
  131                 irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
  132                                          0, ~0, 1, RF_ACTIVE);
  133                 if (irq == NULL) {
  134                         printf("bt_mca_alloc_resources() failed to allocate IRQ\n");
  135                         goto bad;
  136                 }
  137         
  138                 rid = 0;
  139                 drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid,
  140                                                  0, ~0, 1, RF_ACTIVE);
  141                 if (drq == NULL) {
  142                         printf("bt_mca_alloc_resources() failed to allocate DRQ\n");
  143                         goto bad;
  144                 }
  145         }
  146         
  147         bt_init_softc(dev, io, irq, drq);
  148 
  149         return (0);
  150 bad:
  151         bt_mca_release_resources(dev);
  152         return (ENOMEM);
  153 }
  154 
  155 static int
  156 bt_mca_probe (device_t dev)
  157 {
  158         const char *            desc;
  159         mca_id_t                id = mca_get_id(dev);
  160         struct bt_probe_info    info;
  161         u_int32_t               iobase = 0;
  162         u_int32_t               iosize = 0;
  163         u_int8_t                drq = 0;
  164         u_int8_t                irq = 0;
  165         u_int8_t                pos;
  166         int                     result;
  167 
  168         desc = mca_match_id(id, bt_mca_devs);
  169         if (!desc)
  170                 return (ENXIO);
  171         device_set_desc(dev, desc);
  172 
  173         pos = (mca_pos_read(dev, BT_MCA_IOPORT_POS1) & BT_MCA_IOPORT_MASK1) |
  174               (mca_pos_read(dev, BT_MCA_IOPORT_POS2) & BT_MCA_IOPORT_MASK2);
  175         iobase = BT_MCA_IOPORT(pos);
  176         iosize = BT_MCA_IOPORT_SIZE;
  177 
  178         pos = mca_pos_read(dev, BT_MCA_DRQ_POS);
  179         drq = BT_MCA_DRQ(pos);
  180 
  181         pos = mca_pos_read(dev, BT_MCA_IRQ_POS);
  182         irq = BT_MCA_IRQ(pos);
  183 
  184         bt_mark_probed_iop(iobase);
  185 
  186         mca_add_iospace(dev, iobase, iosize);
  187 
  188         /* And allocate them */
  189         bt_mca_alloc_resources(dev, BT_MCA_PROBE);
  190                         
  191         if (bt_port_probe(dev, &info) != 0) {
  192                 printf("bt_mca_probe: Probe failed for "
  193                        "card at slot %d\n", mca_get_slot(dev) + 1);
  194                 result = ENXIO;
  195         } else {               
  196                 mca_add_drq(dev, drq);
  197                 mca_add_irq(dev, irq);
  198                 result = 0;    
  199         }              
  200         bt_mca_release_resources(dev);
  201 
  202         return (result);
  203 }
  204 
  205 static int
  206 bt_mca_attach (device_t dev)
  207 {
  208         struct bt_softc *       bt = device_get_softc(dev);
  209         int                     error = 0;
  210 
  211         /* Allocate resources */      
  212         if ((error = bt_mca_alloc_resources(dev, BT_MCA_ATTACH))) {
  213                 device_printf(dev, "Unable to allocate resources in bt_mca_attach()\n");
  214                 return (error);
  215         }
  216 
  217         isa_dmacascade(rman_get_start(bt->drq));
  218 
  219         /* Allocate a dmatag for our CCB DMA maps */
  220         if (bus_dma_tag_create(/*parent*/NULL, /*alignemnt*/1, /*boundary*/0,
  221                                /*lowaddr*/BUS_SPACE_MAXADDR_24BIT,
  222                                /*highaddr*/BUS_SPACE_MAXADDR,
  223                                /*filter*/btvlbouncefilter,
  224                                /*filterarg*/bt,
  225                                /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
  226                                /*nsegments*/~0,
  227                                /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  228                                /*flags*/0, &bt->parent_dmat) != 0) {
  229                 bt_mca_release_resources(dev);
  230                 return (ENOMEM);
  231         }
  232 
  233         if (bt_init(dev)) {
  234                 bt_mca_release_resources(dev);
  235                 return (ENOMEM);
  236         }
  237 
  238         /* DMA tag for our sense buffers */
  239         if (bus_dma_tag_create(bt->parent_dmat, /*alignment*/1, 
  240                                /*boundary*/0,
  241                                /*lowaddr*/BUS_SPACE_MAXADDR,    
  242                                /*highaddr*/BUS_SPACE_MAXADDR,   
  243                                /*filter*/NULL, /*filterarg*/NULL,
  244                                bt->max_ccbs * sizeof(struct scsi_sense_data),
  245                                /*nsegments*/1,
  246                                /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT,
  247                                /*flags*/0, &bt->sense_dmat) != 0) {
  248                 bt_mca_release_resources(dev);
  249                 return (ENOMEM);
  250         }
  251 
  252         bt->init_level++;     
  253 
  254         /* Allocation of sense buffers */
  255         if (bus_dmamem_alloc(bt->sense_dmat,
  256                              (void **)&bt->sense_buffers,       
  257                              BUS_DMA_NOWAIT, &bt->sense_dmamap) != 0) {
  258                 bt_mca_release_resources(dev);
  259                 return (ENOMEM);
  260         }
  261 
  262         bt->init_level++;     
  263 
  264         /* And permanently map them */
  265         bus_dmamap_load(bt->sense_dmat, bt->sense_dmamap,       
  266                         bt->sense_buffers,
  267                         bt->max_ccbs * sizeof(*bt->sense_buffers),
  268                         btmapsensebuffers, bt, /*flags*/0);     
  269 
  270         bt->init_level++;     
  271 
  272         if ((error = bt_attach(dev))) {
  273                 bt_mca_release_resources(dev);
  274                 return (error);
  275         }
  276 
  277         return (0);
  278 }
  279 
  280 /*
  281  * This code should be shared with the ISA
  282  * stubs as its exactly the same.
  283  */
  284 
  285 #define BIOS_MAP_SIZE (16 * 1024)
  286 
  287 static int
  288 btvlbouncefilter(void *arg, bus_addr_t addr)
  289 {
  290         struct bt_softc *bt;
  291 
  292         bt = (struct bt_softc *)arg;
  293 
  294         addr &= BUS_SPACE_MAXADDR_24BIT;
  295 
  296         if (addr == 0
  297          || (addr >= bt->bios_addr
  298           && addr < (bt->bios_addr + BIOS_MAP_SIZE)))
  299                 return (1);
  300         return (0);
  301 }
  302 
  303 static void
  304 btmapsensebuffers(void *arg, bus_dma_segment_t *segs, int nseg, int error)
  305 {
  306         struct bt_softc* bt;
  307 
  308         bt = (struct bt_softc*)arg;
  309         bt->sense_buffers_physbase = segs->ds_addr;
  310 }
  311 
  312 static device_method_t bt_mca_methods[] = {
  313         /* Device interface */
  314         DEVMETHOD(device_probe,         bt_mca_probe),
  315         DEVMETHOD(device_attach,        bt_mca_attach),
  316 
  317         { 0, 0 }
  318 };
  319 
  320 static driver_t bt_mca_driver = {
  321         "bt",
  322         bt_mca_methods,
  323         sizeof(struct bt_softc),
  324 };
  325 
  326 static devclass_t bt_devclass;
  327 
  328 DRIVER_MODULE(bt, mca, bt_mca_driver, bt_devclass, 0, 0);

Cache object: b115132d3f4e28faaa86d95ee4703229


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