1 /* $Id: isp_pci.c,v 1.18 1999/04/04 01:14:02 mjacob Exp $ */ 2 /* release_4_3_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 union { 260 sdparam _x; 261 fcparam _y; 262 } _z; 263 }; 264 265 static u_long ispunit; 266 267 static struct pci_device isp_pci_driver = { 268 "isp", 269 isp_pci_probe, 270 isp_pci_attach, 271 &ispunit, 272 NULL 273 }; 274 DATA_SET (pcidevice_set, isp_pci_driver); 275 276 277 static PROBETYPE 278 isp_pci_probe(pcici_t tag, pcidi_t type) 279 { 280 static int oneshot = 1; 281 char *x; 282 283 switch (type) { 284 #ifndef ISP_DISABLE_1020_SUPPORT 285 case PCI_QLOGIC_ISP: 286 x = "Qlogic ISP 1020/1040 PCI SCSI Adapter"; 287 break; 288 #endif 289 #ifndef ISP_DISABLE_1080_SUPPORT 290 case PCI_QLOGIC_ISP1080: 291 #if 0 292 case PCI_QLOGIC_ISP1240: /* 1240 not ready yet */ 293 #endif 294 x = "Qlogic ISP 1080/1240 PCI SCSI Adapter"; 295 break; 296 #endif 297 #ifndef ISP_DISABLE_2100_SUPPORT 298 case PCI_QLOGIC_ISP2100: 299 x = "Qlogic ISP 2100 PCI FC-AL Adapter"; 300 break; 301 #endif 302 default: 303 return (NULL); 304 } 305 if (oneshot) { 306 oneshot = 0; 307 printf("%s Version %d.%d, Core Version %d.%d\n", PVS, 308 ISP_PLATFORM_VERSION_MAJOR, ISP_PLATFORM_VERSION_MINOR, 309 ISP_CORE_VERSION_MAJOR, ISP_CORE_VERSION_MINOR); 310 } 311 return (x); 312 } 313 314 315 static void 316 isp_pci_attach(pcici_t config_id, int unit) 317 { 318 int mapped; 319 pci_port_t io_port; 320 u_int32_t data, linesz; 321 struct isp_pcisoftc *pcs; 322 struct ispsoftc *isp; 323 vm_offset_t vaddr, paddr; 324 ISP_LOCKVAL_DECL; 325 326 327 pcs = malloc(sizeof (struct isp_pcisoftc), M_DEVBUF, M_NOWAIT); 328 if (pcs == NULL) { 329 printf("isp%d: cannot allocate softc\n", unit); 330 return; 331 } 332 bzero(pcs, sizeof (struct isp_pcisoftc)); 333 334 vaddr = paddr = NULL; 335 mapped = 0; 336 linesz = PCI_DFLT_LNSZ; 337 /* 338 * Note that pci_conf_read is a 32 bit word aligned function. 339 */ 340 data = pci_conf_read(config_id, PCIR_COMMAND); 341 #if SCSI_ISP_PREFER_MEM_MAP == 1 342 if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) { 343 if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) { 344 pcs->pci_st = MEM_SPACE_MAPPING; 345 pcs->pci_sh = vaddr; 346 mapped++; 347 } 348 } 349 if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) { 350 if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) { 351 pcs->pci_st = IO_SPACE_MAPPING; 352 pcs->pci_sh = io_port; 353 mapped++; 354 } 355 } 356 #else 357 if (mapped == 0 && (data & PCI_COMMAND_IO_ENABLE)) { 358 if (pci_map_port(config_id, PCI_MAP_REG_START, &io_port)) { 359 pcs->pci_st = IO_SPACE_MAPPING; 360 pcs->pci_sh = io_port; 361 mapped++; 362 } 363 } 364 if (mapped == 0 && (data & PCI_COMMAND_MEM_ENABLE)) { 365 if (pci_map_mem(config_id, MEM_MAP_REG, &vaddr, &paddr)) { 366 pcs->pci_st = MEM_SPACE_MAPPING; 367 pcs->pci_sh = vaddr; 368 mapped++; 369 } 370 } 371 #endif 372 if (mapped == 0) { 373 printf("isp%d: unable to map any ports!\n", unit); 374 free(pcs, M_DEVBUF); 375 return; 376 } 377 printf("isp%d: using %s space register mapping\n", unit, 378 pcs->pci_st == IO_SPACE_MAPPING? "I/O" : "Memory"); 379 380 isp = &pcs->pci_isp; 381 #if __FreeBSD_version >= 300006 382 (void) snprintf(isp->isp_name, sizeof (isp->isp_name), "isp%d", unit); 383 #else 384 (void) sprintf(isp->isp_name, "isp%d", unit); 385 #endif 386 isp->isp_osinfo.unit = unit; 387 388 data = pci_conf_read(config_id, PCI_ID_REG); 389 pcs->pci_poff[BIU_BLOCK >> _BLK_REG_SHFT] = BIU_REGS_OFF; 390 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = PCI_MBOX_REGS_OFF; 391 pcs->pci_poff[SXP_BLOCK >> _BLK_REG_SHFT] = PCI_SXP_REGS_OFF; 392 pcs->pci_poff[RISC_BLOCK >> _BLK_REG_SHFT] = PCI_RISC_REGS_OFF; 393 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = DMA_REGS_OFF; 394 #ifndef ISP_DISABLE_1020_SUPPORT 395 if (data == PCI_QLOGIC_ISP) { 396 isp->isp_mdvec = &mdvec; 397 isp->isp_type = ISP_HA_SCSI_UNKNOWN; 398 isp->isp_param = &pcs->_z._x; 399 } 400 #endif 401 #ifndef ISP_DISABLE_1080_SUPPORT 402 if (data == PCI_QLOGIC_ISP1080 || data == PCI_QLOGIC_ISP1240) { 403 isp->isp_mdvec = &mdvec_1080; 404 isp->isp_type = ISP_HA_SCSI_1080; 405 isp->isp_param = &pcs->_z._x; 406 pcs->pci_poff[DMA_BLOCK >> _BLK_REG_SHFT] = 407 ISP1080_DMA_REGS_OFF; 408 } 409 #endif 410 #ifndef ISP_DISABLE_2100_SUPPORT 411 if (data == PCI_QLOGIC_ISP2100) { 412 isp->isp_mdvec = &mdvec_2100; 413 isp->isp_type = ISP_HA_FC_2100; 414 isp->isp_param = &pcs->_z._y; 415 pcs->pci_poff[MBOX_BLOCK >> _BLK_REG_SHFT] = 416 PCI_MBOX_REGS2100_OFF; 417 418 data = pci_conf_read(config_id, PCI_CLASS_REG); 419 if ((data & 0xff) < 3) { 420 /* 421 * XXX: Need to get the actual revision 422 * XXX: number of the 2100 FB. At any rate, 423 * XXX: lower cache line size for early revision 424 * XXX; boards. 425 */ 426 linesz = 1; 427 } 428 } 429 #endif 430 431 #if __FreeBSD_version >= 300004 432 ISP_LOCK(isp); 433 434 /* 435 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER 436 * are set. 437 */ 438 data = pci_cfgread(config_id, PCIR_COMMAND, 2); 439 data |= PCIM_CMD_SEREN | 440 PCIM_CMD_PERRESPEN | 441 PCIM_CMD_BUSMASTEREN | 442 PCIM_CMD_INVEN; 443 pci_cfgwrite(config_id, PCIR_COMMAND, 2, data); 444 445 /* 446 * Make sure the CACHE Line Size register is set sensibly. 447 */ 448 data = pci_cfgread(config_id, PCIR_CACHELNSZ, 1); 449 if (data != linesz) { 450 data = PCI_DFLT_LNSZ; 451 printf("%s: set PCI line size to %d\n", isp->isp_name, data); 452 pci_cfgwrite(config_id, PCIR_CACHELNSZ, data, 1); 453 } 454 455 /* 456 * Make sure the Latency Timer is sane. 457 */ 458 data = pci_cfgread(config_id, PCIR_LATTIMER, 1); 459 if (data < PCI_DFLT_LTNCY) { 460 data = PCI_DFLT_LTNCY; 461 printf("%s: set PCI latency to %d\n", isp->isp_name, data); 462 pci_cfgwrite(config_id, PCIR_LATTIMER, data, 1); 463 } 464 465 /* 466 * Make sure we've disabled the ROM. 467 */ 468 data = pci_cfgread(config_id, PCIR_ROMADDR, 4); 469 data &= ~1; 470 pci_cfgwrite(config_id, PCIR_ROMADDR, data, 4); 471 472 ISP_UNLOCK(isp); 473 474 if (bus_dma_tag_create(NULL, 0, 0, BUS_SPACE_MAXADDR_32BIT, 475 BUS_SPACE_MAXADDR, NULL, NULL, 1<<24, 476 255, 1<<24, 0, &pcs->parent_dmat) != 0) { 477 printf("%s: could not create master dma tag\n", isp->isp_name); 478 free(pcs, M_DEVBUF); 479 return; 480 } 481 #else 482 ISP_LOCK(isp); 483 data = pci_conf_read(config_id, PCIR_COMMAND); 484 data |= PCIM_CMD_SEREN | 485 PCIM_CMD_PERRESPEN | 486 PCIM_CMD_BUSMASTEREN | 487 PCIM_CMD_INVEN; 488 pci_conf_write(config_id, PCIR_COMMAND, data); 489 data = pci_conf_read(config_id, PCIR_CACHELNSZ); 490 if ((data & ~0xffff) != ((PCI_DFLT_LTNCY << 8) | linesz)) { 491 data &= ~0xffff; 492 data |= (PCI_DFLT_LTNCY << 8) | linesz; 493 pci_conf_write(config_id, PCIR_CACHELNSZ, data); 494 printf("%s: set PCI line size to %d\n", isp->isp_name, linesz); 495 printf("%s: set PCI latency to %d\n", isp->isp_name, 496 PCI_DFLT_LTNCY); 497 } 498 499 /* 500 * Make sure we've disabled the ROM. 501 */ 502 data = pci_conf_read(config_id, PCIR_ROMADDR); 503 data &= ~1; 504 pci_conf_write(config_id, PCIR_ROMADDR, data); 505 ISP_UNLOCK(isp); 506 #endif 507 if (pci_map_int(config_id, (void (*)(void *))isp_intr, 508 (void *)isp, &IMASK) == 0) { 509 printf("%s: could not map interrupt\n", isp->isp_name); 510 free(pcs, M_DEVBUF); 511 return; 512 } 513 514 pcs->pci_id = config_id; 515 #ifdef SCSI_ISP_NO_FWLOAD_MASK 516 if (SCSI_ISP_NO_FWLOAD_MASK && (SCSI_ISP_NO_FWLOAD_MASK & (1 << unit))) 517 isp->isp_confopts |= ISP_CFG_NORELOAD; 518 #endif 519 #ifdef SCSI_ISP_NO_NVRAM_MASK 520 if (SCSI_ISP_NO_NVRAM_MASK && (SCSI_ISP_NO_NVRAM_MASK & (1 << unit))) { 521 printf("%s: ignoring NVRAM\n", isp->isp_name); 522 isp->isp_confopts |= ISP_CFG_NONVRAM; 523 } 524 #endif 525 ISP_LOCK(isp); 526 isp_reset(isp); 527 if (isp->isp_state != ISP_RESETSTATE) { 528 ISP_UNLOCK(isp); 529 free(pcs, M_DEVBUF); 530 return; 531 } 532 isp_init(isp); 533 if (isp->isp_state != ISP_INITSTATE) { 534 /* If we're a Fibre Channel Card, we allow deferred attach */ 535 if (isp->isp_type & ISP_HA_SCSI) { 536 isp_uninit(isp); 537 free(pcs, M_DEVBUF); 538 } 539 } 540 isp_attach(isp); 541 if (isp->isp_state != ISP_RUNSTATE) { 542 /* If we're a Fibre Channel Card, we allow deferred attach */ 543 if (IS_SCSI(isp)) { 544 isp_uninit(isp); 545 free(pcs, M_DEVBUF); 546 } 547 } 548 ISP_UNLOCK(isp); 549 #ifdef __alpha__ 550 /* 551 * THIS SHOULD NOT HAVE TO BE HERE 552 */ 553 alpha_register_pci_scsi(config_id->bus, config_id->slot, isp->isp_sim); 554 #endif 555 } 556 557 static u_int16_t 558 isp_pci_rd_reg(isp, regoff) 559 struct ispsoftc *isp; 560 int regoff; 561 { 562 u_int16_t rv; 563 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 564 int offset, oldconf = 0; 565 566 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 567 /* 568 * We will assume that someone has paused the RISC processor. 569 */ 570 oldconf = isp_pci_rd_reg(isp, BIU_CONF1); 571 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP); 572 } 573 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 574 offset += (regoff & 0xff); 575 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset); 576 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 577 isp_pci_wr_reg(isp, BIU_CONF1, oldconf); 578 } 579 return (rv); 580 } 581 582 static void 583 isp_pci_wr_reg(isp, regoff, val) 584 struct ispsoftc *isp; 585 int regoff; 586 u_int16_t val; 587 { 588 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 589 int offset, oldconf = 0; 590 591 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 592 /* 593 * We will assume that someone has paused the RISC processor. 594 */ 595 oldconf = isp_pci_rd_reg(isp, BIU_CONF1); 596 isp_pci_wr_reg(isp, BIU_CONF1, oldconf | BIU_PCI_CONF1_SXP); 597 } 598 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 599 offset += (regoff & 0xff); 600 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val); 601 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 602 isp_pci_wr_reg(isp, BIU_CONF1, oldconf); 603 } 604 } 605 606 #ifndef ISP_DISABLE_1080_SUPPORT 607 static u_int16_t 608 isp_pci_rd_reg_1080(isp, regoff) 609 struct ispsoftc *isp; 610 int regoff; 611 { 612 u_int16_t rv; 613 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 614 int offset, oc = 0; 615 616 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 617 /* 618 * We will assume that someone has paused the RISC processor. 619 */ 620 oc = isp_pci_rd_reg(isp, BIU_CONF1); 621 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP); 622 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) { 623 oc = isp_pci_rd_reg(isp, BIU_CONF1); 624 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA); 625 } 626 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 627 offset += (regoff & 0xff); 628 rv = bus_space_read_2(pcs->pci_st, pcs->pci_sh, offset); 629 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK || 630 ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) { 631 isp_pci_wr_reg(isp, BIU_CONF1, oc); 632 } 633 return (rv); 634 } 635 636 static void 637 isp_pci_wr_reg_1080(isp, regoff, val) 638 struct ispsoftc *isp; 639 int regoff; 640 u_int16_t val; 641 { 642 struct isp_pcisoftc *pcs = (struct isp_pcisoftc *) isp; 643 int offset, oc = 0; 644 645 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK) { 646 /* 647 * We will assume that someone has paused the RISC processor. 648 */ 649 oc = isp_pci_rd_reg(isp, BIU_CONF1); 650 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_SXP); 651 } else if ((regoff & _BLK_REG_MASK) == DMA_BLOCK) { 652 oc = isp_pci_rd_reg(isp, BIU_CONF1); 653 isp_pci_wr_reg(isp, BIU_CONF1, oc | BIU_PCI1080_CONF1_DMA); 654 } 655 offset = pcs->pci_poff[(regoff & _BLK_REG_MASK) >> _BLK_REG_SHFT]; 656 offset += (regoff & 0xff); 657 bus_space_write_2(pcs->pci_st, pcs->pci_sh, offset, val); 658 if ((regoff & _BLK_REG_MASK) == SXP_BLOCK || 659 ((regoff & _BLK_REG_MASK) == DMA_BLOCK)) { 660 isp_pci_wr_reg(isp, BIU_CONF1, oc); 661 } 662 } 663 #endif 664 665 666 #if __FreeBSD_version >= 300004 667 static void isp_map_rquest __P((void *, bus_dma_segment_t *, int, int)); 668 static void isp_map_result __P((void *, bus_dma_segment_t *, int, int)); 669 static void isp_map_fcscrt __P((void *, bus_dma_segment_t *, int, int)); 670 671 static void 672 isp_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error) 673 { 674 struct ispsoftc *isp = (struct ispsoftc *) arg; 675 isp->isp_rquest_dma = segs->ds_addr; 676 } 677 678 static void 679 isp_map_result(void *arg, bus_dma_segment_t *segs, int nseg, int error) 680 { 681 struct ispsoftc *isp = (struct ispsoftc *) arg; 682 isp->isp_result_dma = segs->ds_addr; 683 } 684 685 static void 686 isp_map_fcscrt(void *arg, bus_dma_segment_t *segs, int nseg, int error) 687 { 688 struct ispsoftc *isp = (struct ispsoftc *) arg; 689 fcparam *fcp = isp->isp_param; 690 fcp->isp_scdma = segs->ds_addr; 691 } 692 693 static int 694 isp_pci_mbxdma(struct ispsoftc *isp) 695 { 696 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 697 caddr_t base; 698 u_int32_t len; 699 int i, error; 700 701 /* 702 * Allocate and map the request, result queues, plus FC scratch area. 703 */ 704 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN); 705 len += ISP_QUEUE_SIZE(RESULT_QUEUE_LEN); 706 if (isp->isp_type & ISP_HA_FC) { 707 len += ISP2100_SCRLEN; 708 } 709 if (bus_dma_tag_create(pci->parent_dmat, 0, 0, BUS_SPACE_MAXADDR, 710 BUS_SPACE_MAXADDR, NULL, NULL, len, 1, BUS_SPACE_MAXSIZE_32BIT, 711 0, &pci->cntrol_dmat) != 0) { 712 printf("%s: cannot create a dma tag for control spaces\n", 713 isp->isp_name); 714 return (1); 715 } 716 if (bus_dmamem_alloc(pci->cntrol_dmat, (void **)&base, 717 BUS_DMA_NOWAIT, &pci->cntrol_dmap) != 0) { 718 printf("%s: cannot allocate %d bytes of CCB memory\n", 719 isp->isp_name, len); 720 return (1); 721 } 722 723 isp->isp_rquest = base; 724 bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_rquest, 725 ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN), isp_map_rquest, pci, 0); 726 727 isp->isp_result = base + ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN); 728 bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, isp->isp_result, 729 ISP_QUEUE_SIZE(RESULT_QUEUE_LEN), isp_map_result, pci, 0); 730 731 /* 732 * Use this opportunity to initialize/create data DMA maps. 733 */ 734 for (i = 0; i < MAXISPREQUEST; i++) { 735 error = bus_dmamap_create(pci->parent_dmat, 0, &pci->dmaps[i]); 736 if (error) { 737 printf("%s: error %d creating mailbox DMA maps\n", 738 isp->isp_name, error); 739 return (1); 740 } 741 } 742 743 if (isp->isp_type & ISP_HA_FC) { 744 fcparam *fcp = (fcparam *) isp->isp_param; 745 fcp->isp_scratch = base + 746 ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN) + 747 ISP_QUEUE_SIZE(RESULT_QUEUE_LEN); 748 bus_dmamap_load(pci->cntrol_dmat, pci->cntrol_dmap, 749 fcp->isp_scratch, ISP2100_SCRLEN, isp_map_fcscrt, pci, 0); 750 } 751 return (0); 752 } 753 754 static void dma2 __P((void *, bus_dma_segment_t *, int, int)); 755 typedef struct { 756 struct ispsoftc *isp; 757 ISP_SCSI_XFER_T *ccb; 758 ispreq_t *rq; 759 u_int8_t *iptrp; 760 u_int8_t optr; 761 u_int error; 762 } mush_t; 763 764 #define MUSHERR_NOQENTRIES -2 765 766 static void 767 dma2(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) 768 { 769 mush_t *mp; 770 ISP_SCSI_XFER_T *ccb; 771 struct ispsoftc *isp; 772 struct isp_pcisoftc *pci; 773 bus_dmamap_t *dp; 774 bus_dma_segment_t *eseg; 775 ispreq_t *rq; 776 u_int8_t *iptrp; 777 u_int8_t optr; 778 ispcontreq_t *crq; 779 int drq, seglim, datalen; 780 781 mp = (mush_t *) arg; 782 if (error) { 783 mp->error = error; 784 return; 785 } 786 787 isp = mp->isp; 788 if (nseg < 1) { 789 printf("%s: zero or negative segment count\n", isp->isp_name); 790 mp->error = EFAULT; 791 return; 792 } 793 ccb = mp->ccb; 794 rq = mp->rq; 795 iptrp = mp->iptrp; 796 optr = mp->optr; 797 798 pci = (struct isp_pcisoftc *)isp; 799 dp = &pci->dmaps[rq->req_handle - 1]; 800 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 801 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREREAD); 802 drq = REQFLAG_DATA_IN; 803 } else { 804 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_PREWRITE); 805 drq = REQFLAG_DATA_OUT; 806 } 807 808 datalen = XS_XFRLEN(ccb); 809 if (isp->isp_type & ISP_HA_FC) { 810 seglim = ISP_RQDSEG_T2; 811 ((ispreqt2_t *)rq)->req_totalcnt = datalen; 812 ((ispreqt2_t *)rq)->req_flags |= drq; 813 } else { 814 seglim = ISP_RQDSEG; 815 rq->req_flags |= drq; 816 } 817 818 eseg = dm_segs + nseg; 819 820 while (datalen != 0 && rq->req_seg_count < seglim && dm_segs != eseg) { 821 if (isp->isp_type & ISP_HA_FC) { 822 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 823 rq2->req_dataseg[rq2->req_seg_count].ds_base = 824 dm_segs->ds_addr; 825 rq2->req_dataseg[rq2->req_seg_count].ds_count = 826 dm_segs->ds_len; 827 } else { 828 rq->req_dataseg[rq->req_seg_count].ds_base = 829 dm_segs->ds_addr; 830 rq->req_dataseg[rq->req_seg_count].ds_count = 831 dm_segs->ds_len; 832 } 833 datalen -= dm_segs->ds_len; 834 #if 0 835 if (isp->isp_type & ISP_HA_FC) { 836 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 837 printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n", 838 isp->isp_name, rq->req_seg_count, 839 rq2->req_dataseg[rq2->req_seg_count].ds_count, 840 rq2->req_dataseg[rq2->req_seg_count].ds_base); 841 } else { 842 printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n", 843 isp->isp_name, rq->req_seg_count, 844 rq->req_dataseg[rq->req_seg_count].ds_count, 845 rq->req_dataseg[rq->req_seg_count].ds_base); 846 } 847 #endif 848 rq->req_seg_count++; 849 dm_segs++; 850 } 851 852 while (datalen > 0 && dm_segs != eseg) { 853 crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp); 854 *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN); 855 if (*iptrp == optr) { 856 #if 0 857 printf("%s: Request Queue Overflow++\n", isp->isp_name); 858 #endif 859 mp->error = MUSHERR_NOQENTRIES; 860 return; 861 } 862 rq->req_header.rqs_entry_count++; 863 bzero((void *)crq, sizeof (*crq)); 864 crq->req_header.rqs_entry_count = 1; 865 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG; 866 867 seglim = 0; 868 while (datalen > 0 && seglim < ISP_CDSEG && dm_segs != eseg) { 869 crq->req_dataseg[seglim].ds_base = 870 dm_segs->ds_addr; 871 crq->req_dataseg[seglim].ds_count = 872 dm_segs->ds_len; 873 #if 0 874 printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n", 875 isp->isp_name, rq->req_header.rqs_entry_count-1, 876 seglim, crq->req_dataseg[seglim].ds_count, 877 crq->req_dataseg[seglim].ds_base); 878 #endif 879 rq->req_seg_count++; 880 dm_segs++; 881 seglim++; 882 datalen -= dm_segs->ds_len; 883 } 884 } 885 } 886 887 static int 888 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, ispreq_t *rq, 889 u_int8_t *iptrp, u_int8_t optr) 890 { 891 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 892 struct ccb_hdr *ccb_h; 893 struct ccb_scsiio *csio; 894 bus_dmamap_t *dp; 895 mush_t mush, *mp; 896 897 csio = (struct ccb_scsiio *) ccb; 898 ccb_h = &csio->ccb_h; 899 900 if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE) { 901 rq->req_seg_count = 1; 902 return (CMD_QUEUED); 903 } 904 dp = &pci->dmaps[rq->req_handle - 1]; 905 906 /* 907 * Do a virtual grapevine step to collect info for 908 * the callback dma allocation that we have to use... 909 */ 910 mp = &mush; 911 mp->isp = isp; 912 mp->ccb = ccb; 913 mp->rq = rq; 914 mp->iptrp = iptrp; 915 mp->optr = optr; 916 mp->error = 0; 917 918 if ((ccb_h->flags & CAM_SCATTER_VALID) == 0) { 919 if ((ccb_h->flags & CAM_DATA_PHYS) == 0) { 920 int error, s; 921 922 s = splsoftvm(); 923 error = bus_dmamap_load(pci->parent_dmat, *dp, 924 csio->data_ptr, csio->dxfer_len, dma2, mp, 0); 925 if (error == EINPROGRESS) { 926 bus_dmamap_unload(pci->parent_dmat, *dp); 927 mp->error = EINVAL; 928 printf("%s: deferred dma allocation not " 929 "supported\n", isp->isp_name); 930 } else if (error && mp->error == 0) { 931 mp->error = error; 932 } 933 splx(s); 934 } else { 935 /* Pointer to physical buffer */ 936 struct bus_dma_segment seg; 937 seg.ds_addr = (bus_addr_t)csio->data_ptr; 938 seg.ds_len = csio->dxfer_len; 939 dma2(mp, &seg, 1, 0); 940 } 941 } else { 942 struct bus_dma_segment *segs; 943 944 if ((ccb_h->flags & CAM_DATA_PHYS) != 0) { 945 printf("%s: Physical segment pointers unsupported", 946 isp->isp_name); 947 mp->error = EINVAL; 948 } else if ((ccb_h->flags & CAM_SG_LIST_PHYS) == 0) { 949 printf("%s: Virtual segment addresses unsupported", 950 isp->isp_name); 951 mp->error = EINVAL; 952 } else { 953 /* Just use the segments provided */ 954 segs = (struct bus_dma_segment *) csio->data_ptr; 955 dma2(mp, segs, csio->sglist_cnt, 0); 956 } 957 } 958 if (mp->error) { 959 int retval = CMD_COMPLETE; 960 if (mp->error == MUSHERR_NOQENTRIES) { 961 retval = CMD_EAGAIN; 962 ccb_h->status = CAM_UNREC_HBA_ERROR; 963 } else if (mp->error == EFBIG) { 964 ccb_h->status = CAM_REQ_TOO_BIG; 965 } else if (mp->error == EINVAL) { 966 ccb_h->status = CAM_REQ_INVALID; 967 } else { 968 ccb_h->status = CAM_UNREC_HBA_ERROR; 969 } 970 return (retval); 971 } else { 972 return (CMD_QUEUED); 973 } 974 } 975 976 static void 977 isp_pci_dmateardown(struct ispsoftc *isp, ISP_SCSI_XFER_T *ccb, 978 u_int32_t handle) 979 { 980 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 981 bus_dmamap_t *dp = &pci->dmaps[handle]; 982 983 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 984 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTREAD); 985 } else { 986 bus_dmamap_sync(pci->parent_dmat, *dp, BUS_DMASYNC_POSTWRITE); 987 } 988 bus_dmamap_unload(pci->parent_dmat, *dp); 989 } 990 991 #else /* __FreeBSD_version >= 300004 */ 992 993 994 static int 995 isp_pci_mbxdma(struct ispsoftc *isp) 996 { 997 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 998 u_int32_t len; 999 int rseg; 1000 1001 /* XXXX CHECK FOR ALIGNMENT */ 1002 /* 1003 * Allocate and map the request queue. 1004 */ 1005 len = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN); 1006 isp->isp_rquest = malloc(len, M_DEVBUF, M_NOWAIT); 1007 if (isp->isp_rquest == NULL) { 1008 printf("%s: cannot malloc request queue\n", isp->isp_name); 1009 return (1); 1010 } 1011 isp->isp_rquest_dma = vtophys(isp->isp_rquest); 1012 1013 #if 0 1014 printf("RQUEST=0x%x (0x%x)...", isp->isp_rquest, isp->isp_rquest_dma); 1015 #endif 1016 1017 /* 1018 * Allocate and map the result queue. 1019 */ 1020 len = ISP_QUEUE_SIZE(RESULT_QUEUE_LEN); 1021 isp->isp_result = malloc(len, M_DEVBUF, M_NOWAIT); 1022 if (isp->isp_result == NULL) { 1023 free(isp->isp_rquest, M_DEVBUF); 1024 printf("%s: cannot malloc result queue\n", isp->isp_name); 1025 return (1); 1026 } 1027 isp->isp_result_dma = vtophys(isp->isp_result); 1028 #if 0 1029 printf("RESULT=0x%x (0x%x)\n", isp->isp_result, isp->isp_result_dma); 1030 #endif 1031 if (isp->isp_type & ISP_HA_FC) { 1032 fcparam *fcp = isp->isp_param; 1033 len = ISP2100_SCRLEN; 1034 fcp->isp_scratch = (volatile caddr_t) 1035 malloc(ISP2100_SCRLEN, M_DEVBUF, M_NOWAIT); 1036 if (fcp->isp_scratch == NULL) { 1037 printf("%s: cannot alloc scratch\n", isp->isp_name); 1038 return (1); 1039 } 1040 fcp->isp_scdma = vtophys(fcp->isp_scratch); 1041 } 1042 return (0); 1043 } 1044 1045 static int 1046 isp_pci_dmasetup(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs, 1047 ispreq_t *rq, u_int8_t *iptrp, u_int8_t optr) 1048 { 1049 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 1050 ispcontreq_t *crq; 1051 vm_offset_t vaddr; 1052 int drq, seglim; 1053 u_int32_t paddr, nextpaddr, datalen, size, *ctrp; 1054 1055 if (xs->datalen == 0) { 1056 rq->req_seg_count = 1; 1057 return (CMD_QUEUED); 1058 } 1059 1060 if (xs->flags & SCSI_DATA_IN) { 1061 drq = REQFLAG_DATA_IN; 1062 } else { 1063 drq = REQFLAG_DATA_OUT; 1064 } 1065 1066 if (isp->isp_type & ISP_HA_FC) { 1067 seglim = ISP_RQDSEG_T2; 1068 ((ispreqt2_t *)rq)->req_totalcnt = XS_XFRLEN(xs); 1069 ((ispreqt2_t *)rq)->req_flags |= drq; 1070 } else { 1071 seglim = ISP_RQDSEG; 1072 rq->req_flags |= drq; 1073 } 1074 1075 datalen = XS_XFRLEN(xs); 1076 vaddr = (vm_offset_t) xs->data; 1077 paddr = vtophys(vaddr); 1078 1079 while (datalen != 0 && rq->req_seg_count < seglim) { 1080 if (isp->isp_type & ISP_HA_FC) { 1081 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 1082 rq2->req_dataseg[rq2->req_seg_count].ds_base = paddr; 1083 ctrp = &rq2->req_dataseg[rq2->req_seg_count].ds_count; 1084 } else { 1085 rq->req_dataseg[rq->req_seg_count].ds_base = paddr; 1086 ctrp = &rq->req_dataseg[rq->req_seg_count].ds_count; 1087 } 1088 nextpaddr = paddr; 1089 *(ctrp) = 0; 1090 1091 while (datalen != 0 && paddr == nextpaddr) { 1092 nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE; 1093 size = nextpaddr - paddr; 1094 if (size > datalen) 1095 size = datalen; 1096 *(ctrp) += size; 1097 vaddr += size; 1098 datalen -= size; 1099 if (datalen != 0) 1100 paddr = vtophys(vaddr); 1101 1102 } 1103 #if 0 1104 if (isp->isp_type & ISP_HA_FC) { 1105 ispreqt2_t *rq2 = (ispreqt2_t *)rq; 1106 printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n", 1107 isp->isp_name, rq->req_seg_count, 1108 rq2->req_dataseg[rq2->req_seg_count].ds_count, 1109 rq2->req_dataseg[rq2->req_seg_count].ds_base); 1110 } else { 1111 printf("%s: seg0[%d] cnt 0x%x paddr 0x%08x\n", 1112 isp->isp_name, rq->req_seg_count, 1113 rq->req_dataseg[rq->req_seg_count].ds_count, 1114 rq->req_dataseg[rq->req_seg_count].ds_base); 1115 } 1116 #endif 1117 rq->req_seg_count++; 1118 } 1119 1120 1121 1122 if (datalen == 0) 1123 return (CMD_QUEUED); 1124 1125 paddr = vtophys(vaddr); 1126 while (datalen > 0) { 1127 crq = (ispcontreq_t *) ISP_QUEUE_ENTRY(isp->isp_rquest, *iptrp); 1128 *iptrp = ISP_NXT_QENTRY(*iptrp, RQUEST_QUEUE_LEN); 1129 if (*iptrp == optr) { 1130 printf("%s: Request Queue Overflow\n", isp->isp_name); 1131 XS_SETERR(xs, HBA_BOTCH); 1132 return (CMD_EAGAIN); 1133 } 1134 rq->req_header.rqs_entry_count++; 1135 bzero((void *)crq, sizeof (*crq)); 1136 crq->req_header.rqs_entry_count = 1; 1137 crq->req_header.rqs_entry_type = RQSTYPE_DATASEG; 1138 1139 for (seglim = 0; datalen != 0 && seglim < ISP_CDSEG; seglim++) { 1140 crq->req_dataseg[seglim].ds_base = paddr; 1141 ctrp = &crq->req_dataseg[seglim].ds_count; 1142 *(ctrp) = 0; 1143 nextpaddr = paddr; 1144 while (datalen != 0 && paddr == nextpaddr) { 1145 nextpaddr = (paddr & (~PAGE_MASK)) + PAGE_SIZE; 1146 size = nextpaddr - paddr; 1147 if (size > datalen) 1148 size = datalen; 1149 *(ctrp) += size; 1150 vaddr += size; 1151 datalen -= size; 1152 if (datalen != 0) 1153 paddr = vtophys(vaddr); 1154 } 1155 #if 0 1156 printf("%s: seg%d[%d] cnt 0x%x paddr 0x%08x\n", 1157 isp->isp_name, rq->req_header.rqs_entry_count-1, 1158 seglim, crq->req_dataseg[seglim].ds_count, 1159 crq->req_dataseg[seglim].ds_base); 1160 #endif 1161 rq->req_seg_count++; 1162 } 1163 } 1164 1165 return (CMD_QUEUED); 1166 } 1167 #endif 1168 1169 static void 1170 isp_pci_reset1(struct ispsoftc *isp) 1171 { 1172 /* Make sure the BIOS is disabled */ 1173 isp_pci_wr_reg(isp, HCCR, PCI_HCCR_CMD_BIOS); 1174 } 1175 1176 static void 1177 isp_pci_dumpregs(struct ispsoftc *isp) 1178 { 1179 struct isp_pcisoftc *pci = (struct isp_pcisoftc *)isp; 1180 printf("%s: PCI Status Command/Status=%lx\n", pci->pci_isp.isp_name, 1181 pci_conf_read(pci->pci_id, PCIR_COMMAND)); 1182 } 1183