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