1 /* $FreeBSD$ */ 2 /* 3 * PCI specific probe and attach routines for Qlogic ISP SCSI adapters. 4 * FreeBSD Version. 5 * 6 *--------------------------------------- 7 * Copyright (c) 1997, 1998, 1999 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 42 43 #include <pci/pcireg.h> 44 #include <pci/pcivar.h> 45 46 #include <machine/bus_memio.h> 47 #include <machine/bus_pio.h> 48 #include <machine/bus.h> 49 #include <machine/md_var.h> 50 51 static u_int16_t isp_pci_rd_reg __P((struct ispsoftc *, int)); 52 static void isp_pci_wr_reg __P((struct ispsoftc *, int, u_int16_t)); 53 #ifndef ISP_DISABLE_1080_SUPPORT 54 static u_int16_t isp_pci_rd_reg_1080 __P((struct ispsoftc *, int)); 55 static void isp_pci_wr_reg_1080 __P((struct ispsoftc *, int, u_int16_t)); 56 #endif 57 static int isp_pci_mbxdma __P((struct ispsoftc *)); 58 static int isp_pci_dmasetup __P((struct ispsoftc *, ISP_SCSI_XFER_T *, 59 ispreq_t *, u_int16_t *, u_int16_t)); 60 static void 61 isp_pci_dmateardown __P((struct ispsoftc *, ISP_SCSI_XFER_T *, u_int32_t)); 62 63 static void isp_pci_reset1 __P((struct ispsoftc *)); 64 static void isp_pci_dumpregs __P((struct ispsoftc *)); 65 66 #ifndef ISP_CODE_ORG 67 #define ISP_CODE_ORG 0x1000 68 #endif 69 #ifndef ISP_1040_RISC_CODE 70 #define ISP_1040_RISC_CODE NULL 71 #endif 72 #ifndef ISP_1080_RISC_CODE 73 #define ISP_1080_RISC_CODE NULL 74 #endif 75 #ifndef ISP_2100_RISC_CODE 76 #define ISP_2100_RISC_CODE NULL 77 #endif 78 #ifndef ISP_2200_RISC_CODE 79 #define ISP_2200_RISC_CODE NULL 80 #endif 81 82 #ifndef ISP_DISABLE_1020_SUPPORT 83 static struct ispmdvec mdvec = { 84 isp_pci_rd_reg, 85 isp_pci_wr_reg, 86 isp_pci_mbxdma, 87 isp_pci_dmasetup, 88 isp_pci_dmateardown, 89 NULL, 90 isp_pci_reset1, 91 isp_pci_dumpregs, 92 ISP_1040_RISC_CODE, 93 0, 94 ISP_CODE_ORG, 95 0, 96 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64, 97 0 98 }; 99 #endif 100 101 #ifndef ISP_DISABLE_1080_SUPPORT 102 static struct ispmdvec mdvec_1080 = { 103 isp_pci_rd_reg_1080, 104 isp_pci_wr_reg_1080, 105 isp_pci_mbxdma, 106 isp_pci_dmasetup, 107 isp_pci_dmateardown, 108 NULL, 109 isp_pci_reset1, 110 isp_pci_dumpregs, 111 ISP_1080_RISC_CODE, 112 0, 113 ISP_CODE_ORG, 114 0, 115 BIU_BURST_ENABLE|BIU_PCI_CONF1_FIFO_64, 116 0 117 }; 118 #endif 119 120 #ifndef ISP_DISABLE_2100_SUPPORT 121 static struct ispmdvec mdvec_2100 = { 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_2100_RISC_CODE, 131 0, 132 ISP_CODE_ORG, 133 0, 134 0, 135 0 136 }; 137 #endif 138 139 #ifndef ISP_DISABLE_2200_SUPPORT 140 static struct ispmdvec mdvec_2200 = { 141 isp_pci_rd_reg, 142 isp_pci_wr_reg, 143 isp_pci_mbxdma, 144 isp_pci_dmasetup, 145 isp_pci_dmateardown, 146 NULL, 147 isp_pci_reset1, 148 isp_pci_dumpregs, 149 ISP_2200_RISC_CODE, 150 0, 151 ISP_CODE_ORG, 152 0, 153 0, 154 0 155 }; 156 #endif 157 158 #ifndef SCSI_ISP_PREFER_MEM_MAP 159 #define SCSI_ISP_PREFER_MEM_MAP 0 160 #endif 161 162 #ifndef PCIM_CMD_INVEN 163 #define PCIM_CMD_INVEN 0x10 164 #endif 165 #ifndef PCIM_CMD_BUSMASTEREN 166 #define PCIM_CMD_BUSMASTEREN 0x0004 167 #endif 168 #ifndef PCIM_CMD_PERRESPEN 169 #define PCIM_CMD_PERRESPEN 0x0040 170 #endif 171 #ifndef PCIM_CMD_SEREN 172 #define PCIM_CMD_SEREN 0x0100 173 #endif 174 175 #ifndef PCIR_COMMAND 176 #define PCIR_COMMAND 0x04 177 #endif 178 179 #ifndef PCIR_CACHELNSZ 180 #define PCIR_CACHELNSZ 0x0c 181 #endif 182 183 #ifndef PCIR_LATTIMER 184 #define PCIR_LATTIMER 0x0d 185 #endif 186 187 #ifndef PCIR_ROMADDR 188 #define PCIR_ROMADDR 0x30 189 #endif 190 191 #ifndef PCI_VENDOR_QLOGIC 192 #define PCI_VENDOR_QLOGIC 0x1077 193 #endif 194 195 #ifndef PCI_PRODUCT_QLOGIC_ISP1020 196 #define PCI_PRODUCT_QLOGIC_ISP1020 0x1020 197 #endif 198 199 #ifndef PCI_PRODUCT_QLOGIC_ISP1080 200 #define PCI_PRODUCT_QLOGIC_ISP1080 0x1080 201 #endif 202 203 #ifndef PCI_PRODUCT_QLOGIC_ISP1240 204 #define PCI_PRODUCT_QLOGIC_ISP1240 0x1240 205 #endif 206 207 #ifndef PCI_PRODUCT_QLOGIC_ISP1280 208 #define PCI_PRODUCT_QLOGIC_ISP1280 0x1280 209 #endif 210 211 #ifndef PCI_PRODUCT_QLOGIC_ISP2100 212 #define PCI_PRODUCT_QLOGIC_ISP2100 0x2100 213 #endif 214 215 #ifndef PCI_PRODUCT_QLOGIC_ISP2200 216 #define PCI_PRODUCT_QLOGIC_ISP2200 0x2200 217 #endif 218 219 #define PCI_QLOGIC_ISP ((PCI_PRODUCT_QLOGIC_ISP1020 << 16) | PCI_VENDOR_QLOGIC) 220 221 #define PCI_QLOGIC_ISP1080 \ 222 ((PCI_PRODUCT_QLOGIC_ISP1080 << 16) | PCI_VENDOR_QLOGIC) 223 224 #define PCI_QLOGIC_ISP1240 \ 225 ((PCI_PRODUCT_QLOGIC_ISP1240 << 16) | PCI_VENDOR_QLOGIC) 226 227 #define PCI_QLOGIC_ISP1280 \ 228 ((PCI_PRODUCT_QLOGIC_ISP1280 << 16) | PCI_VENDOR_QLOGIC) 229 230 #define PCI_QLOGIC_ISP2100 \ 231 ((PCI_PRODUCT_QLOGIC_ISP2100 << 16) | PCI_VENDOR_QLOGIC) 232 233 #define PCI_QLOGIC_ISP2200 \ 234 ((PCI_PRODUCT_QLOGIC_ISP2200 << 16) | PCI_VENDOR_QLOGIC) 235 236 #define IO_MAP_REG 0x10 237 #define MEM_MAP_REG 0x14 238 239 #define PCI_DFLT_LTNCY 0x40 240 #define PCI_DFLT_LNSZ 0x10 241 242 static const char *isp_pci_probe __P((pcici_t tag, pcidi_t type)); 243 static void isp_pci_attach __P((pcici_t config_d, int unit)); 244 245 /* This distinguishing define is not right, but it does work */ 246 #ifdef __alpha__ 247 #define IO_SPACE_MAPPING ALPHA_BUS_SPACE_IO 248 #define MEM_SPACE_MAPPING ALPHA_BUS_SPACE_MEM 249 #else 250 #define IO_SPACE_MAPPING I386_BUS_SPACE_IO 251 #define MEM_SPACE_MAPPING I386_BUS_SPACE_MEM 252 #endif 253 254 struct isp_pcisoftc { 255 struct ispsoftc pci_isp; 256 pcici_t pci_id; 257 bus_space_tag_t pci_st; 258 bus_space_handle_t pci_sh; 259 int16_t pci_poff[_NREG_BLKS]; 260 bus_dma_tag_t parent_dmat; 261 bus_dma_tag_t cntrol_dmat; 262 bus_dmamap_t cntrol_dmap; 263 bus_dmamap_t *dmaps; 264 }; 265 266 static u_long ispunit; 267 268 static struct pci_device isp_pci_driver = { 269 "isp", 270 isp_pci_probe, 271 isp_pci_attach, 272 &ispunit, 273 NULL 274 }; 275 COMPAT_PCI_DRIVER (isp_pci, isp_pci_driver); 276 277 278 static const char * 279 isp_pci_probe(pcici_t tag, pcidi_t type) 280 { 281 static int oneshot = 1; 282 char *x; 283 284 switch (type) { 285 #ifndef ISP_DISABLE_1020_SUPPORT 286 case PCI_QLOGIC_ISP: 287 x = "Qlogic ISP 1020/1040 PCI SCSI Adapter"; 288 break; 289 #endif 290 #ifndef ISP_DISABLE_1080_SUPPORT 291 case PCI_QLOGIC_ISP1080: 292 x = "Qlogic ISP 1080 PCI SCSI Adapter"; 293 break; 294 case PCI_QLOGIC_ISP1240: 295 x = "Qlogic ISP 1240 PCI SCSI Adapter"; 296 break; 297 case PCI_QLOGIC_ISP1280: 298 x = "Qlogic ISP 1280 PCI SCSI Adapter"; 299 break; 300 #endif 301 #ifndef ISP_DISABLE_2100_SUPPORT 302 case PCI_QLOGIC_ISP2100: 303 x = "Qlogic ISP 2100 PCI FC-AL Adapter"; 304 break; 305 #endif 306 #ifndef ISP_DISABLE_2200_SUPPORT 307 case PCI_QLOGIC_ISP2200: 308 x = "Qlogic ISP 2200 PCI FC-AL Adapter"; 309 break; 310 #endif 311 default: 312 return (NULL); 313 } 314 if (oneshot) { 315 oneshot = 0; 316 CFGPRINTF("Qlogic ISP Driver, FreeBSD Version %d.%d, " 317 "Core Version %d.%d\n", 318 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR, 319 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR); 320 } 321 return (x); 322 } 323 324 static void 325 isp_pci_attach(pcici_t cfid, int unit) 326 { 327 #ifdef SCSI_ISP_WWN 328 const char *name = SCSI_ISP_WWN; 329 char *vtp = NULL; 330 #endif 331 int mapped, prefer_mem_map, bitmap; 332 pci_port_t io_port; 333 u_int32_t data, rev, linesz, psize, basetype; 334 struct isp_pcisoftc *pcs; 335 struct ispsoftc *isp; 336 vm_offset_t vaddr, paddr; 337 struct ispmdvec *mdvp; 338 bus_size_t lim; 339 ISP_LOCKVAL_DECL; 340 341 pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT); 342 if (pcs == NULL) { 343 printf("isp%d: cannot allocate softc\n", unit); 344 return; 345 } 346 bzero(pcs, sizeof (struct isp_pcisoftc)); 347 348 /* 349 * Figure out if we're supposed to skip this one. 350 */ 351 if (getenv_int("isp_disable", &bitmap)) { 352 if (bitmap & (1 << unit)) { 353 printf("isp%d: not configuring\n", unit); 354 return; 355 } 356 } 357 358 /* 359 * Figure out which we should try first - memory mapping or i/o mapping? 360 */ 361 #if SCSI_ISP_PREFER_MEM_MAP == 1 362 prefer_mem_map = 1; 363 #else 364 prefer_mem_map = 0; 365 #endif 366 bitmap = 0; 367 if (getenv_int("isp_mem_map", &bitmap)) { 368 if (bitmap & (1 << unit)) 369 prefer_mem_map = 1; 370 } 371 bitmap = 0; 372 if (getenv_int("isp_io_map", &bitmap)) { 373 if (bitmap & (1 << unit)) 374 prefer_mem_map = 0; 375 } 376 377 vaddr = paddr = NULL; 378 mapped = 0; 379 linesz = PCI_DFLT_LNSZ; 380 /* 381 * Note that pci_conf_read is a 32 bit word aligned function. 382 */ 383 data = pci_conf_read(cfid, PCIR_COMMAND); 384 if (prefer_mem_map) { 385 if (data & PCI_COMMAND_MEM_ENABLE) { 386 if (pci_map_mem(cfid, MEM_MAP_REG, &vaddr, &paddr)) { 387 pcs->pci_st = MEM_SPACE_MAPPING; 388 pcs->pci_sh = vaddr; 389 mapped++; 390 } 391 } 392 if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) { 393 if (pci_map_port(cfid, PCI_MAP_REG_START, &io_port)) { 394 pcs->pci_st = IO_SPACE_MAPPING; 395 pcs->pci_sh = io_port; 396 mapped++; 397 } 398 } 399 } else { 400 if (data & PCI_COMMAND_IO_ENABLE) { 401 if (pci_map_port(cfid, PCI_MAP_REG_START, &io_port)) { 402 pcs->pci_st = IO_SPACE_MAPPING; 403 pcs->pci_sh = io_port; 404 mapped++; 405 } 406 } 407 if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) { 408 if (pci_map_mem(cfid, MEM_MAP_REG, &vaddr, &paddr)) { 409 pcs->pci_st = MEM_SPACE_MAPPING; 410 pcs->pci_sh = vaddr; 411 mapped++; 412 } 413 } 414 } 415 if (mapped == 0) { 416 printf("isp%d: unable to map any ports!\n", unit); 417 free(pcs, M_DEVBUF); 418 return; 419 } 420 if (bootverbose) 421 printf("isp%d: using %s space register mapping\n", unit, 422 pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory"); 423 424 data = pci_conf_read(cfid, PCI_ID_REG); 425 rev = pci_conf_read(cfid, PCI_CLASS_REG) & 0xff; /* revision */ 426 pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; 427 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF; 428 pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF; 429 pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF; 430 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF; 431 /* 432 * GCC! 433 */ 434 mdvp = &mdvec; 435 basetype = ISP_HA_SCSI_UNKNOWN; 436 psize = sizeof (sdparam); 437 lim = BUS_SPACE_MAXSIZE_32BIT; 438 #ifndef ISP_DISABLE_1020_SUPPORT 439 if (data == PCI_QLOGIC_ISP) { 440 mdvp = &mdvec; 441 basetype = ISP_HA_SCSI_UNKNOWN; 442 psize = sizeof (sdparam); 443 lim = BUS_SPACE_MAXSIZE_24BIT; 444 } 445 #endif 446 #ifndef ISP_DISABLE_1080_SUPPORT 447 if (data == PCI_QLOGIC_ISP1080) { 448 mdvp = &mdvec_1080; 449 basetype = ISP_HA_SCSI_1080; 450 psize = sizeof (sdparam); 451 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 452 ISP1080_DMA_REGS_OFF; 453 } 454 if (data == PCI_QLOGIC_ISP1240) { 455 mdvp = &mdvec_1080; 456 basetype = ISP_HA_SCSI_1240; 457 psize = 2 * sizeof (sdparam); 458 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 459 ISP1080_DMA_REGS_OFF; 460 } 461 if (data == PCI_QLOGIC_ISP1280) { 462 mdvp = &mdvec_1080; 463 basetype = ISP_HA_SCSI_1280; 464 psize = 2 * sizeof (sdparam); 465 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 466 ISP1080_DMA_REGS_OFF; 467 } 468 #endif 469 #ifndef ISP_DISABLE_2100_SUPPORT 470 if (data == PCI_QLOGIC_ISP2100) { 471 mdvp = &mdvec_2100; 472 basetype = ISP_HA_FC_2100; 473 psize = sizeof (fcparam); 474 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 475 PCI_MBOX_REGS2100_OFF; 476 if (rev < 3) { 477 /* 478 * XXX: Need to get the actual revision 479 * XXX: number of the 2100 FB. At any rate, 480 * XXX: lower cache line size for early revision 481 * XXX; boards. 482 */ 483 linesz = 1; 484 } 485 } 486 #endif 487 #ifndef ISP_DISABLE_2200_SUPPORT 488 if (data == PCI_QLOGIC_ISP2200) { 489 mdvp = &mdvec_2200; 490 basetype = ISP_HA_FC_2200; 491 psize = sizeof (fcparam); 492 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 493 PCI_MBOX_REGS2100_OFF; 494 } 495 #endif 496 isp = &pcs->pci_isp; 497 isp->isp_param = malloc(psize, M_DEVBUF, M_NOWAIT); 498 if (isp->isp_param == NULL) { 499 printf("isp%d: cannot allocate parameter data\n", unit); 500 return; 501 } 502 bzero(isp->isp_param, psize); 503 isp->isp_mdvec = mdvp; 504 isp->isp_type = basetype; 505 isp->isp_revision = rev; 506 (void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit); 507 isp->isp_osinfo.unit = unit; 508 509 ISP_LOCK(isp); 510 511 /* 512 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER 513 * are set. 514 */ 515 data = pci_cfgread(cfid, PCIR_COMMAND, 2); 516 data |= PCIM_CMD_SEREN | 517 PCIM_CMD_PERRESPEN | 518 PCIM_CMD_BUSMASTEREN | 519 PCIM_CMD_INVEN; 520 pci_cfgwrite(cfid, PCIR_COMMAND, 2, data); 521 522 /* 523 * Make sure the Cache Line Size register is set sensibly. 524 */ 525 data = pci_cfgread(cfid, PCIR_CACHELNSZ, 1); 526 if (data != linesz) { 527 data = PCI_DFLT_LNSZ; 528 CFGPRINTF("%s: set PCI line size to %d\n", isp->isp_name, data); 529 pci_cfgwrite(cfid, PCIR_CACHELNSZ, data, 1); 530 } 531 532 /* 533 * Make sure the Latency Timer is sane. 534 */ 535 data = pci_cfgread(cfid, PCIR_LATTIMER, 1); 536 if (data < PCI_DFLT_LTNCY) { 537 data = PCI_DFLT_LTNCY; 538 CFGPRINTF("%s: set PCI latency to %d\n", isp->isp_name, data); 539 pci_cfgwrite(cfid, PCIR_LATTIMER, data, 1); 540 } 541 542 /* 543 * Make sure we've disabled the ROM. 544 */ 545 data = pci_cfgread(cfid, PCIR_ROMADDR, 4); 546 data &= ~1; 547 pci_cfgwrite(cfid, PCIR_ROMADDR, data, 4); 548 ISP_UNLOCK(isp); 549 550 if (bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, 551 BUS_SPACE_MAXADDR, NULL, NULL, lim + 1, 552 255, lim, 0, &pcs->parent_dmat) != 0) { 553 printf("%s: could not create master dma tag\n", isp->isp_name); 554 free(pcs, M_DEVBUF); 555 return; 556 } 557 if (pci_map_int(cfid, (void (*)(void *))isp_intr, 558 (void *)isp, &IMASK) == 0) { 559 printf("%s: could not map interrupt\n", isp->isp_name); 560 free(pcs, M_DEVBUF); 561 return; 562 } 563 564 pcs->pci_id = cfid; 565 #ifdef SCSI_ISP_NO_FWLOAD_MASK 566 if (SCSI_ISP_NO_FWLOAD_MASK && (SCSI_ISP_NO_FWLOAD_MASK & (1 << unit))) 567 isp->isp_confopts |= ISP_CFG_NORELOAD; 568 #endif 569 if (getenv_int("isp_no_fwload", &bitmap)) { 570 if (bitmap & (1 << unit)) 571 isp->isp_confopts |= ISP_CFG_NORELOAD; 572 } 573 if (getenv_int("isp_fwload", &bitmap)) { 574 if (bitmap & (1 << unit)) 575 isp->isp_confopts &= ~ISP_CFG_NORELOAD; 576 } 577 578 #ifdef SCSI_ISP_NO_NVRAM_MASK 579 if (SCSI_ISP_NO_NVRAM_MASK && (SCSI_ISP_NO_NVRAM_MASK & (1 << unit))) { 580 printf("%s: ignoring NVRAM\n", isp->isp_name); 581 isp->isp_confopts |= ISP_CFG_NONVRAM; 582 } 583 #endif 584 if (getenv_int("isp_no_nvram", &bitmap)) { 585 if (bitmap & (1 << unit)) 586 isp->isp_confopts |= ISP_CFG_NONVRAM; 587 } 588 if (getenv_int("isp_nvram", &bitmap)) { 589 if (bitmap & (1 << unit)) 590 isp->isp_confopts &= ~ISP_CFG_NONVRAM; 591 } 592 593 #ifdef SCSI_ISP_FCDUPLEX 594 if (IS_FC(isp)) { 595 if (SCSI_ISP_FCDUPLEX && (SCSI_ISP_FCDUPLEX & (1 << unit))) { 596 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 597 } 598 } 599 #endif 600 if (getenv_int("isp_fcduplex", &bitmap)) { 601 if (bitmap & (1 << unit)) 602 isp->isp_confopts |= ISP_CFG_FULL_DUPLEX; 603 } 604 if (getenv_int("isp_no_fcduplex", &bitmap)) { 605 if (bitmap & (1 << unit)) 606 isp->isp_confopts &= ~ISP_CFG_FULL_DUPLEX; 607 } 608 /* 609 * Look for overriding WWN. This is a Node WWN so it binds to 610 * all FC instances. A Port WWN will be constructed from it 611 * as appropriate. 612 */ 613 #ifdef SCSI_ISP_WWN 614 isp->isp_osinfo.default_wwn = strtoq(name, &vtp, 16); 615 if (vtp != name && *vtp == 0) { 616 isp->isp_confopts |= ISP_CFG_OWNWWN; 617 } else 618 #endif 619 if (!getenv_quad("isp_wwn", (quad_t *) &isp->isp_osinfo.default_wwn)) { 620 int i; 621 u_int64_t seed = (u_int64_t) (intptr_t) isp; 622 623 seed <<= 16; 624 seed &= ((1LL << 48) - 1LL); 625 /* 626 * This isn't very random, but it's the best we can do for 627 * the real edge case of cards that don't have WWNs. If 628 * you recompile a new vers.c, you'll get a different WWN. 629 */ 630 for (i = 0; version[i] != 0; i++) { 631 seed += version[i]; 632 } 633 /* 634 * Make sure the top nibble has something vaguely sensible. 635 */ 636 isp->isp_osinfo.default_wwn |= (4LL << 60) | seed; 637 } else { 638 isp->isp_confopts |= ISP_CFG_OWNWWN; 639 } 640 (void) getenv_int("isp_debug", &isp_debug); 641 ISP_LOCK(isp); 642 isp_reset(isp); 643 if (isp->isp_state != ISP_RESETSTATE) { 644 (void) pci_unmap_int(cfid); 645 ISP_UNLOCK(isp); 646 free(pcs, M_DEVBUF); 647 return; 648 } 649 isp_init(isp); 650 if (isp->isp_state != ISP_INITSTATE) { 651 /* If we're a Fibre Channel Card, we allow deferred attach */ 652 if (IS_SCSI(isp)) { 653 isp_uninit(isp); 654 (void) pci_unmap_int(cfid); /* Does nothing */ 655 ISP_UNLOCK(isp); 656 free(pcs, M_DEVBUF); 657 return; 658 } 659 } 660 isp_attach(isp); 661 if (isp->isp_state != ISP_RUNSTATE) { 662 /* If we're a Fibre Channel Card, we allow deferred attach */ 663 if (IS_SCSI(isp)) { 664 isp_uninit(isp); 665 (void) pci_unmap_int(cfid); /* Does nothing */ 666 ISP_UNLOCK(isp); 667 free(pcs, M_DEVBUF); 668 return; 669 } 670 } 671 ISP_UNLOCK(isp); 672 } 673 674 static u_int16_t 675 isp_pci_rd_reg(isp, regoff) 676 struct ispsoftc *isp; 677 int regoff; 678 { 679 u_int16_t rv; 680 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 681 int offset, oldconf = 0; 682 683 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 684 /* 685 * We will assume that someone has paused the RISC processor. 686 */ 687 oldconf = isp_pci_rd_reg(isp, BIU_CONF1); 688 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP); 689 } 690 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 691 offset += (regoff & 0xff); 692 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset); 693 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 694 isp_pci_wr_reg(isp, BIU_CONF1, oldconf); 695 } 696 return (rv); 697 } 698 699 static void 700 isp_pci_wr_reg(isp, regoff, val) 701 struct ispsoftc *isp; 702 int regoff; 703 u_int16_t val; 704 { 705 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 706 int offset, oldconf = 0; 707 708 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 709 /* 710 * We will assume that someone has paused the RISC processor. 711 */ 712 oldconf = isp_pci_rd_reg(isp, BIU_CONF1); 713 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP); 714 } 715 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 716 offset += (regoff & 0xff); 717 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val); 718 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 719 isp_pci_wr_reg(isp, BIU_CONF1, oldconf); 720 } 721 } 722 723 #ifndef ISP_DISABLE_1080_SUPPORT 724 static u_int16_t 725 isp_pci_rd_reg_1080(isp, regoff) 726 struct ispsoftc *isp; 727 int regoff; 728 { 729 u_int16_t rv, oc = 0; 730 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 731 int offset; 732 733 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK || 734 (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) { 735 u_int16_t tc; 736 /* 737 * We will assume that someone has paused the RISC processor. 738 */ 739 oc = isp_pci_rd_reg(isp, BIU_CONF1); 740 tc = oc & ~BIU_PCI1080_CONF1_DMA; 741 if (regoff & SXP_BANK1_SELECT) 742 tc |= BIU_PCI1080_CONF1_SXP1; 743 else 744 tc |= BIU_PCI1080_CONF1_SXP0; 745 isp_pci_wr_reg(isp, BIU_CONF1, tc); 746 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) { 747 oc = isp_pci_rd_reg(isp, BIU_CONF1); 748 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA); 749 } 750 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 751 offset += (regoff & 0xff); 752 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset); 753 if (oc) { 754 isp_pci_wr_reg(isp, BIU_CONF1, oc); 755 } 756 return (rv); 757 } 758 759 static void 760 isp_pci_wr_reg_1080(isp, regoff, val) 761 struct ispsoftc *isp; 762 int regoff; 763 u_int16_t val; 764 { 765 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 766 int offset, oc = 0; 767 768 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK || 769 (regoff & _BLK_REG_MASK) == (SXP_BLOCK|SXP_BANK1_SELECT)) { 770 u_int16_t tc; 771 /* 772 * We will assume that someone has paused the RISC processor. 773 */ 774 oc = isp_pci_rd_reg(isp, BIU_CONF1); 775 tc = oc & ~BIU_PCI1080_CONF1_DMA; 776 if (regoff & SXP_BANK1_SELECT) 777 tc |= BIU_PCI1080_CONF1_SXP1; 778 else 779 tc |= BIU_PCI1080_CONF1_SXP0; 780 isp_pci_wr_reg(isp, BIU_CONF1, tc); 781 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) { 782 oc = isp_pci_rd_reg(isp, BIU_CONF1); 783 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA); 784 } 785 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 786 offset += (regoff & 0xff); 787 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val); 788 if (oc) { 789 isp_pci_wr_reg(isp, BIU_CONF1, oc); 790 } 791 } 792 #endif 793 794 795 static void isp_map_rquest __P((void *, bus_dma_segment_t *, int, int)); 796 static void isp_map_result __P((void *, bus_dma_segment_t *, int, int)); 797 static void isp_map_fcscrt __P((void *, bus_dma_segment_t *, int, int)); 798 799 struct imush { 800 struct ispsoftc *isp; 801 int error; 802 }; 803 804 static void 805 isp_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error) 806 { 807 struct imush *imushp = (struct imush *) arg; 808 if (error) { 809 imushp->error = error; 810 } else { 811 imushp->isp->isp_rquest_dma = segs->ds_addr; 812 } 813 } 814 815 static void 816 isp_map_result(void *arg, bus_dma_segment_t *segs, int nseg, int error) 817 { 818 struct imush *imushp = (struct imush *) arg; 819 if (error) { 820 imushp->error = error; 821 } else { 822 imushp->isp->isp_result_dma = segs->ds_addr; 823 } 824 } 825 826 static void 827 isp_map_fcscrt(void *arg, bus_dma_segment_t *segs, int nseg, int error) 828 { 829 struct imush *imushp = (struct imush *) arg; 830 if (error) { 831 imushp->error = error; 832 } else { 833 fcparam *fcp = imushp->isp->isp_param; 834 fcp->isp_scdma = segs->ds_addr; 835 } 836 } 837 838 static int 839 isp_pci_mbxdma(struct ispsoftc *isp) 840 { 841 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 842 caddr_t base; 843 u_int32_t len; 844 int i, error; 845 bus_size_t lim; 846 struct imush im; 847 848 849 /* 850 * Already been here? If so, leave... 851 */ 852 if (isp->isp_rquest) { 853 return (0); 854 } 855 856 len = sizeof (ISP_SCSI_XFER_T **) * isp->isp_maxcmds; 857 isp->isp_xflist = (ISP_SCSI_XFER_T **) malloc(len, M_DEVBUF, M_WAITOK); 858 if (isp->isp_xflist == NULL) { 859 printf("%s: can't alloc xflist array\n", isp->isp_name); 860 return (1); 861 } 862 bzero(isp->isp_xflist, len); 863 len = sizeof (bus_dmamap_t) * isp->isp_maxcmds; 864 pci->dmaps = (bus_dmamap_t *) malloc(len, M_DEVBUF, M_WAITOK); 865 if (pci->dmaps == NULL) { 866 printf("%s: can't alloc dma maps\n", isp->isp_name); 867 free(isp->isp_xflist, M_DEVBUF); 868 return (1); 869 } 870 871 if (IS_FC(isp) || IS_ULTRA2(isp)) 872 lim = BUS_SPACE_MAXADDR + 1; 873 else 874 lim = BUS_SPACE_MAXADDR_24BIT + 1; 875 876 /* 877 * Allocate and map the request, result queues, plus FC scratch area. 878 */ 879 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN); 880 len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN); 881 if (IS_FC(isp)) { 882 len += ISP2100_SCRLEN; 883 } 884 if (bus_dma_tag_create(pci->parent_dmat, PAGE_SIZE, lim, 885 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, len, 1, 886 BUS_SPACE_MAXSIZE_32BIT, 0, &pci->cntrol_dmat) != 0) { 887 printf("%s: cannot create a dma tag for control spaces\n", 888 isp->isp_name); 889 free(isp->isp_xflist, M_DEVBUF); 890 free(pci->dmaps, M_DEVBUF); 891 return (1); 892 } 893 if (bus_dmamem_alloc(pci->cntrol_dmat, (void **)&base, 894 BUS_DMA_NOWAIT, &pci->cntrol_dmap) != 0) { 895 printf("%s: cannot allocate %d bytes of CCB memory\n", 896 isp->isp_name, len); 897 free(isp->isp_xflist, M_DEVBUF); 898 free(pci->dmaps, M_DEVBUF); 899 return (1); 900 } 901 902 isp->isp_rquest = base; 903 im.isp = isp; 904 im.error = 0; 905 bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_rquest, 906 ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN), isp_map_rquest, &im, 0); 907 if (im.error) { 908 printf("%s: error %d loading dma map for DMA request queue\n", 909 isp->isp_name, im.error); 910 free(isp->isp_xflist, M_DEVBUF); 911 free(pci->dmaps, M_DEVBUF); 912 isp->isp_rquest = NULL; 913 return (1); 914 } 915 isp->isp_result = base + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN); 916 im.error = 0; 917 bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_result, 918 ISP_QUEUE_SIZE(RESULT_QUEUE_LEN), isp_map_result, &im, 0); 919 if (im.error) { 920 printf("%s: error %d loading dma map for DMA result queue\n", 921 isp->isp_name, im.error); 922 free(isp->isp_xflist, M_DEVBUF); 923 free(pci->dmaps, M_DEVBUF); 924 isp->isp_rquest = NULL; 925 return (1); 926 } 927 928 for (i = 0; i < isp->isp_maxcmds; i++) { 929 error = bus_dmamap_create(pci->parent_dmat, 0, &pci->dmaps[i]); 930 if (error) { 931 printf("%s: error %d creating per-cmd DMA maps\n", 932 isp->isp_name, error); 933 free(isp->isp_xflist, M_DEVBUF); 934 free(pci->dmaps, M_DEVBUF); 935 isp->isp_rquest = NULL; 936 return (1); 937 } 938 } 939 940 if (IS_FC(isp)) { 941 fcparam *fcp = (fcparam *) isp->isp_param; 942 fcp->isp_scratch = base + 943 ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN) + 944 ISP_QUEUE_SIZE(RESULT_QUEUE_LEN); 945 im.error = 0; 946 bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, 947 fcp->isp_scratch, ISP2100_SCRLEN, isp_map_fcscrt, &im, 0); 948 if (im.error) { 949 printf("%s: error %d loading FC scratch area\n", 950 isp->isp_name, im.error); 951 free(isp->isp_xflist, M_DEVBUF); 952 free(pci->dmaps, M_DEVBUF); 953 isp->isp_rquest = NULL; 954 return (1); 955 } 956 } 957 return (0); 958 } 959 960 static void dma2 __P((void *, bus_dma_segment_t *, int, int)); 961 typedef struct { 962 struct ispsoftc *isp; 963 ISP_SCSI_XFER_T *ccb; 964 ispreq_t *rq; 965 u_int16_t *iptrp; 966 u_int16_t optr; 967 u_int error; 968 } mush_t; 969 970 #define MUSHERR_NOQENTRIES -2 971 972 static void 973 dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 974 { 975 mush_t *mp; 976 ISP_SCSI_XFER_T *ccb; 977 struct ispsoftc *isp; 978 struct isp_pcisoftc *pci; 979 bus_dmamap_t *dp; 980 bus_dma_segment_t *eseg; 981 ispreq_t *rq; 982 u_int16_t *iptrp; 983 u_int16_t optr; 984 ispcontreq_t *crq; 985 int drq, seglim, datalen; 986 987 mp = (mush_t *) arg; 988 if (error) { 989 mp->error = error; 990 return; 991 } 992 993 isp = mp->isp; 994 if (nseg < 1) { 995 printf("%s: zero or negative segment count\n", isp->isp_name); 996 mp->error = EFAULT; 997 return; 998 } 999 ccb = mp->ccb; 1000 rq = mp->rq; 1001 iptrp = mp->iptrp; 1002 optr = mp->optr; 1003 pci = (struct isp_pcisoftc *)isp; 1004 dp = &pci->dmaps[rq->req_handle - 1]; 1005 1006 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1007 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD); 1008 drq = REQFLAG_DATA_IN; 1009 } else { 1010 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREWRITE); 1011 drq = REQFLAG_DATA_OUT; 1012 } 1013 1014 datalen = XS_XFRLEN(ccb); 1015 if (IS_FC(isp)) { 1016 seglim = ISP_RQDSEG_T2; 1017 ((ispreqt2_t *)rq)->req_totalcnt = datalen; 1018 ((ispreqt2_t *)rq)->req_flags |= drq; 1019 } else { 1020 seglim = ISP_RQDSEG; 1021 rq->req_flags |= drq; 1022 } 1023 1024 eseg = dm_segs + nseg; 1025 1026 while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) { 1027 if (IS_FC(isp)) { 1028 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 1029 rq2->req_dataseg[rq2->req_seg_count].ds_base = 1030 dm_segs->ds_addr; 1031 rq2->req_dataseg[rq2->req_seg_count].ds_count = 1032 dm_segs->ds_len; 1033 } else { 1034 rq->req_dataseg[rq->req_seg_count].ds_base = 1035 dm_segs->ds_addr; 1036 rq->req_dataseg[rq->req_seg_count].ds_count = 1037 dm_segs->ds_len; 1038 } 1039 datalen -= dm_segs->ds_len; 1040 #if 0 1041 if (IS_FC(isp)) { 1042 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 1043 printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n", 1044 isp->isp_name, rq->req_seg_count, 1045 rq2->req_dataseg[rq2->req_seg_count].ds_count, 1046 rq2->req_dataseg[rq2->req_seg_count].ds_base); 1047 } else { 1048 printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n", 1049 isp->isp_name, rq->req_seg_count, 1050 rq->req_dataseg[rq->req_seg_count].ds_count, 1051 rq->req_dataseg[rq->req_seg_count].ds_base); 1052 } 1053 #endif 1054 rq->req_seg_count++; 1055 dm_segs++; 1056 } 1057 1058 while (datalen > 0 && dm_segs != eseg) { 1059 crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp); 1060 *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN); 1061 if (*iptrp == optr) { 1062 #if 0 1063 printf("%s: Request Queue Overflow++\n", isp->isp_name); 1064 #endif 1065 mp->error = MUSHERR_NOQENTRIES; 1066 return; 1067 } 1068 rq->req_header.rqs_entry_count++; 1069 bzero((void *)crq, sizeof (*crq)); 1070 crq->req_header.rqs_entry_count = 1; 1071 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG; 1072 1073 seglim = 0; 1074 while (datalen > 0 && seglim < ISP_CDSEG && dm_segs != eseg) { 1075 crq->req_dataseg[seglim].ds_base = 1076 dm_segs->ds_addr; 1077 crq->req_dataseg[seglim].ds_count = 1078 dm_segs->ds_len; 1079 #if 0 1080 printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n", 1081 isp->isp_name, rq->req_header.rqs_entry_count-1, 1082 seglim, crq->req_dataseg[seglim].ds_count, 1083 crq->req_dataseg[seglim].ds_base); 1084 #endif 1085 rq->req_seg_count++; 1086 dm_segs++; 1087 seglim++; 1088 datalen -= dm_segs->ds_len; 1089 } 1090 } 1091 } 1092 1093 static int 1094 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, ispreq_t *rq, 1095 u_int16_t *iptrp, u_int16_t optr) 1096 { 1097 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 1098 struct ccb_hdr *ccb_h; 1099 struct ccb_scsiio *csio; 1100 bus_dmamap_t *dp = NULL; 1101 mush_t mush, *mp; 1102 1103 csio = (struct ccb_scsiio *) ccb; 1104 ccb_h = &csio->ccb_h; 1105 1106 if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) { 1107 rq->req_seg_count = 1; 1108 return (CMD_QUEUED); 1109 } 1110 1111 /* 1112 * Do a virtual grapevine step to collect info for 1113 * the callback dma allocation that we have to use... 1114 */ 1115 mp = &mush; 1116 mp->isp = isp; 1117 mp->ccb = ccb; 1118 mp->rq = rq; 1119 mp->iptrp = iptrp; 1120 mp->optr = optr; 1121 mp->error = 0; 1122 1123 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { 1124 if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { 1125 int error, s; 1126 dp = &pci->dmaps[rq->req_handle - 1]; 1127 s = splsoftvm(); 1128 error = bus_dmamap_load(pci->parent_dmat, *dp, 1129 csio->data_ptr, csio->dxfer_len, dma2, mp, 0); 1130 if (error == EINPROGRESS) { 1131 bus_dmamap_unload(pci->parent_dmat, *dp); 1132 mp->error = EINVAL; 1133 printf("%s: deferred dma allocation not " 1134 "supported\n", isp->isp_name); 1135 } else if (error && mp->error == 0) { 1136 #ifdef DIAGNOSTIC 1137 printf("%s: error %d in dma mapping code\n", 1138 isp->isp_name, error); 1139 #endif 1140 mp->error = error; 1141 } 1142 splx(s); 1143 } else { 1144 /* Pointer to physical buffer */ 1145 struct bus_dma_segment seg; 1146 seg.ds_addr = (bus_addr_t)csio->data_ptr; 1147 seg.ds_len = csio->dxfer_len; 1148 dma2(mp, &seg, 1, 0); 1149 } 1150 } else { 1151 struct bus_dma_segment *segs; 1152 1153 if ((ccb_h->flags & CAM_DATA_PHYS) != 0) { 1154 printf("%s: Physical segment pointers unsupported", 1155 isp->isp_name); 1156 mp->error = EINVAL; 1157 } else if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) { 1158 printf("%s: Virtual segment addresses unsupported", 1159 isp->isp_name); 1160 mp->error = EINVAL; 1161 } else { 1162 /* Just use the segments provided */ 1163 segs = (struct bus_dma_segment *) csio->data_ptr; 1164 dma2(mp, segs, csio->sglist_cnt, 0); 1165 } 1166 } 1167 if (mp->error) { 1168 int retval = CMD_COMPLETE; 1169 if (mp->error == MUSHERR_NOQENTRIES) { 1170 retval = CMD_EAGAIN; 1171 } else if (mp->error == EFBIG) { 1172 XS_SETERR(csio, CAM_REQ_TOO_BIG); 1173 } else if (mp->error == EINVAL) { 1174 XS_SETERR(csio, CAM_REQ_INVALID); 1175 } else { 1176 XS_SETERR(csio, CAM_UNREC_HBA_ERROR); 1177 } 1178 return (retval); 1179 } else { 1180 /* 1181 * Check to see if we weren't cancelled while sleeping on 1182 * getting DMA resources... 1183 */ 1184 if ((ccb_h->status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 1185 if (dp) { 1186 bus_dmamap_unload(pci->parent_dmat, *dp); 1187 } 1188 return (CMD_COMPLETE); 1189 } 1190 return (CMD_QUEUED); 1191 } 1192 } 1193 1194 static void 1195 isp_pci_dmateardown(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs, u_int32_t handle) 1196 { 1197 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 1198 bus_dmamap_t *dp = &pci->dmaps[handle - 1]; 1199 KASSERT((handle > 0 && handle <= isp->isp_maxcmds), 1200 ("bad handle in isp_pci_dmateardonw")); 1201 if ((xs->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1202 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTREAD); 1203 } else { 1204 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTWRITE); 1205 } 1206 bus_dmamap_unload(pci->parent_dmat, *dp); 1207 } 1208 1209 1210 static void 1211 isp_pci_reset1(struct ispsoftc *isp) 1212 { 1213 /* Make sure the BIOS is disabled */ 1214 isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS); 1215 } 1216 1217 static void 1218 isp_pci_dumpregs(struct ispsoftc *isp) 1219 { 1220 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 1221 printf("%s: PCI Status Command/Status=%lx\n", pci->pci_isp.isp_name, 1222 pci_conf_read(pci->pci_id, PCIR_COMMAND)); 1223 } 1224