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/isp_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 /* $FreeBSD: src/sys/pci/isp_pci.c,v 1.24.2.6 2000/03/04 06:04:42 mjacob Exp $ */
    2 /*
    3  * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
    4  * FreeBSD 2.X Version.
    5  *
    6  *---------------------------------------
    7  * Copyright (c) 1997, 1998, 1999, 2000 by Matthew Jacob
    8  * NASA/Ames Research Center
    9  * All rights reserved.
   10  *---------------------------------------
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice immediately at the beginning of the file, without modification,
   17  *    this list of conditions, and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. The name of the author may not be used to endorse or promote products
   22  *    derived from this software without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   28  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  */
   36 #include <dev/isp/isp_freebsd.h>
   37 #include <dev/isp/asm_pci.h>
   38 #include <sys/malloc.h>
   39 #include <vm/vm.h>
   40 #include <vm/pmap.h>
   41 #include <vm/vm_extern.h>
   42 
   43 
   44 #include <pci/pcireg.h>
   45 #include <pci/pcivar.h>
   46 
   47 static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int));
   48 static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t));
   49 #if !defined(ISP_DISABLE_1080_SUPPORT) && !defined(ISP_DISABLE_12160_SUPPORT)
   50 static u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int));
   51 static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t));
   52 #endif
   53 static int isp_pci_mbxdma __P((struct ispsoftc *));
   54 static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *,
   55         ispreq_t *, u_int16_t *, u_int16_t));
   56 typedef u_int16_t pci_port_t;
   57 
   58 static void isp_pci_reset1 __P((struct ispsoftc *));
   59 static void isp_pci_dumpregs __P((struct ispsoftc *));
   60 
   61 #ifndef ISP_CODE_ORG
   62 #define ISP_CODE_ORG            0x1000
   63 #endif
   64 #ifndef ISP_1040_RISC_CODE
   65 #define ISP_1040_RISC_CODE      NULL
   66 #endif
   67 #ifndef ISP_1080_RISC_CODE
   68 #define ISP_1080_RISC_CODE      NULL
   69 #endif
   70 #ifndef ISP_12160_RISC_CODE
   71 #define ISP_12160_RISC_CODE     NULL
   72 #endif
   73 #ifndef ISP_2100_RISC_CODE
   74 #define ISP_2100_RISC_CODE      NULL
   75 #endif
   76 #ifndef ISP_2200_RISC_CODE
   77 #define ISP_2200_RISC_CODE      NULL
   78 #endif
   79 
   80 #ifndef ISP_DISABLE_1020_SUPPORT
   81 static struct ispmdvec mdvec = {
   82         isp_pci_rd_reg,
   83         isp_pci_wr_reg,
   84         isp_pci_mbxdma,
   85         isp_pci_dmasetup,
   86         NULL,
   87         NULL,
   88         isp_pci_reset1,
   89         isp_pci_dumpregs,
   90         ISP_1040_RISC_CODE,
   91         0,
   92         ISP_CODE_ORG,
   93         0,
   94         BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,
   95         0
   96 };
   97 #endif
   98 
   99 #ifndef ISP_DISABLE_1080_SUPPORT
  100 static struct ispmdvec mdvec_1080 = {
  101         isp_pci_rd_reg_1080,
  102         isp_pci_wr_reg_1080,
  103         isp_pci_mbxdma,
  104         isp_pci_dmasetup,
  105         NULL,
  106         NULL,
  107         isp_pci_reset1,
  108         isp_pci_dumpregs,
  109         ISP_1080_RISC_CODE,
  110         0,
  111         ISP_CODE_ORG,
  112         0,
  113         BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,
  114         0
  115 };
  116 #endif
  117 
  118 #ifndef ISP_DISABLE_12160_SUPPORT
  119 static struct ispmdvec mdvec_12160 = {
  120         isp_pci_rd_reg_1080,
  121         isp_pci_wr_reg_1080,
  122         isp_pci_mbxdma,
  123         isp_pci_dmasetup,
  124         NULL,
  125         NULL,
  126         isp_pci_reset1,
  127         isp_pci_dumpregs,
  128         ISP_12160_RISC_CODE,
  129         0,
  130         ISP_CODE_ORG,
  131         0,
  132         BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64,
  133         0
  134 };
  135 #endif
  136 
  137 #ifndef ISP_DISABLE_2100_SUPPORT
  138 static struct ispmdvec mdvec_2100 = {
  139         isp_pci_rd_reg,
  140         isp_pci_wr_reg,
  141         isp_pci_mbxdma,
  142         isp_pci_dmasetup,
  143         NULL,
  144         NULL,
  145         isp_pci_reset1,
  146         isp_pci_dumpregs,
  147         ISP_2100_RISC_CODE,
  148         0,
  149         ISP_CODE_ORG,
  150         0,
  151         0,                      /* Irrelevant to the 2100 */
  152         0
  153 };
  154 #endif
  155 
  156 #ifndef ISP_DISABLE_2200_SUPPORT
  157 static struct ispmdvec mdvec_2200 = {
  158         isp_pci_rd_reg,
  159         isp_pci_wr_reg,
  160         isp_pci_mbxdma,
  161         isp_pci_dmasetup,
  162         NULL,
  163         NULL,
  164         isp_pci_reset1,
  165         isp_pci_dumpregs,
  166         ISP_2200_RISC_CODE,
  167         0,
  168         ISP_CODE_ORG,
  169         0,
  170         0,
  171         0
  172 };
  173 #endif
  174 
  175 #ifndef SCSI_ISP_PREFER_MEM_MAP
  176 #ifdef  __alpha__
  177 #define SCSI_ISP_PREFER_MEM_MAP 0
  178 #else
  179 #define SCSI_ISP_PREFER_MEM_MAP 1
  180 #endif
  181 #endif
  182 
  183 #ifndef PCIM_CMD_INVEN
  184 #define PCIM_CMD_INVEN                  0x10
  185 #endif
  186 #ifndef PCIM_CMD_BUSMASTEREN
  187 #define PCIM_CMD_BUSMASTEREN            0x0004
  188 #endif
  189 #ifndef PCIM_CMD_PERRESPEN
  190 #define PCIM_CMD_PERRESPEN              0x0040
  191 #endif
  192 #ifndef PCIM_CMD_SEREN
  193 #define PCIM_CMD_SEREN                  0x0100
  194 #endif
  195 
  196 #ifndef PCIR_COMMAND
  197 #define PCIR_COMMAND                    0x04
  198 #endif
  199 
  200 #ifndef PCIR_CACHELNSZ
  201 #define PCIR_CACHELNSZ                  0x0c
  202 #endif
  203 
  204 #ifndef PCIR_LATTIMER
  205 #define PCIR_LATTIMER                   0x0d
  206 #endif
  207 
  208 #ifndef PCIR_ROMADDR
  209 #define PCIR_ROMADDR                    0x30
  210 #endif
  211 
  212 #ifndef PCI_VENDOR_QLOGIC
  213 #define PCI_VENDOR_QLOGIC       0x1077
  214 #endif
  215 
  216 #ifndef PCI_PRODUCT_QLOGIC_ISP1020
  217 #define PCI_PRODUCT_QLOGIC_ISP1020      0x1020
  218 #endif
  219 
  220 #ifndef PCI_PRODUCT_QLOGIC_ISP1080
  221 #define PCI_PRODUCT_QLOGIC_ISP1080      0x1080
  222 #endif
  223 
  224 #ifndef PCI_PRODUCT_QLOGIC_ISP1240
  225 #define PCI_PRODUCT_QLOGIC_ISP1240      0x1240
  226 #endif
  227 
  228 #ifndef PCI_PRODUCT_QLOGIC_ISP1280
  229 #define PCI_PRODUCT_QLOGIC_ISP1280      0x1280
  230 #endif
  231 
  232 #ifndef PCI_PRODUCT_QLOGIC_ISP12160
  233 #define PCI_PRODUCT_QLOGIC_ISP12160     0x1216
  234 #endif
  235 
  236 #ifndef PCI_PRODUCT_QLOGIC_ISP2100
  237 #define PCI_PRODUCT_QLOGIC_ISP2100      0x2100
  238 #endif
  239 
  240 #ifndef PCI_PRODUCT_QLOGIC_ISP2200
  241 #define PCI_PRODUCT_QLOGIC_ISP2200      0x2200
  242 #endif
  243 
  244 #define PCI_QLOGIC_ISP  ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
  245 
  246 #define PCI_QLOGIC_ISP1080      \
  247         ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
  248 
  249 #define PCI_QLOGIC_ISP1240      \
  250         ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
  251 
  252 #define PCI_QLOGIC_ISP12160     \
  253         ((PCI_PRODUCT_QLOGIC_ISP12160 << 16) | PCI_VENDOR_QLOGIC)
  254 
  255 #define PCI_QLOGIC_ISP1280      \
  256         ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
  257 
  258 #define PCI_QLOGIC_ISP2100      \
  259         ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
  260 
  261 #define PCI_QLOGIC_ISP2200      \
  262         ((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC)
  263 
  264 #define IO_MAP_REG      0x10
  265 #define MEM_MAP_REG     0x14
  266 
  267 #define PCI_DFLT_LTNCY  0x40
  268 #define PCI_DFLT_LNSZ   0x10
  269 
  270 static char *isp_pci_probe __P((pcici_t tag, pcidi_t type));
  271 static void isp_pci_attach __P((pcici_t config_d, int unit));
  272 
  273 /* This distinguishing define is not right, but it does work */
  274  
  275 #define IO_SPACE_MAPPING        0
  276 #define MEM_SPACE_MAPPING       1
  277 typedef int bus_space_tag_t;
  278 typedef u_long bus_space_handle_t;
  279 typedef unsigned int            __uintptr_t;
  280 typedef __uintptr_t     uintptr_t;
  281 #ifdef __alpha__
  282 #define bus_space_read_2(st, sh, offset)        \
  283         alpha_mb(),
  284         (st == IO_SPACE_MAPPING)? \
  285                 inw((pci_port_t)sh + offset) : readw((pci_port_t)sh + offset)
  286 #define bus_space_write_2(st, sh, offset, val)  \
  287         ((st == IO_SPACE_MAPPING)? outw((pci_port_t)sh + offset, val) : \
  288                 writew((pci_port_t)sh + offset, val)), alpha_mb()
  289 #else
  290 #define bus_space_read_2(st, sh, offset)        \
  291         (st == IO_SPACE_MAPPING)? \
  292                 inw((pci_port_t)sh + offset) : *((u_int16_t *)(uintptr_t)sh)
  293 #define bus_space_write_2(st, sh, offset, val)  \
  294         if (st == IO_SPACE_MAPPING) outw((pci_port_t)sh + offset, val); else \
  295                 *((u_int16_t *)(uintptr_t)sh) = val
  296 #endif
  297 
  298 struct isp_pcisoftc {
  299         struct ispsoftc                 pci_isp;
  300         pcici_t                         pci_id;
  301         bus_space_tag_t                 pci_st;
  302         bus_space_handle_t              pci_sh;
  303         int16_t                         pci_poff[_NREG_BLKS];
  304 };
  305 
  306 static u_long ispunit;
  307 
  308 static struct pci_device isp_pci_driver = {
  309         "isp",
  310         isp_pci_probe,
  311         isp_pci_attach,
  312         &ispunit,
  313         NULL
  314 };
  315 DATA_SET (pcidevice_set, isp_pci_driver);
  316 
  317 
  318 static char *
  319 isp_pci_probe(pcici_t tag, pcidi_t type)
  320 {
  321         static int oneshot = 1;
  322         char *x;
  323 
  324         switch (type) {
  325 #ifndef ISP_DISABLE_1020_SUPPORT
  326         case PCI_QLOGIC_ISP:
  327                 x = "Qlogic ISP 1020/1040 PCI SCSI Adapter";
  328                 break;
  329 #endif
  330 #ifndef ISP_DISABLE_1080_SUPPORT
  331         case PCI_QLOGIC_ISP1080:
  332                 x = "Qlogic ISP 1080 PCI SCSI Adapter";
  333                 break;
  334         case PCI_QLOGIC_ISP1240:
  335                 x = "Qlogic ISP 1240 PCI SCSI Adapter";
  336                 break;
  337         case PCI_QLOGIC_ISP1280:
  338                 x = "Qlogic ISP 1280 PCI SCSI Adapter";
  339                 break;
  340 #endif
  341 #ifndef ISP_DISABLE_12160_SUPPORT
  342         case PCI_QLOGIC_ISP12160:
  343                 x = "Qlogic ISP 12160 PCI SCSI Adapter";
  344                 break;
  345 #endif
  346 #ifndef ISP_DISABLE_2100_SUPPORT
  347         case PCI_QLOGIC_ISP2100:
  348                 x = "Qlogic ISP 2100 PCI FC-AL Adapter";
  349                 break;
  350 #endif
  351 #ifndef ISP_DISABLE_2200_SUPPORT
  352         case PCI_QLOGIC_ISP2200:
  353                 x = "Qlogic ISP 2200 PCI FC-AL Adapter";
  354                 break;
  355 #endif
  356         default:
  357                 return (NULL);
  358         }
  359         if (oneshot) {
  360                 oneshot = 0;
  361                 printf("Qlogic ISP Driver, FreeBSD Version %d.%d, "
  362                     "Core Version %d.%d\n",
  363                     ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
  364                     ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
  365         }
  366         return (x);
  367 }
  368 
  369 
  370 #if     SCSI_ISP_PREFER_MEM_MAP == 1
  371 #define prefer_mem_map  1
  372 #else
  373 #define prefer_mem_map  0
  374 #endif
  375 
  376 static void
  377 isp_pci_attach(pcici_t cfid, int unit)
  378 {
  379         int mapped;
  380         pci_port_t io_port;
  381         u_int32_t data, rev, linesz, psize, basetype;
  382         struct isp_pcisoftc *pcs;
  383         struct ispsoftc *isp;
  384         vm_offset_t vaddr, paddr;
  385         struct ispmdvec *mdvp;
  386         long i;
  387         ISP_LOCKVAL_DECL;
  388 
  389 
  390         pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT);
  391         if (pcs == NULL) {
  392                 printf("isp%d: cannot allocate softc\n", unit);
  393                 return;
  394         }
  395         bzero(pcs, sizeof (struct isp_pcisoftc));
  396 
  397         /*
  398          * Figure out which we should try first - memory mapping or i/o mapping?
  399          */
  400 
  401         vaddr = paddr = NULL;
  402         mapped = 0;
  403         linesz = PCI_DFLT_LNSZ;
  404 
  405         /*
  406          * Note that pci_conf_read is a 32 bit word aligned function.
  407          */
  408         data = pci_conf_read(cfid, PCIR_COMMAND);
  409         if (prefer_mem_map) {
  410                 if (data & PCI_COMMAND_MEM_ENABLE) {
  411                         if (pci_map_mem(cfid, MEM_MAP_REG, &vaddr, &paddr)) {
  412                                 pcs->pci_st = MEM_SPACE_MAPPING;
  413                                 pcs->pci_sh = vaddr;
  414                                 mapped++;
  415                         }
  416                 }
  417                 if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) {
  418                         if (pci_map_port(cfid, PCI_MAP_REG_START, &io_port)) {
  419                                 pcs->pci_st = IO_SPACE_MAPPING;
  420                                 pcs->pci_sh = io_port;
  421                                 mapped++;
  422                         }
  423                 }
  424         } else {
  425                 if (data & PCI_COMMAND_IO_ENABLE) {
  426                         if (pci_map_port(cfid, PCI_MAP_REG_START, &io_port)) {
  427                                 pcs->pci_st = IO_SPACE_MAPPING;
  428                                 pcs->pci_sh = io_port;
  429                                 mapped++;
  430                         }
  431                 }
  432                 if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) {
  433                         if (pci_map_mem(cfid, MEM_MAP_REG, &vaddr, &paddr)) {
  434                                 pcs->pci_st = MEM_SPACE_MAPPING;
  435                                 pcs->pci_sh = vaddr;
  436                                 mapped++;
  437                         }
  438                 }
  439         }
  440         if (mapped == 0) {
  441                 printf("isp%d: unable to map any ports!\n", unit);
  442                 free(pcs, M_DEVBUF);
  443                 return;
  444         }
  445         if (bootverbose)
  446                 printf("isp%d: using %s space register mapping\n", unit,
  447                     pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory");
  448 
  449         data = pci_conf_read(cfid, PCI_ID_REG);
  450         rev = pci_conf_read(cfid, PCI_CLASS_REG) & 0xff;        /* revision */
  451         pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
  452         pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
  453         pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
  454         pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
  455         pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
  456         /*
  457          * GCC!
  458          */
  459         mdvp = &mdvec;
  460         basetype = ISP_HA_SCSI_UNKNOWN;
  461         psize = sizeof (sdparam);
  462 #ifndef ISP_DISABLE_1020_SUPPORT
  463         if (data == PCI_QLOGIC_ISP) {
  464                 mdvp = &mdvec;
  465                 basetype = ISP_HA_SCSI_UNKNOWN;
  466                 psize = sizeof (sdparam);
  467         }
  468 #endif
  469 #ifndef ISP_DISABLE_1080_SUPPORT
  470         if (data == PCI_QLOGIC_ISP1080) {
  471                 mdvp = &mdvec_1080;
  472                 basetype = ISP_HA_SCSI_1080;
  473                 psize = sizeof (sdparam);
  474                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  475                     ISP1080_DMA_REGS_OFF;
  476         }
  477         if (data == PCI_QLOGIC_ISP1240) {
  478                 mdvp = &mdvec_1080;
  479                 basetype = ISP_HA_SCSI_1240;
  480                 psize = 2 * sizeof (sdparam);
  481                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  482                     ISP1080_DMA_REGS_OFF;
  483         }
  484         if (data == PCI_QLOGIC_ISP1280) {
  485                 mdvp = &mdvec_1080;
  486                 basetype = ISP_HA_SCSI_1280;
  487                 psize = 2 * sizeof (sdparam);
  488                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  489                     ISP1080_DMA_REGS_OFF;
  490         }
  491 #endif
  492 #ifndef ISP_DISABLE_12160_SUPPORT
  493         if (data == PCI_QLOGIC_ISP12160) {
  494                 mdvp = &mdvec_1080;
  495                 basetype = ISP_HA_SCSI_12160;
  496                 psize = 2 * sizeof (sdparam);
  497                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  498                     ISP1080_DMA_REGS_OFF;
  499         }
  500 #endif
  501 #ifndef ISP_DISABLE_2100_SUPPORT
  502         if (data == PCI_QLOGIC_ISP2100) {
  503                 mdvp = &mdvec_2100;
  504                 basetype = ISP_HA_FC_2100;
  505                 psize = sizeof (fcparam);
  506                 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
  507                     PCI_MBOX_REGS2100_OFF;
  508                 if (rev < 3) {
  509                         /*
  510                          * XXX: Need to get the actual revision
  511                          * XXX: number of the 2100 FB. At any rate,
  512                          * XXX: lower cache line size for early revision
  513                          * XXX; boards.
  514                          */
  515                         linesz = 1;
  516                 }
  517         }
  518 #endif
  519 #ifndef ISP_DISABLE_2200_SUPPORT
  520         if (data == PCI_QLOGIC_ISP2200) {
  521                 mdvp = &mdvec_2200;
  522                 basetype = ISP_HA_FC_2200;
  523                 psize = sizeof (fcparam);
  524                 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
  525                     PCI_MBOX_REGS2100_OFF;
  526         }
  527 #endif
  528         isp = &pcs->pci_isp;
  529         isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT);
  530         if (isp->isp_param == NULL) {
  531                 printf("isp%d: cannot allocate parameter data\n", unit);
  532                 return;
  533         }
  534         bzero(isp->isp_param, psize);
  535         isp->isp_mdvec = mdvp;
  536         isp->isp_type = basetype;
  537         isp->isp_revision = rev;
  538         (void) sprintf(isp->isp_name, "isp%d", unit);
  539         isp->isp_osinfo.unit = unit;
  540         /*
  541          * poor man's attempt at pseudo randomness.
  542          */
  543         i = (long) isp;
  544         i >>= 5;
  545         i &= 0x7;
  546         /*
  547          * This isn't very random, but it's the best we can do for
  548          * the real edge case of cards that don't have WWNs.
  549          */
  550         isp->isp_osinfo.seed += ((int) cfid.tag);
  551         while (version[i])
  552                 isp->isp_osinfo.seed += (int) version[i++];
  553         isp->isp_osinfo.seed <<= 8;
  554         isp->isp_osinfo.seed += (unit + 1);
  555 
  556         ISP_LOCK(isp);
  557         data = pci_conf_read(cfid, PCIR_COMMAND);
  558         data |= PCIM_CMD_SEREN          |
  559                 PCIM_CMD_PERRESPEN      |
  560                 PCIM_CMD_BUSMASTEREN    |
  561                 PCIM_CMD_INVEN;
  562         pci_conf_write(cfid, PCIR_COMMAND, data);
  563         data = pci_conf_read(cfid, PCIR_CACHELNSZ);
  564         if ((data & ~0xffff) != ((PCI_DFLT_LTNCY << 8) | linesz)) {
  565                 data &= ~0xffff;
  566                 data |= (PCI_DFLT_LTNCY << 8) | linesz;
  567                 pci_conf_write(cfid, PCIR_CACHELNSZ, data);
  568                 CFGPRINTF("%s: set PCI line size to %d\n",
  569                     isp->isp_name, linesz);
  570                 CFGPRINTF("%s: set PCI latency to %d\n", isp->isp_name,
  571                     PCI_DFLT_LTNCY);
  572         }
  573 
  574         /*
  575          * Make sure we've disabled the ROM.
  576          */
  577         data = pci_conf_read(cfid, PCIR_ROMADDR);
  578         data &= ~1;
  579         pci_conf_write(cfid, PCIR_ROMADDR, data);
  580         ISP_UNLOCK(isp);
  581         if (pci_map_int(cfid, (void (*)(void *))isp_intr,
  582             (void *)isp, &IMASK) == 0) {
  583                 printf("%s: could not map interrupt\n", isp->isp_name);
  584                 free(pcs, M_DEVBUF);
  585                 return;
  586         }
  587 
  588         pcs->pci_id = cfid;
  589 #ifdef  SCSI_ISP_NO_FWLOAD_MASK
  590         if (SCSI_ISP_NO_FWLOAD_MASK && (SCSI_ISP_NO_FWLOAD_MASK & (1 << unit)))
  591                 isp->isp_confopts |= ISP_CFG_NORELOAD;
  592 #endif
  593 #ifdef  SCSI_ISP_NO_NVRAM_MASK
  594         if (SCSI_ISP_NO_NVRAM_MASK && (SCSI_ISP_NO_NVRAM_MASK & (1 << unit))) {
  595                 printf("%s: ignoring NVRAM\n", isp->isp_name);
  596                 isp->isp_confopts |= ISP_CFG_NONVRAM;
  597         }
  598 #endif
  599 #ifdef  SCSI_ISP_FCDUPLEX
  600         if (IS_FC(isp)) {
  601                 if (SCSI_ISP_FCDUPLEX && (SCSI_ISP_FCDUPLEX & (1 << unit))) {
  602                         isp->isp_confopts |= ISP_CFG_FULL_DUPLEX;
  603                 }
  604         }
  605 #endif
  606         ISP_LOCK(isp);
  607         isp_reset(isp);
  608         if (isp->isp_state != ISP_RESETSTATE) {
  609                 (void) pci_unmap_int(cfid);
  610                 ISP_UNLOCK(isp);
  611                 free(pcs, M_DEVBUF);
  612                 return;
  613         }
  614         isp_init(isp);
  615         if (isp->isp_state != ISP_INITSTATE) {
  616                 /* If we're a Fibre Channel Card, we allow deferred attach */
  617                 if (IS_SCSI(isp)) {
  618                         isp_uninit(isp);
  619                         (void) pci_unmap_int(cfid); /* Does nothing */
  620                         ISP_UNLOCK(isp);
  621                         free(pcs, M_DEVBUF);
  622                         return;
  623                 }
  624         }
  625         isp_attach(isp);
  626         if (isp->isp_state != ISP_RUNSTATE) {
  627                 /* If we're a Fibre Channel Card, we allow deferred attach */
  628                 if (IS_SCSI(isp)) {
  629                         isp_uninit(isp);
  630                         (void) pci_unmap_int(cfid); /* Does nothing */
  631                         ISP_UNLOCK(isp);
  632                         free(pcs, M_DEVBUF);
  633                         return;
  634                 }
  635         }
  636         ISP_UNLOCK(isp);
  637 #ifdef __alpha__
  638         /*
  639          * THIS SHOULD NOT HAVE TO BE HERE
  640          */
  641         alpha_register_pci_scsi(cfid->bus, cfid->slot, isp->isp_sim);
  642 #endif  
  643 }
  644 
  645 static u_int16_t
  646 isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
  647 {
  648         u_int16_t rv;
  649         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  650         int offset, oldconf = 0;
  651 
  652         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  653                 /*
  654                  * We will assume that someone has paused the RISC processor.
  655                  */
  656                 oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
  657                 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
  658         }
  659         offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
  660         offset += (regoff & 0xff);
  661         rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
  662         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  663                 isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
  664         }
  665         return (rv);
  666 }
  667 
  668 static void
  669 isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
  670 {
  671         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  672         int offset, oldconf = 0;
  673 
  674         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  675                 /*
  676                  * We will assume that someone has paused the RISC processor.
  677                  */
  678                 oldconf = isp_pci_rd_reg(isp, BIU_CONF1);
  679                 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP);
  680         }
  681         offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
  682         offset += (regoff & 0xff);
  683         bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
  684         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  685                 isp_pci_wr_reg(isp, BIU_CONF1, oldconf);
  686         }
  687 }
  688 
  689 #if !defined(ISP_DISABLE_1080_SUPPORT) && !defined(ISP_DISABLE_12160_SUPPORT)
  690 static u_int16_t
  691 isp_pci_rd_reg_1080(isp, regoff)
  692         struct ispsoftc *isp;
  693         int regoff;
  694 {
  695         u_int16_t rv, oc = 0;
  696         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  697         int offset;
  698 
  699         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
  700             (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
  701                 u_int16_t tc;
  702                 /*
  703                  * We will assume that someone has paused the RISC processor.
  704                  */
  705                 oc = isp_pci_rd_reg(isp, BIU_CONF1);
  706                 tc = oc & ~BIU_PCI1080_CONF1_DMA;
  707                 if (regoff & SXP_BANK1_SELECT)
  708                         tc |= BIU_PCI1080_CONF1_SXP1;
  709                 else
  710                         tc |= BIU_PCI1080_CONF1_SXP0;
  711                 isp_pci_wr_reg(isp, BIU_CONF1, tc);
  712         } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
  713                 oc = isp_pci_rd_reg(isp, BIU_CONF1);
  714                 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
  715         }
  716         offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
  717         offset += (regoff & 0xff);
  718         rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset);
  719         if (oc) {
  720                 isp_pci_wr_reg(isp, BIU_CONF1, oc);
  721         }
  722         return (rv);
  723 }
  724 
  725 static void
  726 isp_pci_wr_reg_1080(isp, regoff, val)
  727         struct ispsoftc *isp;
  728         int regoff;
  729         u_int16_t val;
  730 {
  731         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  732         int offset, oc = 0;
  733 
  734         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
  735             (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
  736                 u_int16_t tc;
  737                 /*
  738                  * We will assume that someone has paused the RISC processor.
  739                  */
  740                 oc = isp_pci_rd_reg(isp, BIU_CONF1);
  741                 tc = oc & ~BIU_PCI1080_CONF1_DMA;
  742                 if (regoff & SXP_BANK1_SELECT)
  743                         tc |= BIU_PCI1080_CONF1_SXP1;
  744                 else
  745                         tc |= BIU_PCI1080_CONF1_SXP0;
  746                 isp_pci_wr_reg(isp, BIU_CONF1, tc);
  747         } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
  748                 oc = isp_pci_rd_reg(isp, BIU_CONF1);
  749                 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA);
  750         }
  751         offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT];
  752         offset += (regoff & 0xff);
  753         bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val);
  754         if (oc) {
  755                 isp_pci_wr_reg(isp, BIU_CONF1, oc);
  756         }
  757 }
  758 #endif
  759 
  760 static int
  761 isp_pci_mbxdma(struct ispsoftc *isp)
  762 {
  763         struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
  764         u_int32_t len;
  765         int rseg;
  766 
  767         if (isp->isp_rquest)    /* been here before? */
  768                 return (0);
  769 
  770         len = sizeof (ISP_SCSI_XFER_T **) * isp->isp_maxcmds;
  771         isp->isp_xflist = (ISP_SCSI_XFER_T **) malloc(len, M_DEVBUF, M_WAITOK);
  772         if (isp->isp_xflist == NULL) {
  773                 printf("%s: can't alloc xflist array\n", isp->isp_name);
  774                 return (1);
  775         }
  776         bzero(isp->isp_xflist, len);
  777 
  778         /*
  779          * Allocate and map the request queue.
  780          */
  781         len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN);
  782         isp->isp_rquest = malloc(len, M_DEVBUF, M_NOWAIT);
  783         if (isp->isp_rquest == NULL) {
  784                 free(isp->isp_xflist, M_DEVBUF);
  785                 printf("%s: cannot malloc request queue\n", isp->isp_name);
  786                 return (1);
  787         }
  788         isp->isp_rquest_dma = vtophys(isp->isp_rquest);
  789 
  790 #if     0
  791         printf("RQUEST=0x%x (0x%x)...", isp->isp_rquest, isp->isp_rquest_dma);
  792 #endif
  793 
  794         /*
  795          * Allocate and map the result queue.
  796          */
  797         len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN);
  798         isp->isp_result = malloc(len, M_DEVBUF, M_NOWAIT);
  799         if (isp->isp_result == NULL) {
  800                 free(isp->isp_xflist, M_DEVBUF);
  801                 free(isp->isp_rquest, M_DEVBUF);
  802                 printf("%s: cannot malloc result queue\n", isp->isp_name);
  803                 return (1);
  804         }
  805         isp->isp_result_dma = vtophys(isp->isp_result);
  806 #if     0
  807         printf("RESULT=0x%x (0x%x)\n", isp->isp_result, isp->isp_result_dma);
  808 #endif
  809         if (isp->isp_type & ISP_HA_FC) {
  810                 fcparam *fcp = isp->isp_param;
  811                 len = ISP2100_SCRLEN;
  812                 fcp->isp_scratch = (caddr_t)
  813                     malloc(ISP2100_SCRLEN, M_DEVBUF, M_NOWAIT);
  814                 if (fcp->isp_scratch == NULL) {
  815                         free(isp->isp_xflist, M_DEVBUF);
  816                         free(isp->isp_rquest, M_DEVBUF);
  817                         free(isp->isp_result, M_DEVBUF);
  818                         printf("%s: cannot alloc scratch\n", isp->isp_name);
  819                         return (1);
  820                 }
  821                 fcp->isp_scdma = vtophys(fcp->isp_scratch);
  822         }
  823         return (0);
  824 }
  825 
  826 static int
  827 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs,
  828         ispreq_t *rq, u_int16_t *iptrp, u_int16_t optr)
  829 {
  830         struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
  831         ispcontreq_t *crq;
  832         vm_offset_t vaddr;
  833         int drq, seglim;
  834         u_int32_t paddr, nextpaddr, datalen, size, *ctrp;
  835 
  836         if (xs->datalen == 0) {
  837                 rq->req_seg_count = 1;
  838                 return (CMD_QUEUED);
  839         }
  840 
  841         if (xs->flags & SCSI_DATA_IN) {
  842                 drq = REQFLAG_DATA_IN;
  843         } else {
  844                 drq = REQFLAG_DATA_OUT;
  845         }
  846 
  847         if (isp->isp_type & ISP_HA_FC) {
  848                 seglim = ISP_RQDSEG_T2;
  849                 ((ispreqt2_t *)rq)->req_totalcnt = XS_XFRLEN(xs);
  850                 ((ispreqt2_t *)rq)->req_flags |= drq;
  851         } else {
  852                 rq->req_flags |= drq;
  853                 if (XS_CDBLEN(xs) > 12) {
  854                         seglim = 0;
  855                 } else {
  856                         seglim = ISP_RQDSEG;
  857                 }
  858         }
  859 
  860         datalen = XS_XFRLEN(xs);
  861         vaddr = (vm_offset_t) xs->data;
  862         paddr = vtophys(vaddr);
  863 
  864         while (datalen != 0 && rq->req_seg_count < seglim) {
  865                 if (isp->isp_type & ISP_HA_FC) {
  866                         ispreqt2_t *rq2 = (ispreqt2_t *)rq;
  867                         rq2->req_dataseg[rq2->req_seg_count].ds_base = paddr;
  868                         ctrp = &rq2->req_dataseg[rq2->req_seg_count].ds_count;
  869                 } else {
  870                         rq->req_dataseg[rq->req_seg_count].ds_base = paddr;
  871                         ctrp = &rq->req_dataseg[rq->req_seg_count].ds_count;
  872                 }
  873                 nextpaddr = paddr;
  874                 *(ctrp) = 0;
  875 
  876                 while (datalen != 0 && paddr == nextpaddr) {
  877                         nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
  878                         size = nextpaddr - paddr;
  879                         if (size > datalen)
  880                                 size = datalen;
  881                         *(ctrp) += size;
  882                         vaddr += size;
  883                         datalen -= size;
  884                         if (datalen != 0)
  885                                 paddr = vtophys(vaddr);
  886 
  887                 }
  888 #if     0
  889                 if (isp->isp_type & ISP_HA_FC) {
  890                         ispreqt2_t *rq2 = (ispreqt2_t *)rq;
  891                         printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
  892                             isp->isp_name, rq->req_seg_count,
  893                             rq2->req_dataseg[rq2->req_seg_count].ds_count,
  894                             rq2->req_dataseg[rq2->req_seg_count].ds_base);
  895                 } else {
  896                         printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n",
  897                             isp->isp_name, rq->req_seg_count,
  898                             rq->req_dataseg[rq->req_seg_count].ds_count,
  899                             rq->req_dataseg[rq->req_seg_count].ds_base);
  900                 }
  901 #endif
  902                 rq->req_seg_count++;
  903         }
  904 
  905 
  906 
  907         if (datalen == 0)
  908                 return (CMD_QUEUED);
  909 
  910         paddr = vtophys(vaddr);
  911         while (datalen > 0) {
  912                 crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp);
  913                 *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN);
  914                 if (*iptrp == optr) {
  915                         printf("%s: Request Queue Overflow\n", isp->isp_name);
  916                         XS_SETERR(xs, HBA_BOTCH);
  917                         return (CMD_EAGAIN);
  918                 }
  919                 rq->req_header.rqs_entry_count++;
  920                 bzero((void *)crq, sizeof (*crq));
  921                 crq->req_header.rqs_entry_count = 1;
  922                 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
  923 
  924                 for (seglim = 0; datalen != 0 && seglim < ISP_CDSEG; seglim++) {
  925                         crq->req_dataseg[seglim].ds_base = paddr;
  926                         ctrp = &crq->req_dataseg[seglim].ds_count;
  927                         *(ctrp) = 0;
  928                         nextpaddr = paddr;
  929                         while (datalen != 0 && paddr == nextpaddr) {
  930                                 nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE;
  931                                 size = nextpaddr - paddr;
  932                                 if (size > datalen)
  933                                         size = datalen;
  934                                 *(ctrp) += size;
  935                                 vaddr += size;
  936                                 datalen -= size;
  937                                 if (datalen != 0)
  938                                         paddr = vtophys(vaddr);
  939                         }
  940 #if     0
  941                         printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n",
  942                             isp->isp_name, rq->req_header.rqs_entry_count-1,
  943                             seglim, crq->req_dataseg[seglim].ds_count,
  944                             crq->req_dataseg[seglim].ds_base);
  945 #endif
  946                         rq->req_seg_count++;
  947                 }
  948         }
  949 
  950         return (CMD_QUEUED);
  951 }
  952 
  953 static void
  954 isp_pci_reset1(struct ispsoftc *isp)
  955 {
  956         /* Make sure the BIOS is disabled */
  957         isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
  958 }
  959 
  960 static void
  961 isp_pci_dumpregs(struct ispsoftc *isp)
  962 {
  963         struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp;
  964         printf("%s: PCI Status Command/Status=%lx\n", pci->pci_isp.isp_name,
  965             pci_conf_read(pci->pci_id, PCIR_COMMAND));
  966 }

Cache object: 5cff734cbab0fa9b9a6fcb26380dc68f


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