root/dev/pci/isp_pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isp_pci_probe
  2. isp_pci_attach
  3. isp_pci_rd_debounced
  4. isp_pci_rd_isr
  5. isp_pci_rd_isr_2300
  6. isp_pci_rd_reg
  7. isp_pci_wr_reg
  8. isp_pci_rd_reg_1080
  9. isp_pci_wr_reg_1080
  10. isp_pci_mbxdma
  11. isp_pci_dmasetup
  12. isp_pci_intr
  13. isp_pci_dmateardown
  14. isp_pci_reset1
  15. isp_pci_dumpregs

    1 /*      $OpenBSD: isp_pci.c,v 1.39 2007/02/28 19:40:38 kettenis Exp $   */
    2 /*
    3  * PCI specific probe and attach routines for Qlogic ISP SCSI adapters.
    4  *
    5  *---------------------------------------
    6  * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
    7  * NASA/Ames Research Center
    8  * All rights reserved.
    9  *---------------------------------------
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice immediately at the beginning of the file, without modification,
   16  *    this list of conditions, and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  */
   36 
   37 #include <dev/ic/isp_openbsd.h>
   38 
   39 #include <dev/pci/pcireg.h>
   40 #include <dev/pci/pcivar.h>
   41 #include <dev/pci/pcidevs.h>
   42 
   43 #ifdef __sparc64__
   44 #include <dev/ofw/openfirm.h>
   45 #endif
   46 
   47 static u_int16_t isp_pci_rd_reg(struct ispsoftc *, int);
   48 static void isp_pci_wr_reg(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(struct ispsoftc *, int);
   51 static void isp_pci_wr_reg_1080(struct ispsoftc *, int, u_int16_t);
   52 #endif
   53 static int
   54 isp_pci_rd_isr(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
   55 #ifndef ISP_DISABLE_2300_SUPPORT
   56 static int
   57 isp_pci_rd_isr_2300(struct ispsoftc *, u_int16_t *, u_int16_t *, u_int16_t *);
   58 #endif
   59 static int isp_pci_mbxdma(struct ispsoftc *);
   60 static int isp_pci_dmasetup(struct ispsoftc *, struct scsi_xfer *,
   61         ispreq_t *, u_int16_t *, u_int16_t);
   62 static void
   63 isp_pci_dmateardown (struct ispsoftc *, struct scsi_xfer *, u_int16_t);
   64 static void isp_pci_reset1 (struct ispsoftc *);
   65 static void isp_pci_dumpregs (struct ispsoftc *, const char *);
   66 static int isp_pci_intr (void *);
   67 
   68 #ifdef  ISP_COMPILE_FW
   69 #define ISP_COMPILE_1040_FW     1
   70 #define ISP_COMPILE_1080_FW     1
   71 #define ISP_COMPILE_12160_FW    1
   72 #define ISP_COMPILE_2100_FW     1
   73 #define ISP_COMPILE_2200_FW     1
   74 #define ISP_COMPILE_2300_FW     1
   75 #endif
   76 
   77 #if     defined(ISP_DISABLE_1040_SUPPORT) || !defined(ISP_COMPILE_1040_FW)
   78 #define ISP_1040_RISC_CODE      NULL
   79 #else
   80 #define ISP_1040_RISC_CODE      (u_int16_t *) isp_1040_risc_code
   81 #include <dev/microcode/isp/asm_1040.h>
   82 #endif
   83 
   84 #if     defined(ISP_DISABLE_1080_SUPPORT) || !defined(ISP_COMPILE_1080_FW)
   85 #define ISP_1080_RISC_CODE      NULL
   86 #else
   87 #define ISP_1080_RISC_CODE      (u_int16_t *) isp_1080_risc_code
   88 #include <dev/microcode/isp/asm_1080.h>
   89 #endif
   90 
   91 #if     defined(ISP_DISABLE_12160_SUPPORT) || !defined(ISP_COMPILE_12160_FW)
   92 #define ISP_12160_RISC_CODE     (u_int16_t *) NULL
   93 #else
   94 #define ISP_12160_RISC_CODE     (u_int16_t *) isp_12160_risc_code
   95 #include <dev/microcode/isp/asm_12160.h>
   96 #endif
   97 
   98 #if     defined(ISP_DISABLE_2100_SUPPORT) || !defined(ISP_COMPILE_2100_FW)
   99 #define ISP_2100_RISC_CODE      NULL
  100 #else
  101 #define ISP_2100_RISC_CODE      (u_int16_t *) isp_2100_risc_code
  102 #include <dev/microcode/isp/asm_2100.h>
  103 #endif
  104 
  105 #if     defined(ISP_DISABLE_2200_SUPPORT) || !defined(ISP_COMPILE_2200_FW)
  106 #define ISP_2200_RISC_CODE      NULL
  107 #else
  108 #define ISP_2200_RISC_CODE      (u_int16_t *) isp_2200_risc_code
  109 #include <dev/microcode/isp/asm_2200.h>
  110 #endif
  111 
  112 #if     defined(ISP_DISABLE_2300_SUPPORT) || !defined(ISP_COMPILE_2300_FW)
  113 #define ISP_2300_RISC_CODE      NULL
  114 #else
  115 #define ISP_2300_RISC_CODE      (u_int16_t *) isp_2300_risc_code
  116 #include <dev/microcode/isp/asm_2300.h>
  117 #endif
  118 
  119 #ifndef ISP_DISABLE_1020_SUPPORT
  120 static struct ispmdvec mdvec = {
  121         isp_pci_rd_isr,
  122         isp_pci_rd_reg,
  123         isp_pci_wr_reg,
  124         isp_pci_mbxdma,
  125         isp_pci_dmasetup,
  126         isp_pci_dmateardown,
  127         NULL,
  128         isp_pci_reset1,
  129         isp_pci_dumpregs,
  130         ISP_1040_RISC_CODE,
  131         BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
  132 };
  133 #endif
  134 
  135 #ifndef ISP_DISABLE_1080_SUPPORT
  136 static struct ispmdvec mdvec_1080 = {
  137         isp_pci_rd_isr,
  138         isp_pci_rd_reg_1080,
  139         isp_pci_wr_reg_1080,
  140         isp_pci_mbxdma,
  141         isp_pci_dmasetup,
  142         isp_pci_dmateardown,
  143         NULL,
  144         isp_pci_reset1,
  145         isp_pci_dumpregs,
  146         ISP_1080_RISC_CODE,
  147         BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
  148 };
  149 #endif
  150 
  151 #ifndef ISP_DISABLE_12160_SUPPORT
  152 static struct ispmdvec mdvec_12160 = {
  153         isp_pci_rd_isr,
  154         isp_pci_rd_reg_1080,
  155         isp_pci_wr_reg_1080,
  156         isp_pci_mbxdma,
  157         isp_pci_dmasetup,
  158         isp_pci_dmateardown,
  159         NULL,
  160         isp_pci_reset1,
  161         isp_pci_dumpregs,
  162         ISP_12160_RISC_CODE,
  163         BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64
  164 };
  165 #endif
  166 
  167 #ifndef ISP_DISABLE_2100_SUPPORT
  168 static struct ispmdvec mdvec_2100 = {
  169         isp_pci_rd_isr,
  170         isp_pci_rd_reg,
  171         isp_pci_wr_reg,
  172         isp_pci_mbxdma,
  173         isp_pci_dmasetup,
  174         isp_pci_dmateardown,
  175         NULL,
  176         isp_pci_reset1,
  177         isp_pci_dumpregs,
  178         ISP_2100_RISC_CODE
  179 };
  180 #endif
  181 
  182 #ifndef ISP_DISABLE_2200_SUPPORT
  183 static struct ispmdvec mdvec_2200 = {
  184         isp_pci_rd_isr,
  185         isp_pci_rd_reg,
  186         isp_pci_wr_reg,
  187         isp_pci_mbxdma,
  188         isp_pci_dmasetup,
  189         isp_pci_dmateardown,
  190         NULL,
  191         isp_pci_reset1,
  192         isp_pci_dumpregs,
  193         ISP_2200_RISC_CODE
  194 };
  195 #endif
  196 
  197 #ifndef ISP_DISABLE_2300_SUPPORT
  198 static struct ispmdvec mdvec_2300 = {
  199         isp_pci_rd_isr_2300,
  200         isp_pci_rd_reg,
  201         isp_pci_wr_reg,
  202         isp_pci_mbxdma,
  203         isp_pci_dmasetup,
  204         isp_pci_dmateardown,
  205         NULL,
  206         isp_pci_reset1,
  207         isp_pci_dumpregs,
  208         ISP_2300_RISC_CODE
  209 };
  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_ISP10160
  233 #define PCI_PRODUCT_QLOGIC_ISP10160     0x1016
  234 #endif
  235 
  236 #ifndef PCI_PRODUCT_QLOGIC_ISP12160
  237 #define PCI_PRODUCT_QLOGIC_ISP12160     0x1216
  238 #endif
  239 
  240 #ifndef PCI_PRODUCT_QLOGIC_ISP2100
  241 #define PCI_PRODUCT_QLOGIC_ISP2100      0x2100
  242 #endif
  243 
  244 #ifndef PCI_PRODUCT_QLOGIC_ISP2200
  245 #define PCI_PRODUCT_QLOGIC_ISP2200      0x2200
  246 #endif
  247 
  248 #ifndef PCI_PRODUCT_QLOGIC_ISP2300
  249 #define PCI_PRODUCT_QLOGIC_ISP2300      0x2300
  250 #endif
  251 
  252 #ifndef PCI_PRODUCT_QLOGIC_ISP2312
  253 #define PCI_PRODUCT_QLOGIC_ISP2312      0x2312
  254 #endif
  255 
  256 #ifndef PCI_PRODUCT_QLOGIC_ISP6312
  257 #define PCI_PRODUCT_QLOGIC_ISP6312      0x6312
  258 #endif
  259 
  260 #define PCI_QLOGIC_ISP  ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC)
  261 
  262 #define PCI_QLOGIC_ISP1080      \
  263         ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC)
  264 
  265 #define PCI_QLOGIC_ISP1240      \
  266         ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC)
  267 
  268 #define PCI_QLOGIC_ISP1280      \
  269         ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC)
  270 
  271 #define PCI_QLOGIC_ISP10160     \
  272         ((PCI_PRODUCT_QLOGIC_ISP10160 << 16) | PCI_VENDOR_QLOGIC)
  273 
  274 #define PCI_QLOGIC_ISP12160     \
  275         ((PCI_PRODUCT_QLOGIC_ISP12160 << 16) | PCI_VENDOR_QLOGIC)
  276 
  277 #define PCI_QLOGIC_ISP2100      \
  278         ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC)
  279 
  280 #define PCI_QLOGIC_ISP2200      \
  281         ((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC)
  282 
  283 #define PCI_QLOGIC_ISP2300      \
  284         ((PCI_PRODUCT_QLOGIC_ISP2300 << 16) | PCI_VENDOR_QLOGIC)
  285 
  286 #define PCI_QLOGIC_ISP2312      \
  287         ((PCI_PRODUCT_QLOGIC_ISP2312 << 16) | PCI_VENDOR_QLOGIC)
  288 
  289 #define PCI_QLOGIC_ISP6312      \
  290         ((PCI_PRODUCT_QLOGIC_ISP6312 << 16) | PCI_VENDOR_QLOGIC)
  291 
  292 /*
  293  * Odd case for some AMI raid cards... We need to *not* attach to this.
  294  */
  295 #define AMI_RAID_SUBVENDOR_ID   0x101e
  296 
  297 
  298 #define IO_MAP_REG      0x10
  299 #define MEM_MAP_REG     0x14
  300 #define PCIR_ROMADDR    0x30
  301 
  302 #define PCI_DFLT_LTNCY  0x40
  303 #define PCI_DFLT_LNSZ   0x10
  304 
  305 #ifndef SCSI_ISP_PREFER_MEM_MAP
  306 #ifdef __alpha__
  307 #define SCSI_ISP_PREFER_MEM_MAP 1
  308 #else
  309 #define SCSI_ISP_PREFER_MEM_MAP 0
  310 #endif
  311 #endif
  312 
  313 #ifndef BUS_DMA_COHERENT
  314 #define BUS_DMA_COHERENT        BUS_DMAMEM_NOSYNC
  315 #endif
  316 
  317 static int isp_pci_probe (struct device *, void *, void *);
  318 static void isp_pci_attach (struct device *, struct device *, void *);
  319 
  320 struct isp_pcisoftc {
  321         struct ispsoftc         pci_isp;
  322         pci_chipset_tag_t       pci_pc;
  323         pcitag_t                pci_tag;
  324         bus_space_tag_t         pci_st;
  325         bus_space_handle_t      pci_sh;
  326         bus_dmamap_t            *pci_xfer_dmap;
  327         void *                  pci_ih;
  328         int16_t                 pci_poff[_NREG_BLKS];
  329 };
  330 
  331 struct cfattach isp_pci_ca = {
  332         sizeof (struct isp_pcisoftc), isp_pci_probe, isp_pci_attach
  333 };
  334 
  335 #ifdef  DEBUG
  336 const char vstring[] =
  337     "Qlogic ISP Driver, NetBSD (pci) Platform Version %d.%d Core Version %d.%d";
  338 #endif
  339 
  340 const struct pci_matchid ispdev[] = {
  341 #ifndef ISP_DISABLE_1020_SUPPORT
  342         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1020 },
  343 #endif
  344 #ifndef ISP_DISABLE_1080_SUPPORT
  345         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1080 },
  346         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1240 },
  347         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP1280 },
  348 #endif
  349 #ifndef ISP_DISABLE_12160_SUPPORT
  350         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP10160 },
  351         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP12160 },
  352 #endif
  353 #ifndef ISP_DISABLE_2100_SUPPORT
  354         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2100 },
  355 #endif
  356 #ifndef ISP_DISABLE_2200_SUPPORT
  357         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2200 },
  358 #endif
  359 #ifndef ISP_DISABLE_2300_SUPPORT
  360         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2300 },
  361         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP2312 },
  362         { PCI_VENDOR_QLOGIC, PCI_PRODUCT_QLOGIC_ISP6312 },
  363 #endif
  364         { 0, 0 }
  365 };
  366 
  367 static int
  368 isp_pci_probe(struct device *parent, void *match, void *aux)
  369 {
  370         struct pci_attach_args *pa = aux;
  371 
  372 #ifndef ISP_DISABLE_12160_SUPPORT
  373         /*
  374          * Sigh. Check for subvendor id match here. Too bad we
  375          * can't give an exclude mask in matchbyid.
  376          */
  377         if (pa->pa_id == PCI_QLOGIC_ISP12160) {
  378                 pcireg_t subvid =
  379                     pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBVEND_0);
  380                 if (PCI_VENDOR(subvid) == AMI_RAID_SUBVENDOR_ID) {
  381                         return (0);
  382                 }
  383         }
  384 #endif
  385         return (pci_matchbyid(pa, ispdev, sizeof(ispdev)/sizeof(ispdev[0])));
  386 }
  387 
  388 
  389 static void    
  390 isp_pci_attach(struct device *parent, struct device *self, void *aux)
  391 {
  392 #ifdef  DEBUG
  393         static char oneshot = 1;
  394 #endif
  395         static const char nomem[] = ": no mem for sdparam table\n";
  396         u_int32_t data, rev, linesz = PCI_DFLT_LNSZ;
  397         struct pci_attach_args *pa = aux;
  398         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) self;
  399         struct ispsoftc *isp = &pcs->pci_isp;
  400         bus_space_tag_t st, iot, memt;
  401         bus_space_handle_t sh, ioh, memh;
  402         pci_intr_handle_t ih;
  403         const char *intrstr;
  404         int ioh_valid, memh_valid;
  405         bus_size_t iosize, msize;
  406         u_int32_t confopts = 0;
  407 
  408         ioh_valid = memh_valid = 0;
  409 
  410 #if     SCSI_ISP_PREFER_MEM_MAP == 1
  411         if (pci_mapreg_map(pa, MEM_MAP_REG, PCI_MAPREG_TYPE_MEM, 0,
  412             &memt, &memh, NULL, &msize, 0)) {
  413                 printf(": can't map mem space\n");
  414         } else  {
  415                 st = memt;
  416                 sh = memh;
  417                 memh_valid = 1;
  418         }
  419         if (memh_valid == 0) {
  420                 if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0,
  421                     &iot, &ioh, NULL, &iosize, 0)) {
  422                 } else {
  423                         st = iot;
  424                         sh = ioh;
  425                         ioh_valid = 1;
  426                 }
  427         }
  428 #else
  429         if (pci_mapreg_map(pa, IO_MAP_REG, PCI_MAPREG_TYPE_IO, 0,
  430             &iot, &ioh, NULL, &iosize, 0)) {
  431                 printf(": can't map i/o space\n");
  432         } else {
  433                 st = iot;
  434                 sh = ioh;
  435                 ioh_valid = 1;
  436         }
  437         if (ioh_valid == 0) {
  438                 if (pci_mapreg_map(pa, MEM_MAP_REG, PCI_MAPREG_TYPE_MEM, 0,
  439                     &memt, &memh, NULL, &msize, 0)) {
  440                         printf(": can't map mem space\n");
  441                 } else  {
  442                         st = memt;
  443                         sh = memh;
  444                         memh_valid = 1;
  445                 }
  446         }
  447 #endif
  448         if (ioh_valid == 0 && memh_valid == 0) {
  449                 printf(": unable to map device registers\n");
  450                 return;
  451         }
  452 #if 0
  453         printf("\n");
  454 #endif
  455 
  456         pcs->pci_st = st;
  457         pcs->pci_sh = sh;
  458         pcs->pci_pc = pa->pa_pc;
  459         pcs->pci_tag = pa->pa_tag;
  460         pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF;
  461         pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF;
  462         pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF;
  463         pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF;
  464         pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF;
  465         rev = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG) & 0xff;
  466 #ifndef ISP_DISABLE_1020_SUPPORT
  467         if (pa->pa_id == PCI_QLOGIC_ISP) {
  468                 isp->isp_mdvec = &mdvec;
  469                 isp->isp_type = ISP_HA_SCSI_UNKNOWN;
  470                 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
  471                 if (isp->isp_param == NULL) {
  472                         printf(nomem);
  473                         return;
  474                 }
  475                 bzero(isp->isp_param, sizeof (sdparam));
  476         }
  477 #endif
  478 #ifndef ISP_DISABLE_1080_SUPPORT
  479         if (pa->pa_id == PCI_QLOGIC_ISP1080) {
  480                 isp->isp_mdvec = &mdvec_1080;
  481                 isp->isp_type = ISP_HA_SCSI_1080;
  482                 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
  483                 if (isp->isp_param == NULL) {
  484                         printf(nomem);
  485                         return;
  486                 }
  487                 bzero(isp->isp_param, sizeof (sdparam));
  488                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  489                     ISP1080_DMA_REGS_OFF;
  490         }
  491         if (pa->pa_id == PCI_QLOGIC_ISP1240) {
  492                 isp->isp_mdvec = &mdvec_1080;
  493                 isp->isp_type = ISP_HA_SCSI_1240;
  494                 isp->isp_param = malloc(2 * sizeof (sdparam),
  495                     M_DEVBUF, M_NOWAIT);
  496                 if (isp->isp_param == NULL) {
  497                         printf(nomem);
  498                         return;
  499                 }
  500                 bzero(isp->isp_param, sizeof (sdparam));
  501                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  502                     ISP1080_DMA_REGS_OFF;
  503         }
  504         if (pa->pa_id == PCI_QLOGIC_ISP1280) {
  505                 isp->isp_mdvec = &mdvec_1080;
  506                 isp->isp_type = ISP_HA_SCSI_1280;
  507                 isp->isp_param = malloc(2 * sizeof (sdparam),
  508                     M_DEVBUF, M_NOWAIT);
  509                 if (isp->isp_param == NULL) {
  510                         printf(nomem);
  511                         return;
  512                 }
  513                 bzero(isp->isp_param, sizeof (sdparam));
  514                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  515                     ISP1080_DMA_REGS_OFF;
  516         }
  517 #endif
  518 #ifndef ISP_DISABLE_12160_SUPPORT
  519         if (pa->pa_id == PCI_QLOGIC_ISP10160) {
  520                 isp->isp_mdvec = &mdvec_12160;
  521                 isp->isp_type = ISP_HA_SCSI_10160;
  522                 isp->isp_param = malloc(sizeof (sdparam), M_DEVBUF, M_NOWAIT);
  523                 if (isp->isp_param == NULL) {
  524                         printf(nomem);
  525                         return;
  526                 }
  527                 bzero(isp->isp_param, sizeof (sdparam));
  528                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  529                     ISP1080_DMA_REGS_OFF;
  530         }
  531         if (pa->pa_id == PCI_QLOGIC_ISP12160) {
  532                 isp->isp_mdvec = &mdvec_12160;
  533                 isp->isp_type = ISP_HA_SCSI_12160;
  534                 isp->isp_param = malloc(2 * sizeof (sdparam),
  535                     M_DEVBUF, M_NOWAIT);
  536                 if (isp->isp_param == NULL) {
  537                         printf(nomem);
  538                         return;
  539                 }
  540                 bzero(isp->isp_param, 2 * sizeof (sdparam));
  541                 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] =
  542                     ISP1080_DMA_REGS_OFF;
  543         }
  544 #endif
  545 #ifndef ISP_DISABLE_2100_SUPPORT
  546         if (pa->pa_id == PCI_QLOGIC_ISP2100) {
  547                 isp->isp_mdvec = &mdvec_2100;
  548                 isp->isp_type = ISP_HA_FC_2100;
  549                 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
  550                 if (isp->isp_param == NULL) {
  551                         printf(nomem);
  552                         return;
  553                 }
  554                 bzero(isp->isp_param, sizeof (fcparam));
  555                 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
  556                     PCI_MBOX_REGS2100_OFF;
  557                 if (rev < 3) {
  558                         /*
  559                          * XXX: Need to get the actual revision
  560                          * XXX: number of the 2100 FB. At any rate,
  561                          * XXX: lower cache line size for early revision
  562                          * XXX; boards.
  563                          */
  564                         linesz = 1;
  565                 }
  566         }
  567 #endif
  568 #ifndef ISP_DISABLE_2200_SUPPORT
  569         if (pa->pa_id == PCI_QLOGIC_ISP2200) {
  570                 isp->isp_mdvec = &mdvec_2200;
  571                 isp->isp_type = ISP_HA_FC_2200;
  572                 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
  573                 if (isp->isp_param == NULL) {
  574                         printf(nomem);
  575                         return;
  576                 }
  577                 bzero(isp->isp_param, sizeof (fcparam));
  578                 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
  579                     PCI_MBOX_REGS2100_OFF;
  580                 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
  581 #ifdef __sparc64__
  582                 {
  583                         char name[32];
  584 
  585                         bzero(name, sizeof(name));
  586                         OF_getprop(PCITAG_NODE(pa->pa_tag),
  587                             "name", name, sizeof(name));
  588                         if (strcmp(name, "SUNW,qlc") == 0)
  589                                 confopts |= ISP_CFG_NONVRAM;
  590                 }
  591 #endif
  592         }
  593 #endif
  594 #ifndef ISP_DISABLE_2300_SUPPORT
  595         if (pa->pa_id == PCI_QLOGIC_ISP2300 ||
  596             pa->pa_id == PCI_QLOGIC_ISP2312 ||
  597             pa->pa_id == PCI_QLOGIC_ISP6312) {
  598                 isp->isp_mdvec = &mdvec_2300;
  599                 if (pa->pa_id  == PCI_QLOGIC_ISP2300) {
  600                         isp->isp_type = ISP_HA_FC_2300;
  601                 } else {
  602                         isp->isp_type = ISP_HA_FC_2312;
  603                         isp->isp_port = pa->pa_function;
  604                 }
  605                 isp->isp_param = malloc(sizeof (fcparam), M_DEVBUF, M_NOWAIT);
  606                 if (isp->isp_param == NULL) {
  607                         printf(nomem);
  608                         return;
  609                 }
  610                 bzero(isp->isp_param, sizeof (fcparam));
  611                 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] =
  612                     PCI_MBOX_REGS2300_OFF;
  613                 data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CLASS_REG);
  614         }
  615 #endif
  616         /*
  617          * Set up logging levels.
  618          */
  619 #ifdef  ISP_LOGDEFAULT
  620         isp->isp_dblev = ISP_LOGDEFAULT;
  621 #else
  622         isp->isp_dblev = ISP_LOGWARN|ISP_LOGERR;
  623 #ifdef  SCSIDEBUG
  624         isp->isp_dblev |= ISP_LOGDEBUG1|ISP_LOGDEBUG2;
  625 #endif
  626 #ifdef  DEBUG
  627         isp->isp_dblev |= ISP_LOGDEBUG0|ISP_LOGCONFIG|ISP_LOGINFO;
  628 #endif
  629 #endif
  630 
  631 #ifdef  DEBUG
  632         if (oneshot) {
  633                 oneshot = 0;
  634                 isp_prt(isp, ISP_LOGCONFIG, vstring,
  635                     ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR,
  636                     ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR);
  637         }
  638 #endif
  639 
  640         isp->isp_dmatag = pa->pa_dmat;
  641         isp->isp_revision = rev;
  642 
  643         /*
  644          * Make sure that command register set sanely.
  645          */
  646         data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
  647         if (IS_2300(isp)) {     /* per QLogic errata */
  648                 data &= ~PCI_COMMAND_PARITY_ENABLE;
  649         }
  650         if (IS_23XX(isp)) {
  651                 isp->isp_touched = 1;
  652         }
  653         data |= PCI_COMMAND_INVALIDATE_ENABLE;
  654 
  655         /*
  656          * Not so sure about these- but I think it's important that they get
  657          * enabled......
  658          */
  659         data |= PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE;
  660         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, data);
  661 
  662         /*
  663          * Make sure that the latency timer, cache line size,
  664          * and ROM is disabled.
  665          */
  666         data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
  667         data &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
  668         data &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
  669         data |= (0x40 << PCI_LATTIMER_SHIFT);
  670         data |= (0x10 << PCI_CACHELINE_SHIFT);
  671         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, data);
  672 
  673         data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR);
  674         data &= ~1;
  675         pci_conf_write(pa->pa_pc, pa->pa_tag, PCIR_ROMADDR, data);
  676 
  677         if (pci_intr_map(pa, &ih)) {
  678                 printf(": couldn't map interrupt\n");
  679                 free(isp->isp_param, M_DEVBUF);
  680                 return;
  681         }
  682         intrstr = pci_intr_string(pa->pa_pc, ih);
  683         if (intrstr == NULL)
  684                 intrstr = "<I dunno>";
  685         pcs->pci_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, isp_pci_intr,
  686             isp, isp->isp_name);
  687         if (pcs->pci_ih == NULL) {
  688                 printf(": couldn't establish interrupt at %s\n",
  689                         intrstr);
  690                 free(isp->isp_param, M_DEVBUF);
  691                 return;
  692         }
  693 
  694         printf(": %s\n", intrstr);
  695 
  696         if (IS_FC(isp)) {
  697                 DEFAULT_NODEWWN(isp) = 0x400000007F000003ULL;
  698                 DEFAULT_PORTWWN(isp) = 0x400000007F000003ULL;
  699         }
  700 
  701         isp->isp_confopts = confopts | self->dv_cfdata->cf_flags;
  702         isp->isp_role = ISP_DEFAULT_ROLES;
  703         ISP_LOCK(isp);
  704         isp->isp_osinfo.no_mbox_ints = 1;
  705         isp_reset(isp);
  706         if (isp->isp_state != ISP_RESETSTATE) {
  707                 ISP_UNLOCK(isp);
  708                 free(isp->isp_param, M_DEVBUF);
  709                 return;
  710         }
  711         ENABLE_INTS(isp);
  712         isp_init(isp);
  713         if (isp->isp_state != ISP_INITSTATE) {
  714                 isp_uninit(isp);
  715                 ISP_UNLOCK(isp);
  716                 free(isp->isp_param, M_DEVBUF);
  717                 return;
  718         }
  719         /*
  720          * Do Generic attach now.
  721          */
  722         isp_attach(isp);
  723         if (isp->isp_state != ISP_RUNSTATE) {
  724                 isp_uninit(isp);
  725                 ISP_UNLOCK(isp);
  726                 free(isp->isp_param, M_DEVBUF);
  727         } else {
  728                 ISP_UNLOCK(isp);
  729         }
  730 }
  731 
  732 #define IspVirt2Off(a, x)       \
  733         (((struct isp_pcisoftc *)a)->pci_poff[((x) & _BLK_REG_MASK) >> \
  734         _BLK_REG_SHFT] + ((x) & 0xff))
  735 
  736 #define BXR2(pcs, off)          \
  737         bus_space_read_2(pcs->pci_st, pcs->pci_sh, off)
  738 #define BXW2(pcs, off, v)       \
  739         bus_space_write_2(pcs->pci_st, pcs->pci_sh, off, v)
  740 
  741 
  742 static INLINE int
  743 isp_pci_rd_debounced(struct ispsoftc *isp, int off, u_int16_t *rp)
  744 {
  745         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  746         u_int16_t val0, val1;
  747         int i = 0;
  748 
  749         do {
  750                 val0 = BXR2(pcs, IspVirt2Off(isp, off));
  751                 val1 = BXR2(pcs, IspVirt2Off(isp, off));
  752         } while (val0 != val1 && ++i < 1000);
  753         if (val0 != val1) {
  754                 return (1);
  755         }
  756         *rp = val0;
  757         return (0);
  758 }
  759 
  760 static int
  761 isp_pci_rd_isr(struct ispsoftc *isp, u_int16_t *isrp,
  762     u_int16_t *semap, u_int16_t *mbp)
  763 {
  764         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  765         u_int16_t isr, sema;
  766 
  767         if (IS_2100(isp)) {
  768                 if (isp_pci_rd_debounced(isp, BIU_ISR, &isr)) {
  769                     return (0);
  770                 }
  771                 if (isp_pci_rd_debounced(isp, BIU_SEMA, &sema)) {
  772                     return (0);
  773                 }
  774         } else {
  775                 isr = BXR2(pcs, IspVirt2Off(isp, BIU_ISR));
  776                 sema = BXR2(pcs, IspVirt2Off(isp, BIU_SEMA));
  777         }
  778         isp_prt(isp, ISP_LOGDEBUG3, "ISR 0x%x SEMA 0x%x", isr, sema);
  779         isr &= INT_PENDING_MASK(isp);
  780         sema &= BIU_SEMA_LOCK;
  781         if (isr == 0 && sema == 0) {
  782                 return (0);
  783         }
  784         *isrp = isr;
  785         if ((*semap = sema) != 0) {
  786                 if (IS_2100(isp)) {
  787                         if (isp_pci_rd_debounced(isp, OUTMAILBOX0, mbp)) {
  788                                 return (0);
  789                         }
  790                 } else {
  791                         *mbp = BXR2(pcs, IspVirt2Off(isp, OUTMAILBOX0));
  792                 }
  793         }
  794         return (1);
  795 }
  796 
  797 #ifndef ISP_DISABLE_2300_SUPPORT
  798 static int
  799 isp_pci_rd_isr_2300(struct ispsoftc *isp, u_int16_t *isrp,
  800     u_int16_t *semap, u_int16_t *mbox0p)
  801 {
  802         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  803         u_int32_t r2hisr;
  804 
  805         if (!(BXR2(pcs, IspVirt2Off(isp, BIU_ISR)) & BIU2100_ISR_RISC_INT)) {
  806                 *isrp = 0;
  807                 return (0);
  808         }
  809         r2hisr = bus_space_read_4(pcs->pci_st, pcs->pci_sh,
  810             IspVirt2Off(pcs, BIU_R2HSTSLO));
  811         isp_prt(isp, ISP_LOGDEBUG3, "RISC2HOST ISR 0x%x", r2hisr);
  812         if ((r2hisr & BIU_R2HST_INTR) == 0) {
  813                 *isrp = 0;
  814                 return (0);
  815         }
  816         switch (r2hisr & BIU_R2HST_ISTAT_MASK) {
  817         case ISPR2HST_ROM_MBX_OK:
  818         case ISPR2HST_ROM_MBX_FAIL:
  819         case ISPR2HST_MBX_OK:
  820         case ISPR2HST_MBX_FAIL:
  821         case ISPR2HST_ASYNC_EVENT:
  822                 *isrp = r2hisr & 0xffff;
  823                 *mbox0p = (r2hisr >> 16);
  824                 *semap = 1;
  825                 return (1);
  826         case ISPR2HST_RIO_16:
  827                 *isrp = r2hisr & 0xffff;
  828                 *mbox0p = ASYNC_RIO1;
  829                 *semap = 1;
  830                 return (1);
  831         case ISPR2HST_FPOST:
  832                 *isrp = r2hisr & 0xffff;
  833                 *mbox0p = ASYNC_CMD_CMPLT;
  834                 *semap = 1;
  835                 return (1);
  836         case ISPR2HST_FPOST_CTIO:
  837                 *isrp = r2hisr & 0xffff;
  838                 *mbox0p = ASYNC_CTIO_DONE;
  839                 *semap = 1;
  840                 return (1);
  841         case ISPR2HST_RSPQ_UPDATE:
  842                 *isrp = r2hisr & 0xffff;
  843                 *mbox0p = 0;
  844                 *semap = 0;
  845                 return (1);
  846         default:
  847                 return (0);
  848         }
  849 }
  850 #endif
  851 
  852 static u_int16_t
  853 isp_pci_rd_reg(struct ispsoftc *isp, int regoff)
  854 {
  855         u_int16_t rv;
  856         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  857         int oldconf = 0;
  858 
  859         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  860                 /*
  861                  * We will assume that someone has paused the RISC processor.
  862                  */
  863                 oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
  864                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
  865                     oldconf | BIU_PCI_CONF1_SXP);
  866         }
  867         rv = BXR2(pcs, IspVirt2Off(isp, regoff));
  868         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  869                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
  870         }
  871         return (rv);
  872 }
  873 
  874 static void
  875 isp_pci_wr_reg(struct ispsoftc *isp, int regoff, u_int16_t val)
  876 {
  877         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  878         int oldconf = 0;
  879 
  880         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  881                 /*
  882                  * We will assume that someone has paused the RISC processor.
  883                  */
  884                 oldconf = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
  885                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1),
  886                     oldconf | BIU_PCI_CONF1_SXP);
  887         }
  888         BXW2(pcs, IspVirt2Off(isp, regoff), val);
  889         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) {
  890                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oldconf);
  891         }
  892 }
  893 
  894 #if !(defined(ISP_DISABLE_1080_SUPPORT) && defined(ISP_DISABLE_12160_SUPPORT))
  895 static u_int16_t
  896 isp_pci_rd_reg_1080(struct ispsoftc *isp, int regoff)
  897 {
  898         u_int16_t rv, oc = 0;
  899         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  900 
  901         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
  902             (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
  903                 u_int16_t tc;
  904                 /*
  905                  * We will assume that someone has paused the RISC processor.
  906                  */
  907                 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
  908                 tc = oc & ~BIU_PCI1080_CONF1_DMA;
  909                 if (regoff & SXP_BANK1_SELECT)
  910                         tc |= BIU_PCI1080_CONF1_SXP1;
  911                 else
  912                         tc |= BIU_PCI1080_CONF1_SXP0;
  913                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
  914         } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
  915                 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
  916                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), 
  917                     oc | BIU_PCI1080_CONF1_DMA);
  918         }
  919         rv = BXR2(pcs, IspVirt2Off(isp, regoff));
  920         if (oc) {
  921                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
  922         }
  923         return (rv);
  924 }
  925 
  926 static void
  927 isp_pci_wr_reg_1080(struct ispsoftc *isp, int regoff, u_int16_t val)
  928 {
  929         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp;
  930         int oc = 0;
  931 
  932         if ((regoff & _BLK_REG_MASK) == SXP_BLOCK ||
  933             (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) {
  934                 u_int16_t tc;
  935                 /*
  936                  * We will assume that someone has paused the RISC processor.
  937                  */
  938                 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
  939                 tc = oc & ~BIU_PCI1080_CONF1_DMA;
  940                 if (regoff & SXP_BANK1_SELECT)
  941                         tc |= BIU_PCI1080_CONF1_SXP1;
  942                 else
  943                         tc |= BIU_PCI1080_CONF1_SXP0;
  944                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), tc);
  945         } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) {
  946                 oc = BXR2(pcs, IspVirt2Off(isp, BIU_CONF1));
  947                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), 
  948                     oc | BIU_PCI1080_CONF1_DMA);
  949         }
  950         BXW2(pcs, IspVirt2Off(isp, regoff), val);
  951         if (oc) {
  952                 BXW2(pcs, IspVirt2Off(isp, BIU_CONF1), oc);
  953         }
  954 }
  955 #endif
  956 
  957 static int
  958 isp_pci_mbxdma(struct ispsoftc *isp)
  959 {
  960         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
  961         bus_dma_tag_t dmat = isp->isp_dmatag;
  962         bus_dma_segment_t sg;
  963         bus_size_t len;
  964         fcparam *fcp;
  965         int rs, i;
  966 
  967         if (isp->isp_rquest_dma)        /* been here before? */
  968                 return (0);
  969 
  970         len = isp->isp_maxcmds * sizeof (XS_T *);
  971         isp->isp_xflist = (XS_T **) malloc(len, M_DEVBUF, M_WAITOK);
  972         if (isp->isp_xflist == NULL) {
  973                 isp_prt(isp, ISP_LOGERR, "cannot malloc xflist array");
  974                 return (1);
  975         }
  976         bzero(isp->isp_xflist, len);
  977         len = isp->isp_maxcmds * sizeof (bus_dmamap_t);
  978         pcs->pci_xfer_dmap = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK);
  979         if (pcs->pci_xfer_dmap == NULL) {
  980                 free(isp->isp_xflist, M_DEVBUF);
  981                 isp->isp_xflist = NULL;
  982                 isp_prt(isp, ISP_LOGERR, "cannot malloc dma map array");
  983                 return (1);
  984         }
  985 
  986         for (i = 0; i < isp->isp_maxcmds; i++) {
  987                 if (bus_dmamap_create(dmat, MAXPHYS, (MAXPHYS / NBPG) + 1,
  988                     MAXPHYS, 0, BUS_DMA_NOWAIT, &pcs->pci_xfer_dmap[i])) {
  989                         isp_prt(isp, ISP_LOGERR, "cannot create dma maps");
  990                         break;
  991                 }
  992         }
  993 
  994         if (i < isp->isp_maxcmds) {
  995                 while (--i >= 0) {
  996                         bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
  997                 }
  998                 free(isp->isp_xflist, M_DEVBUF);
  999                 free(pcs->pci_xfer_dmap, M_DEVBUF);
 1000                 isp->isp_xflist = NULL;
 1001                 pcs->pci_xfer_dmap = NULL;
 1002                 return (1);
 1003         }
 1004 
 1005         /*
 1006          * Allocate and map the request queue.
 1007          */
 1008         len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp));
 1009         if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
 1010                              BUS_DMA_NOWAIT) ||
 1011             bus_dmamem_map(isp->isp_dmatag, &sg, rs, len,
 1012             (caddr_t *)&isp->isp_rquest, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
 1013                 goto dmafail;
 1014         }
 1015 
 1016         if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
 1017             &isp->isp_rqdmap) || bus_dmamap_load(dmat, isp->isp_rqdmap,
 1018             (caddr_t)isp->isp_rquest, len, NULL,
 1019             BUS_DMA_NOWAIT)) {
 1020                 goto dmafail;
 1021         }
 1022         isp->isp_rquest_dma = isp->isp_rqdmap->dm_segs[0].ds_addr;
 1023 
 1024         /*
 1025          * Allocate and map the result queue.
 1026          */
 1027         len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN(isp));
 1028         if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
 1029                              BUS_DMA_NOWAIT) ||
 1030             bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&isp->isp_result,
 1031             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
 1032                 goto dmafail;
 1033         }
 1034         if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
 1035             &isp->isp_rsdmap) || bus_dmamap_load(isp->isp_dmatag,
 1036             isp->isp_rsdmap, (caddr_t)isp->isp_result, len, NULL,
 1037             BUS_DMA_NOWAIT)) {
 1038                 goto dmafail;
 1039         }
 1040         isp->isp_result_dma = isp->isp_rsdmap->dm_segs[0].ds_addr;
 1041 
 1042         if (IS_SCSI(isp)) {
 1043                 return (0);
 1044         }
 1045 
 1046         fcp = isp->isp_param;
 1047         len = ISP2100_SCRLEN;
 1048         if (bus_dmamem_alloc(dmat, len, PAGE_SIZE, 0, &sg, 1, &rs,
 1049                              BUS_DMA_NOWAIT) ||
 1050             bus_dmamem_map(dmat, &sg, rs, len, (caddr_t *)&fcp->isp_scratch,
 1051             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
 1052                 goto dmafail;
 1053         }
 1054         if (bus_dmamap_create(dmat, len, 1, len, 0, BUS_DMA_NOWAIT,
 1055             &isp->isp_scdmap) || bus_dmamap_load(dmat,
 1056             isp->isp_scdmap, (caddr_t)fcp->isp_scratch, len, NULL,
 1057             BUS_DMA_NOWAIT)) {
 1058                 goto dmafail;
 1059         }
 1060         fcp->isp_scdma = isp->isp_scdmap->dm_segs[0].ds_addr;
 1061         return (0);
 1062 dmafail:
 1063         isp_prt(isp, ISP_LOGERR, "mailbox dma setup failure");
 1064         for (i = 0; i < isp->isp_maxcmds; i++) {
 1065                 bus_dmamap_destroy(dmat, pcs->pci_xfer_dmap[i]);
 1066         }
 1067         free(isp->isp_xflist, M_DEVBUF);
 1068         free(pcs->pci_xfer_dmap, M_DEVBUF);
 1069         isp->isp_xflist = NULL;
 1070         pcs->pci_xfer_dmap = NULL;
 1071         return (1);
 1072 }
 1073 
 1074 static int
 1075 isp_pci_dmasetup(struct ispsoftc *isp, XS_T *xs, ispreq_t *rq,
 1076     u_int16_t *nxtip, u_int16_t optr)
 1077 {
 1078         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
 1079         bus_dmamap_t dmap;
 1080         u_int16_t starti = isp->isp_reqidx, nxti = *nxtip;
 1081         ispreq_t *qep;
 1082         int segcnt, seg, error, ovseg, seglim, drq;
 1083 
 1084         qep = (ispreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, starti);
 1085         dmap = pcs->pci_xfer_dmap[isp_handle_index(rq->req_handle)];
 1086         if (xs->datalen == 0) {
 1087                 rq->req_seg_count = 1;
 1088                 goto mbxsync;
 1089         }
 1090 
 1091         if (xs->flags & SCSI_DATA_IN) {
 1092                 drq = REQFLAG_DATA_IN;
 1093         } else {
 1094                 drq = REQFLAG_DATA_OUT;
 1095         }
 1096 
 1097         if (IS_FC(isp)) {
 1098                 seglim = ISP_RQDSEG_T2;
 1099                 ((ispreqt2_t *)rq)->req_totalcnt = xs->datalen;
 1100                 ((ispreqt2_t *)rq)->req_flags |= drq;
 1101         } else {
 1102                 rq->req_flags |= drq;
 1103                 if (XS_CDBLEN(xs) > 12)
 1104                         seglim = 0;
 1105                 else
 1106                         seglim = ISP_RQDSEG;
 1107         }
 1108         error = bus_dmamap_load(isp->isp_dmatag, dmap, xs->data, xs->datalen,
 1109             NULL, (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
 1110         if (error) {
 1111                 XS_SETERR(xs, HBA_BOTCH);
 1112                 return (CMD_COMPLETE);
 1113         }
 1114 
 1115         segcnt = dmap->dm_nsegs;
 1116 
 1117         isp_prt(isp, ISP_LOGDEBUG2, "%d byte %s %p in %d segs",
 1118             xs->datalen, (xs->flags & SCSI_DATA_IN)? "read to" :
 1119             "write from", xs->data, segcnt);
 1120 
 1121         for (seg = 0, rq->req_seg_count = 0;
 1122              seg < segcnt && rq->req_seg_count < seglim;
 1123              seg++, rq->req_seg_count++) {
 1124                 if (isp->isp_type & ISP_HA_FC) {
 1125                         ispreqt2_t *rq2 = (ispreqt2_t *)rq;
 1126                         rq2->req_dataseg[rq2->req_seg_count].ds_count =
 1127                             dmap->dm_segs[seg].ds_len;
 1128                         rq2->req_dataseg[rq2->req_seg_count].ds_base =
 1129                             dmap->dm_segs[seg].ds_addr;
 1130                 } else {
 1131                         rq->req_dataseg[rq->req_seg_count].ds_count =
 1132                             dmap->dm_segs[seg].ds_len;
 1133                         rq->req_dataseg[rq->req_seg_count].ds_base =
 1134                             dmap->dm_segs[seg].ds_addr;
 1135                 }
 1136                 isp_prt(isp, ISP_LOGDEBUG2, "seg0.[%d]={0x%lx,%lu}",
 1137                     rq->req_seg_count, (long) dmap->dm_segs[seg].ds_addr,
 1138                     (unsigned long) dmap->dm_segs[seg].ds_len);
 1139         }
 1140 
 1141         if (seg == segcnt) {
 1142                 goto dmasync;
 1143         }
 1144 
 1145         do {
 1146                 u_int16_t onxti;
 1147                 ispcontreq_t *crq, *cqe, local;
 1148 
 1149                 crq = &local;
 1150 
 1151                 cqe = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, nxti);
 1152                 onxti = nxti;
 1153                 nxti = ISP_NXT_QENTRY(onxti, RQUEST_QUEUE_LEN(isp));
 1154                 if (nxti == optr) {
 1155                         isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow++");
 1156                         bus_dmamap_unload(isp->isp_dmatag, dmap);
 1157                         XS_SETERR(xs, HBA_BOTCH);
 1158                         return (CMD_EAGAIN);
 1159                 }
 1160                 rq->req_header.rqs_entry_count++;
 1161                 bzero((void *)crq, sizeof (*crq));
 1162                 crq->req_header.rqs_entry_count = 1;
 1163                 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG;
 1164 
 1165                 for (ovseg = 0; seg < segcnt && ovseg < ISP_CDSEG;
 1166                     rq->req_seg_count++, seg++, ovseg++) {
 1167                         crq->req_dataseg[ovseg].ds_count =
 1168                             dmap->dm_segs[seg].ds_len;
 1169                         crq->req_dataseg[ovseg].ds_base =
 1170                             dmap->dm_segs[seg].ds_addr;
 1171                         isp_prt(isp, ISP_LOGDEBUG2, "seg%d.[%d]={0x%lx,%lu}",
 1172                             rq->req_header.rqs_entry_count - 1,
 1173                             rq->req_seg_count, (long)dmap->dm_segs[seg].ds_addr,
 1174                             (unsigned long) dmap->dm_segs[seg].ds_len);
 1175                 }
 1176                 isp_put_cont_req(isp, crq, cqe);
 1177                 MEMORYBARRIER(isp, SYNC_REQUEST, onxti, QENTRY_LEN);
 1178         } while (seg < segcnt);
 1179 
 1180 dmasync:
 1181         bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize,
 1182             (xs->flags & SCSI_DATA_IN) ?  BUS_DMASYNC_PREREAD :
 1183             BUS_DMASYNC_PREWRITE);
 1184 
 1185 mbxsync:
 1186         switch (rq->req_header.rqs_entry_type) {
 1187         case RQSTYPE_REQUEST:
 1188                 isp_put_request(isp, rq, qep);
 1189                 break;
 1190         case RQSTYPE_CMDONLY:
 1191                 isp_put_extended_request(isp, (ispextreq_t *)rq,
 1192                     (ispextreq_t *)qep);
 1193                 break;
 1194         case RQSTYPE_T2RQS:
 1195                 isp_put_request_t2(isp, (ispreqt2_t *) rq, (ispreqt2_t *) qep);
 1196                 break;
 1197         }
 1198         *nxtip = nxti;
 1199         return (CMD_QUEUED);
 1200 }
 1201 
 1202 static int
 1203 isp_pci_intr(void *arg)
 1204 {
 1205         u_int16_t isr, sema, mbox;
 1206         struct ispsoftc *isp = (struct ispsoftc *)arg;
 1207 
 1208         isp->isp_intcnt++;
 1209         if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {
 1210                 isp->isp_intbogus++;
 1211                 return (0);
 1212         } else {
 1213                 isp->isp_osinfo.onintstack = 1;
 1214                 isp_intr(isp, isr, sema, mbox);
 1215                 isp->isp_osinfo.onintstack = 0;
 1216                 return (1);
 1217         }
 1218 }
 1219 
 1220 static void
 1221 isp_pci_dmateardown(struct ispsoftc *isp, XS_T *xs, u_int16_t handle)
 1222 {
 1223         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
 1224         bus_dmamap_t dmap = pcs->pci_xfer_dmap[isp_handle_index(handle)];
 1225         bus_dmamap_sync(isp->isp_dmatag, dmap, 0, dmap->dm_mapsize,
 1226             (xs->flags & SCSI_DATA_IN)?
 1227             BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 1228         bus_dmamap_unload(isp->isp_dmatag, dmap);
 1229 }
 1230 
 1231 static void
 1232 isp_pci_reset1(struct ispsoftc *isp)
 1233 {
 1234         /* Make sure the BIOS is disabled */
 1235         isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS);
 1236         if (isp->isp_osinfo.no_mbox_ints == 0) {
 1237                 ENABLE_INTS(isp);
 1238         }
 1239 }
 1240 
 1241 static void
 1242 isp_pci_dumpregs(struct ispsoftc *isp, const char *msg)
 1243 {
 1244         struct isp_pcisoftc *pcs = (struct isp_pcisoftc *)isp;
 1245         if (msg)
 1246                 isp_prt(isp, ISP_LOGERR, "%s", msg);
 1247         isp_prt(isp, ISP_LOGERR, "PCI Status Command/Status=%x\n",
 1248             pci_conf_read(pcs->pci_pc, pcs->pci_tag, PCI_COMMAND_STATUS_REG));
 1249 }

/* [<][>][^][v][top][bottom][index][help] */