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/pci/adv_pci.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  * Device probe and attach routines for the following
    3  * Advanced Systems Inc. SCSI controllers:
    4  *
    5  *   Connectivity Products:
    6  *      ABP920   - Bus-Master PCI (16 CDB)
    7  *      ABP930   - Bus-Master PCI (16 CDB) *
    8  *      ABP930U  - Bus-Master PCI Ultra (16 CDB)
    9  *      ABP930UA - Bus-Master PCI Ultra (16 CDB)
   10  *      ABP960   - Bus-Master PCI MAC/PC (16 CDB) **
   11  *      ABP960U  - Bus-Master PCI MAC/PC Ultra (16 CDB)
   12  *
   13  *   Single Channel Products:
   14  *      ABP940 - Bus-Master PCI (240 CDB)
   15  *      ABP940U - Bus-Master PCI Ultra (240 CDB)
   16  *      ABP970 - Bus-Master PCI MAC/PC (240 CDB)
   17  *      ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB)
   18  *
   19  *   Dual Channel Products:  
   20  *      ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel)
   21  *
   22  *   Footnotes:
   23  *       * This board has been sold by SIIG as the Fast SCSI Pro PCI.
   24  *      ** This board has been sold by Iomega as a Jaz Jet PCI adapter. 
   25  *
   26  * Copyright (c) 1997 Justin Gibbs.
   27  * All rights reserved.
   28  *
   29  * Redistribution and use in source and binary forms, with or without
   30  * modification, are permitted provided that the following conditions
   31  * are met:
   32  * 1. Redistributions of source code must retain the above copyright
   33  *    notice, this list of conditions, and the following disclaimer,
   34  *    without modification, immediately at the beginning of the file.
   35  * 2. The name of the author may not be used to endorse or promote products
   36  *    derived from this software without specific prior written permission.
   37  *
   38  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   41  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   42  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   44  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   46  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   47  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   48  * SUCH DAMAGE.
   49  *
   50  * $FreeBSD$
   51  */
   52 
   53 #include <pci.h>
   54 #if NPCI > 0
   55 #include <sys/param.h>
   56 #include <sys/systm.h>
   57 #include <sys/kernel.h>
   58 
   59 #include <machine/bus_pio.h>
   60 #include <machine/bus.h>
   61 
   62 #include <pci/pcireg.h>
   63 #include <pci/pcivar.h>
   64 
   65 #include <dev/advansys/advansys.h>
   66 
   67 #define PCI_BASEADR0    PCI_MAP_REG_START       /* I/O Address */
   68 #define PCI_BASEADR1    PCI_MAP_REG_START + 4   /* Mem I/O Address */
   69 
   70 #define PCI_DEVICE_ID_ADVANSYS_1200A    0x110010CD
   71 #define PCI_DEVICE_ID_ADVANSYS_1200B    0x120010CD
   72 #define PCI_DEVICE_ID_ADVANSYS_ULTRA    0x130010CD
   73 #define PCI_DEVICE_REV_ADVANSYS_3150    0x02
   74 #define PCI_DEVICE_REV_ADVANSYS_3050    0x03
   75 
   76 #define ADV_PCI_MAX_DMA_ADDR    (0xFFFFFFFFL)
   77 #define ADV_PCI_MAX_DMA_COUNT   (0xFFFFFFFFL)
   78 
   79 static const char* advpciprobe(pcici_t tag, pcidi_t type);
   80 static void advpciattach(pcici_t config_id, int unit);
   81 
   82 /* 
   83  * The overrun buffer shared amongst all PCI adapters.
   84  */
   85 static  u_int8_t*       overrun_buf;
   86 static  bus_dma_tag_t   overrun_dmat;
   87 static  bus_dmamap_t    overrun_dmamap;
   88 static  bus_addr_t      overrun_physbase;
   89 
   90 static struct  pci_device adv_pci_driver = {
   91         "adv",
   92         advpciprobe,
   93         advpciattach,
   94         &adv_unit,
   95         NULL
   96 };
   97 
   98 DATA_SET (pcidevice_set, adv_pci_driver);
   99 
  100 static const char*
  101 advpciprobe(pcici_t tag, pcidi_t type)
  102 {
  103         int rev = pci_conf_read(tag, PCI_CLASS_REG) & 0xff;
  104         switch (type) {
  105         case PCI_DEVICE_ID_ADVANSYS_1200A:
  106                 return ("AdvanSys ASC1200A SCSI controller");
  107         case PCI_DEVICE_ID_ADVANSYS_1200B:
  108                 return ("AdvanSys ASC1200B SCSI controller");
  109         case PCI_DEVICE_ID_ADVANSYS_ULTRA:
  110                 if (rev == PCI_DEVICE_REV_ADVANSYS_3150)
  111                         return ("AdvanSys ASC3150 Ultra SCSI controller");
  112                 else
  113                         return ("AdvanSys ASC3050 Ultra SCSI controller");
  114                 break;
  115         default:
  116                 break;
  117         }
  118         return (NULL);
  119 }
  120 
  121 static void
  122 advpciattach(pcici_t config_id, int unit)
  123 {
  124         u_int16_t       io_port;
  125         struct          adv_softc *adv;
  126         u_int32_t       id;
  127         u_int32_t       command;
  128         int             error;
  129  
  130         /*
  131          * Determine the chip version.
  132          */
  133         id = pci_cfgread(config_id, PCI_ID_REG, /*bytes*/4);
  134         command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1);
  135 
  136         /*
  137          * These cards do not allow memory mapped accesses, so we must
  138          * ensure that I/O accesses are available or we won't be able
  139          * to talk to them.
  140          */
  141         if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN))
  142          != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) {
  143                 command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN;
  144                 pci_cfgwrite(config_id, PCIR_COMMAND, command, /*bytes*/1);
  145         }
  146 
  147         /*
  148          * Early chips can't handle non-zero latency timer settings.
  149          */
  150         if (id == PCI_DEVICE_ID_ADVANSYS_1200A
  151          || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
  152                 pci_cfgwrite(config_id, PCIR_LATTIMER, /*value*/0, /*bytes*/1);
  153         }
  154 
  155 
  156         if (pci_map_port(config_id, PCI_BASEADR0, &io_port) == 0)
  157                 return;
  158 
  159         if (adv_find_signature(I386_BUS_SPACE_IO, io_port) == 0)
  160                 return;
  161 
  162         adv = adv_alloc(unit, I386_BUS_SPACE_IO, io_port);
  163         if (adv == NULL)
  164                 return;
  165 
  166         /* Allocate a dmatag for our transfer DMA maps */
  167         /* XXX Should be a child of the PCI bus dma tag */
  168         error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1,
  169                                    /*boundary*/0,
  170                                    /*lowaddr*/ADV_PCI_MAX_DMA_ADDR,
  171                                    /*highaddr*/BUS_SPACE_MAXADDR,
  172                                    /*filter*/NULL, /*filterarg*/NULL,
  173                                    /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
  174                                    /*nsegments*/BUS_SPACE_UNRESTRICTED,
  175                                    /*maxsegsz*/ADV_PCI_MAX_DMA_COUNT,
  176                                    /*flags*/0,
  177                                    &adv->parent_dmat);
  178  
  179         if (error != 0) {
  180                 printf("%s: Could not allocate DMA tag - error %d\n",
  181                        adv_name(adv), error);
  182                 adv_free(adv);
  183                 return;
  184         }
  185 
  186         adv->init_level++;
  187 
  188         if (overrun_buf == NULL) {
  189                 /* Need to allocate our overrun buffer */
  190                 if (bus_dma_tag_create(adv->parent_dmat,
  191                                        /*alignment*/8, /*boundary*/0,
  192                                        ADV_PCI_MAX_DMA_ADDR, BUS_SPACE_MAXADDR,
  193                                        /*filter*/NULL, /*filterarg*/NULL,
  194                                        ADV_OVERRUN_BSIZE, /*nsegments*/1,
  195                                        BUS_SPACE_MAXSIZE_32BIT, /*flags*/0,
  196                                        &overrun_dmat) != 0) {
  197                         bus_dma_tag_destroy(adv->parent_dmat);
  198                         adv_free(adv);
  199                         return;
  200                 }
  201                 if (bus_dmamem_alloc(overrun_dmat,
  202                                      (void **)&overrun_buf,
  203                                      BUS_DMA_NOWAIT,
  204                                      &overrun_dmamap) != 0) {
  205                         bus_dma_tag_destroy(overrun_dmat);
  206                         bus_dma_tag_destroy(adv->parent_dmat);
  207                         adv_free(adv);
  208                         return;
  209                 }
  210                 /* And permanently map it in */  
  211                 bus_dmamap_load(overrun_dmat, overrun_dmamap,
  212                                 overrun_buf, ADV_OVERRUN_BSIZE,
  213                                 adv_map, &overrun_physbase,
  214                                 /*flags*/0);
  215         }
  216 
  217         adv->overrun_physbase = overrun_physbase;
  218                         
  219         /*
  220          * Stop the chip.
  221          */
  222         ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT);
  223         ADV_OUTW(adv, ADV_CHIP_STATUS, 0);
  224 
  225         adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION);
  226         adv->type = ADV_PCI;
  227         
  228         /*
  229          * Setup active negation and signal filtering.
  230          */
  231         {
  232                 u_int8_t extra_cfg;
  233 
  234                 if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150)
  235                         adv->type |= ADV_ULTRA;
  236                 if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3150)
  237                         extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
  238                 else if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050)
  239                         extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER;
  240                 else
  241                         extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE;
  242                 ADV_OUTB(adv, ADV_REG_IFC, extra_cfg);
  243         }
  244 
  245         if (adv_init(adv) != 0) {
  246                 adv_free(adv);
  247                 return;
  248         }
  249 
  250         adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT;
  251         adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR;
  252 
  253 #if CC_DISABLE_PCI_PARITY_INT
  254         {
  255                 u_int16_t config_msw;
  256 
  257                 config_msw = ADV_INW(adv, ADV_CONFIG_MSW);
  258                 config_msw &= 0xFFC0;
  259                 ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw); 
  260         }
  261 #endif
  262  
  263         if (id == PCI_DEVICE_ID_ADVANSYS_1200A
  264          || id == PCI_DEVICE_ID_ADVANSYS_1200B) {
  265                 adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB;
  266                 adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN;
  267                 adv->fix_asyn_xfer = ~0;
  268         }
  269 
  270         if ((pci_map_int(config_id, adv_intr, (void *)adv, &cam_imask)) == 0) {
  271                 adv_free(adv);
  272                 return;
  273         }
  274         
  275         adv_attach(adv);
  276 }
  277 
  278 #endif /* NPCI > 0 */

Cache object: 07f9cfd739ef6e95c74f17dd83662866


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