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