1 /*- 2 * PCI specific probe and attach routines for LSI Fusion Adapters 3 * FreeBSD Version. 4 * 5 * Copyright (c) 2000, 2001 by Greg Ansley 6 * Partially derived from Matt Jacob's ISP driver. 7 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 by Matthew Jacob 8 * Feral Software 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice immediately at the beginning of the file, without modification, 16 * this list of conditions, and the following disclaimer. 17 * 2. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/module.h> 40 #include <sys/bus.h> 41 42 #include <dev/pci/pcireg.h> 43 #include <dev/pci/pcivar.h> 44 45 #include <machine/bus_memio.h> 46 #include <machine/bus_pio.h> 47 #include <machine/bus.h> 48 #include <machine/resource.h> 49 #include <sys/rman.h> 50 #include <sys/malloc.h> 51 52 #include <dev/mpt/mpt_freebsd.h> 53 54 #ifndef PCI_VENDOR_LSI 55 #define PCI_VENDOR_LSI 0x1000 56 #endif 57 58 #ifndef PCI_PRODUCT_LSI_FC909 59 #define PCI_PRODUCT_LSI_FC909 0x0620 60 #endif 61 62 #ifndef PCI_PRODUCT_LSI_FC909A 63 #define PCI_PRODUCT_LSI_FC909A 0x0621 64 #endif 65 66 #ifndef PCI_PRODUCT_LSI_FC919 67 #define PCI_PRODUCT_LSI_FC919 0x0624 68 #endif 69 70 #ifndef PCI_PRODUCT_LSI_FC929 71 #define PCI_PRODUCT_LSI_FC929 0x0622 72 #endif 73 74 #ifndef PCI_PRODUCT_LSI_FC929X 75 #define PCI_PRODUCT_LSI_FC929X 0x0626 76 #endif 77 78 #ifndef PCI_PRODUCT_LSI_1030 79 #define PCI_PRODUCT_LSI_1030 0x0030 80 #endif 81 82 #ifndef PCIM_CMD_SERRESPEN 83 #define PCIM_CMD_SERRESPEN 0x0100 84 #endif 85 86 87 88 #define MEM_MAP_REG 0x14 89 #define MEM_MAP_SRAM 0x1C 90 91 static int mpt_probe(device_t); 92 static int mpt_attach(device_t); 93 static void mpt_free_bus_resources(mpt_softc_t *mpt); 94 static int mpt_detach(device_t); 95 static int mpt_shutdown(device_t); 96 static int mpt_dma_mem_alloc(mpt_softc_t *mpt); 97 static void mpt_dma_mem_free(mpt_softc_t *mpt); 98 static void mpt_read_config_regs(mpt_softc_t *mpt); 99 static void mpt_pci_intr(void *); 100 101 static device_method_t mpt_methods[] = { 102 /* Device interface */ 103 DEVMETHOD(device_probe, mpt_probe), 104 DEVMETHOD(device_attach, mpt_attach), 105 DEVMETHOD(device_detach, mpt_detach), 106 DEVMETHOD(device_shutdown, mpt_shutdown), 107 { 0, 0 } 108 }; 109 110 static driver_t mpt_driver = { 111 "mpt", mpt_methods, sizeof (mpt_softc_t) 112 }; 113 static devclass_t mpt_devclass; 114 DRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0); 115 MODULE_VERSION(mpt, 1); 116 117 int 118 mpt_intr(void *dummy) 119 { 120 int nrepl = 0; 121 u_int32_t reply; 122 mpt_softc_t *mpt = (mpt_softc_t *)dummy; 123 124 if ((mpt_read(mpt, MPT_OFFSET_INTR_STATUS) & MPT_INTR_REPLY_READY) == 0) 125 return (0); 126 reply = mpt_pop_reply_queue(mpt); 127 while (reply != MPT_REPLY_EMPTY) { 128 nrepl++; 129 if (mpt->verbose > 1) { 130 if ((reply & MPT_CONTEXT_REPLY) != 0) { 131 /* Address reply; IOC has something to say */ 132 mpt_print_reply(MPT_REPLY_PTOV(mpt, reply)); 133 } else { 134 /* Context reply ; all went well */ 135 mpt_prt(mpt, "context %u reply OK", reply); 136 } 137 } 138 mpt_done(mpt, reply); 139 reply = mpt_pop_reply_queue(mpt); 140 } 141 return (nrepl != 0); 142 } 143 144 static int 145 mpt_probe(device_t dev) 146 { 147 char *desc; 148 149 if (pci_get_vendor(dev) != PCI_VENDOR_LSI) 150 return (ENXIO); 151 152 switch ((pci_get_device(dev) & ~1)) { 153 case PCI_PRODUCT_LSI_FC909: 154 desc = "LSILogic FC909 FC Adapter"; 155 break; 156 case PCI_PRODUCT_LSI_FC909A: 157 desc = "LSILogic FC909A FC Adapter"; 158 break; 159 case PCI_PRODUCT_LSI_FC919: 160 desc = "LSILogic FC919 FC Adapter"; 161 break; 162 case PCI_PRODUCT_LSI_FC929: 163 desc = "LSILogic FC929 FC Adapter"; 164 break; 165 case PCI_PRODUCT_LSI_FC929X: 166 desc = "LSILogic FC929X FC Adapter"; 167 break; 168 case PCI_PRODUCT_LSI_1030: 169 desc = "LSILogic 1030 Ultra4 Adapter"; 170 break; 171 default: 172 return (ENXIO); 173 } 174 175 device_set_desc(dev, desc); 176 return (0); 177 } 178 179 #ifdef RELENG_4 180 static void 181 mpt_set_options(mpt_softc_t *mpt) 182 { 183 int bitmap; 184 185 bitmap = 0; 186 if (getenv_int("mpt_disable", &bitmap)) { 187 if (bitmap & (1 << mpt->unit)) { 188 mpt->disabled = 1; 189 } 190 } 191 192 bitmap = 0; 193 if (getenv_int("mpt_debug", &bitmap)) { 194 if (bitmap & (1 << mpt->unit)) { 195 mpt->verbose = 2; 196 } 197 } 198 199 } 200 #else 201 static void 202 mpt_set_options(mpt_softc_t *mpt) 203 { 204 int tval; 205 206 tval = 0; 207 if (resource_int_value(device_get_name(mpt->dev), 208 device_get_unit(mpt->dev), "disable", &tval) == 0 && tval != 0) { 209 mpt->disabled = 1; 210 } 211 tval = 0; 212 if (resource_int_value(device_get_name(mpt->dev), 213 device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) { 214 mpt->verbose += tval; 215 } 216 } 217 #endif 218 219 220 static void 221 mpt_link_peer(mpt_softc_t *mpt) 222 { 223 mpt_softc_t *mpt2; 224 225 if (mpt->unit == 0) { 226 return; 227 } 228 229 /* 230 * XXX: depends on probe order 231 */ 232 mpt2 = (mpt_softc_t *) devclass_get_softc(mpt_devclass, mpt->unit-1); 233 234 if (mpt2 == NULL) { 235 return; 236 } 237 if (pci_get_vendor(mpt2->dev) != pci_get_vendor(mpt->dev)) { 238 return; 239 } 240 if (pci_get_device(mpt2->dev) != pci_get_device(mpt->dev)) { 241 return; 242 } 243 mpt->mpt2 = mpt2; 244 mpt2->mpt2 = mpt; 245 if (mpt->verbose) { 246 mpt_prt(mpt, "linking with peer (mpt%d)", 247 device_get_unit(mpt2->dev)); 248 } 249 } 250 251 252 static int 253 mpt_attach(device_t dev) 254 { 255 int iqd; 256 u_int32_t data, cmd; 257 mpt_softc_t *mpt; 258 259 /* Allocate the softc structure */ 260 mpt = (mpt_softc_t*) device_get_softc(dev); 261 if (mpt == NULL) { 262 device_printf(dev, "cannot allocate softc\n"); 263 return (ENOMEM); 264 } 265 bzero(mpt, sizeof (mpt_softc_t)); 266 switch ((pci_get_device(dev) & ~1)) { 267 case PCI_PRODUCT_LSI_FC909: 268 case PCI_PRODUCT_LSI_FC909A: 269 case PCI_PRODUCT_LSI_FC919: 270 case PCI_PRODUCT_LSI_FC929: 271 mpt->is_fc = 1; 272 break; 273 default: 274 break; 275 } 276 mpt->dev = dev; 277 mpt->unit = device_get_unit(dev); 278 mpt_set_options(mpt); 279 mpt->verbose += (bootverbose != 0)? 1 : 0; 280 281 /* Make sure memory access decoders are enabled */ 282 cmd = pci_read_config(dev, PCIR_COMMAND, 2); 283 if ((cmd & PCIM_CMD_MEMEN) == 0) { 284 device_printf(dev, "Memory accesses disabled"); 285 goto bad; 286 } 287 288 /* 289 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set. 290 */ 291 cmd |= 292 PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN | 293 PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN; 294 pci_write_config(dev, PCIR_COMMAND, cmd, 2); 295 296 /* 297 * Make sure we've disabled the ROM. 298 */ 299 data = pci_read_config(dev, PCIR_BIOS, 4); 300 data &= ~1; 301 pci_write_config(dev, PCIR_BIOS, data, 4); 302 303 304 /* 305 * Is this part a dual? 306 * If so, link with our partner (around yet) 307 */ 308 if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929 || 309 (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_1030) { 310 mpt_link_peer(mpt); 311 } 312 313 /* Set up the memory regions */ 314 /* Allocate kernel virtual memory for the 9x9's Mem0 region */ 315 mpt->pci_reg_id = MEM_MAP_REG; 316 mpt->pci_reg = bus_alloc_resource(dev, SYS_RES_MEMORY, 317 &mpt->pci_reg_id, 0, ~0, 0, RF_ACTIVE); 318 if (mpt->pci_reg == NULL) { 319 device_printf(dev, "unable to map any ports\n"); 320 goto bad; 321 } 322 mpt->pci_st = rman_get_bustag(mpt->pci_reg); 323 mpt->pci_sh = rman_get_bushandle(mpt->pci_reg); 324 /* Get the Physical Address */ 325 mpt->pci_pa = rman_get_start(mpt->pci_reg); 326 327 /* Get a handle to the interrupt */ 328 iqd = 0; 329 mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd, 330 RF_ACTIVE | RF_SHAREABLE); 331 if (mpt->pci_irq == NULL) { 332 device_printf(dev, "could not allocate interrupt\n"); 333 goto bad; 334 } 335 336 /* Register the interrupt handler */ 337 if (bus_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, mpt_pci_intr, 338 mpt, &mpt->ih)) { 339 device_printf(dev, "could not setup interrupt\n"); 340 goto bad; 341 } 342 343 MPT_LOCK_SETUP(mpt); 344 345 /* Disable interrupts at the part */ 346 mpt_disable_ints(mpt); 347 348 /* Allocate dma memory */ 349 if (mpt_dma_mem_alloc(mpt)) { 350 device_printf(dev, "Could not allocate DMA memory\n"); 351 goto bad; 352 } 353 354 /* 355 * Save the PCI config register values 356 * 357 * Hard resets are known to screw up the BAR for diagnostic 358 * memory accesses (Mem1). 359 * 360 * Using Mem1 is known to make the chip stop responding to 361 * configuration space transfers, so we need to save it now 362 */ 363 364 mpt_read_config_regs(mpt); 365 366 /* Initialize the hardware */ 367 if (mpt->disabled == 0) { 368 MPT_LOCK(mpt); 369 if (mpt_init(mpt, MPT_DB_INIT_HOST) != 0) { 370 MPT_UNLOCK(mpt); 371 goto bad; 372 } 373 374 /* 375 * Attach to CAM 376 */ 377 MPTLOCK_2_CAMLOCK(mpt); 378 mpt_cam_attach(mpt); 379 CAMLOCK_2_MPTLOCK(mpt); 380 MPT_UNLOCK(mpt); 381 } 382 383 return (0); 384 385 bad: 386 mpt_dma_mem_free(mpt); 387 mpt_free_bus_resources(mpt); 388 389 /* 390 * but return zero to preserve unit numbering 391 */ 392 return (0); 393 } 394 395 /* 396 * Free bus resources 397 */ 398 static void 399 mpt_free_bus_resources(mpt_softc_t *mpt) 400 { 401 if (mpt->ih) { 402 bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih); 403 mpt->ih = 0; 404 } 405 406 if (mpt->pci_irq) { 407 bus_release_resource(mpt->dev, SYS_RES_IRQ, 0, mpt->pci_irq); 408 mpt->pci_irq = 0; 409 } 410 411 if (mpt->pci_reg) { 412 bus_release_resource(mpt->dev, SYS_RES_MEMORY, mpt->pci_reg_id, 413 mpt->pci_reg); 414 mpt->pci_reg = 0; 415 } 416 MPT_LOCK_DESTROY(mpt); 417 } 418 419 420 /* 421 * Disconnect ourselves from the system. 422 */ 423 static int 424 mpt_detach(device_t dev) 425 { 426 mpt_softc_t *mpt; 427 mpt = (mpt_softc_t*) device_get_softc(dev); 428 429 mpt_prt(mpt, "mpt_detach"); 430 431 if (mpt) { 432 mpt_disable_ints(mpt); 433 mpt_cam_detach(mpt); 434 mpt_reset(mpt); 435 mpt_dma_mem_free(mpt); 436 mpt_free_bus_resources(mpt); 437 } 438 return(0); 439 } 440 441 442 /* 443 * Disable the hardware 444 */ 445 static int 446 mpt_shutdown(device_t dev) 447 { 448 mpt_softc_t *mpt; 449 mpt = (mpt_softc_t*) device_get_softc(dev); 450 451 if (mpt) { 452 mpt_reset(mpt); 453 } 454 return(0); 455 } 456 457 458 struct imush { 459 mpt_softc_t *mpt; 460 int error; 461 u_int32_t phys; 462 }; 463 464 static void 465 mpt_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error) 466 { 467 struct imush *imushp = (struct imush *) arg; 468 imushp->error = error; 469 imushp->phys = segs->ds_addr; 470 } 471 472 473 static int 474 mpt_dma_mem_alloc(mpt_softc_t *mpt) 475 { 476 int i, error; 477 u_char *vptr; 478 u_int32_t pptr, end; 479 size_t len; 480 struct imush im; 481 device_t dev = mpt->dev; 482 483 /* Check if we alreay have allocated the reply memory */ 484 if (mpt->reply_phys != 0) { 485 return 0; 486 } 487 488 len = sizeof (request_t *) * MPT_REQ_MEM_SIZE(mpt); 489 #ifdef RELENG_4 490 mpt->request_pool = (request_t *) malloc(len, M_DEVBUF, M_WAITOK); 491 if (mpt->request_pool == NULL) { 492 device_printf(dev, "cannot allocate request pool\n"); 493 return (1); 494 } 495 bzero(mpt->request_pool, len); 496 #else 497 mpt->request_pool = (request_t *) 498 malloc(len, M_DEVBUF, M_WAITOK | M_ZERO); 499 if (mpt->request_pool == NULL) { 500 device_printf(dev, "cannot allocate request pool\n"); 501 return (1); 502 } 503 #endif 504 505 /* 506 * Create a dma tag for this device 507 * 508 * Align at page boundaries, limit to 32-bit addressing 509 * (The chip supports 64-bit addressing, but this driver doesn't) 510 */ 511 if (bus_dma_tag_create(NULL, PAGE_SIZE, 0, BUS_SPACE_MAXADDR_32BIT, 512 BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT, 513 BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED, 0, 514 busdma_lock_mutex, &Giant, &mpt->parent_dmat) != 0) { 515 device_printf(dev, "cannot create parent dma tag\n"); 516 return (1); 517 } 518 519 /* Create a child tag for reply buffers */ 520 if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE, 521 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 522 NULL, NULL, PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0, 523 busdma_lock_mutex, &Giant, &mpt->reply_dmat) != 0) { 524 device_printf(dev, "cannot create a dma tag for replies\n"); 525 return (1); 526 } 527 528 /* Allocate some DMA accessable memory for replies */ 529 if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply, 530 BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) { 531 device_printf(dev, "cannot allocate %lu bytes of reply memory\n", 532 (u_long)PAGE_SIZE); 533 return (1); 534 } 535 536 im.mpt = mpt; 537 im.error = 0; 538 539 /* Load and lock it into "bus space" */ 540 bus_dmamap_load(mpt->reply_dmat, mpt->reply_dmap, mpt->reply, 541 PAGE_SIZE, mpt_map_rquest, &im, 0); 542 543 if (im.error) { 544 device_printf(dev, 545 "error %d loading dma map for DMA reply queue\n", im.error); 546 return (1); 547 } 548 mpt->reply_phys = im.phys; 549 550 /* Create a child tag for data buffers */ 551 if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE, 552 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 553 NULL, NULL, MAXBSIZE, MPT_SGL_MAX, BUS_SPACE_MAXSIZE_32BIT, 0, 554 busdma_lock_mutex, &Giant, &mpt->buffer_dmat) != 0) { 555 device_printf(dev, 556 "cannot create a dma tag for data buffers\n"); 557 return (1); 558 } 559 560 /* Create a child tag for request buffers */ 561 if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE, 562 0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 563 NULL, NULL, MPT_REQ_MEM_SIZE(mpt), 1, BUS_SPACE_MAXSIZE_32BIT, 0, 564 busdma_lock_mutex, &Giant, &mpt->request_dmat) != 0) { 565 device_printf(dev, "cannot create a dma tag for requests\n"); 566 return (1); 567 } 568 569 /* Allocate some DMA accessable memory for requests */ 570 if (bus_dmamem_alloc(mpt->request_dmat, (void **)&mpt->request, 571 BUS_DMA_NOWAIT, &mpt->request_dmap) != 0) { 572 device_printf(dev, 573 "cannot allocate %d bytes of request memory\n", 574 MPT_REQ_MEM_SIZE(mpt)); 575 return (1); 576 } 577 578 im.mpt = mpt; 579 im.error = 0; 580 581 /* Load and lock it into "bus space" */ 582 bus_dmamap_load(mpt->request_dmat, mpt->request_dmap, mpt->request, 583 MPT_REQ_MEM_SIZE(mpt), mpt_map_rquest, &im, 0); 584 585 if (im.error) { 586 device_printf(dev, 587 "error %d loading dma map for DMA request queue\n", 588 im.error); 589 return (1); 590 } 591 mpt->request_phys = im.phys; 592 593 i = 0; 594 pptr = mpt->request_phys; 595 vptr = mpt->request; 596 end = pptr + MPT_REQ_MEM_SIZE(mpt); 597 while(pptr < end) { 598 request_t *req = &mpt->request_pool[i]; 599 req->index = i++; 600 601 /* Store location of Request Data */ 602 req->req_pbuf = pptr; 603 req->req_vbuf = vptr; 604 605 pptr += MPT_REQUEST_AREA; 606 vptr += MPT_REQUEST_AREA; 607 608 req->sense_pbuf = (pptr - MPT_SENSE_SIZE); 609 req->sense_vbuf = (vptr - MPT_SENSE_SIZE); 610 611 error = bus_dmamap_create(mpt->buffer_dmat, 0, &req->dmap); 612 if (error) { 613 device_printf(dev, 614 "error %d creating per-cmd DMA maps\n", error); 615 return (1); 616 } 617 } 618 return (0); 619 } 620 621 622 623 /* Deallocate memory that was allocated by mpt_dma_mem_alloc 624 */ 625 static void 626 mpt_dma_mem_free(mpt_softc_t *mpt) 627 { 628 int i; 629 630 /* Make sure we aren't double destroying */ 631 if (mpt->reply_dmat == 0) { 632 if (mpt->verbose) 633 device_printf(mpt->dev,"Already released dma memory\n"); 634 return; 635 } 636 637 for (i = 0; i < MPT_MAX_REQUESTS(mpt); i++) { 638 bus_dmamap_destroy(mpt->buffer_dmat, mpt->request_pool[i].dmap); 639 } 640 bus_dmamap_unload(mpt->request_dmat, mpt->request_dmap); 641 bus_dmamem_free(mpt->request_dmat, mpt->request, mpt->request_dmap); 642 bus_dma_tag_destroy(mpt->request_dmat); 643 bus_dma_tag_destroy(mpt->buffer_dmat); 644 bus_dmamap_unload(mpt->reply_dmat, mpt->reply_dmap); 645 bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap); 646 bus_dma_tag_destroy(mpt->reply_dmat); 647 bus_dma_tag_destroy(mpt->parent_dmat); 648 mpt->reply_dmat = 0; 649 free(mpt->request_pool, M_DEVBUF); 650 mpt->request_pool = 0; 651 652 } 653 654 655 656 /* Reads modifiable (via PCI transactions) config registers */ 657 static void 658 mpt_read_config_regs(mpt_softc_t *mpt) 659 { 660 mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2); 661 mpt->pci_cfg.LatencyTimer_LineSize = 662 pci_read_config(mpt->dev, PCIR_CACHELNSZ, 2); 663 mpt->pci_cfg.IO_BAR = pci_read_config(mpt->dev, PCIR_BAR(0), 4); 664 mpt->pci_cfg.Mem0_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(1), 4); 665 mpt->pci_cfg.Mem0_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(2), 4); 666 mpt->pci_cfg.Mem1_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(3), 4); 667 mpt->pci_cfg.Mem1_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(4), 4); 668 mpt->pci_cfg.ROM_BAR = pci_read_config(mpt->dev, PCIR_BIOS, 4); 669 mpt->pci_cfg.IntLine = pci_read_config(mpt->dev, PCIR_INTLINE, 1); 670 mpt->pci_cfg.PMCSR = pci_read_config(mpt->dev, 0x44, 4); 671 } 672 673 /* Sets modifiable config registers */ 674 void 675 mpt_set_config_regs(mpt_softc_t *mpt) 676 { 677 u_int32_t val; 678 679 #define MPT_CHECK(reg, offset, size) \ 680 val = pci_read_config(mpt->dev, offset, size); \ 681 if (mpt->pci_cfg.reg != val) { \ 682 mpt_prt(mpt, \ 683 "Restoring " #reg " to 0x%X from 0x%X\n", \ 684 mpt->pci_cfg.reg, val); \ 685 } 686 687 if (mpt->verbose) { 688 MPT_CHECK(Command, PCIR_COMMAND, 2); 689 MPT_CHECK(LatencyTimer_LineSize, PCIR_CACHELNSZ, 2); 690 MPT_CHECK(IO_BAR, PCIR_BAR(0), 4); 691 MPT_CHECK(Mem0_BAR[0], PCIR_BAR(1), 4); 692 MPT_CHECK(Mem0_BAR[1], PCIR_BAR(2), 4); 693 MPT_CHECK(Mem1_BAR[0], PCIR_BAR(3), 4); 694 MPT_CHECK(Mem1_BAR[1], PCIR_BAR(4), 4); 695 MPT_CHECK(ROM_BAR, PCIR_BIOS, 4); 696 MPT_CHECK(IntLine, PCIR_INTLINE, 1); 697 MPT_CHECK(PMCSR, 0x44, 4); 698 } 699 #undef MPT_CHECK 700 701 pci_write_config(mpt->dev, PCIR_COMMAND, mpt->pci_cfg.Command, 2); 702 pci_write_config(mpt->dev, PCIR_CACHELNSZ, 703 mpt->pci_cfg.LatencyTimer_LineSize, 2); 704 pci_write_config(mpt->dev, PCIR_BAR(0), mpt->pci_cfg.IO_BAR, 4); 705 pci_write_config(mpt->dev, PCIR_BAR(1), mpt->pci_cfg.Mem0_BAR[0], 4); 706 pci_write_config(mpt->dev, PCIR_BAR(2), mpt->pci_cfg.Mem0_BAR[1], 4); 707 pci_write_config(mpt->dev, PCIR_BAR(3), mpt->pci_cfg.Mem1_BAR[0], 4); 708 pci_write_config(mpt->dev, PCIR_BAR(4), mpt->pci_cfg.Mem1_BAR[1], 4); 709 pci_write_config(mpt->dev, PCIR_BIOS, mpt->pci_cfg.ROM_BAR, 4); 710 pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1); 711 pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4); 712 } 713 714 static void 715 mpt_pci_intr(void *arg) 716 { 717 mpt_softc_t *mpt = arg; 718 MPT_LOCK(mpt); 719 (void) mpt_intr(mpt); 720 MPT_UNLOCK(mpt); 721 } 722