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