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