xref: /freebsd/sys/dev/mpt/mpt_pci.c (revision c4f6a2a9e1b1879b618c436ab4f56ff75c73a0f5)
1 /* $FreeBSD$ */
2 /*
3  * PCI specific probe and attach routines for LSI '909 FC  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_FC929
61 #define	PCI_PRODUCT_LSI_FC929		0x0622
62 #endif
63 
64 #ifndef	PCI_PRODUCT_LSI_1030
65 #define	PCI_PRODUCT_LSI_1030		0x0030
66 #endif
67 
68 
69 
70 #define	MEM_MAP_REG	0x14
71 #define	MEM_MAP_SRAM	0x1C
72 
73 static int mpt_probe(device_t);
74 static int mpt_attach(device_t);
75 static void mpt_free_bus_resources(mpt_softc_t *mpt);
76 static int mpt_detach(device_t);
77 static int mpt_shutdown(device_t);
78 static int mpt_dma_mem_alloc(mpt_softc_t *mpt);
79 static void mpt_dma_mem_free(mpt_softc_t *mpt);
80 static void mpt_read_config_regs(mpt_softc_t *mpt);
81 static void mpt_pci_intr(void *);
82 
83 static device_method_t mpt_methods[] = {
84 	/* Device interface */
85 	DEVMETHOD(device_probe,		mpt_probe),
86 	DEVMETHOD(device_attach,	mpt_attach),
87 	DEVMETHOD(device_detach,	mpt_detach),
88 	DEVMETHOD(device_shutdown,	mpt_shutdown),
89 	{ 0, 0 }
90 };
91 
92 static driver_t mpt_driver = {
93 	"mpt", mpt_methods, sizeof (mpt_softc_t)
94 };
95 static devclass_t mpt_devclass;
96 DRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0);
97 MODULE_VERSION(mpt, 1);
98 
99 int
100 mpt_intr(void *dummy)
101 {
102 	u_int32_t reply;
103 	mpt_softc_t *mpt = (mpt_softc_t *)dummy;
104 
105 	reply = mpt_pop_reply_queue(mpt);
106 	while (reply != MPT_REPLY_EMPTY) {
107 		if (mpt->verbose > 1) {
108 			if ((reply & MPT_CONTEXT_REPLY) != 0)  {
109 				/* Address reply; IOC has something to say */
110 				mpt_print_reply(MPT_REPLY_PTOV(mpt, reply));
111 			} else {
112 				/* Context reply ; all went well */
113 				device_printf(mpt->dev,
114 				    "context %u reply OK\n", reply);
115 			}
116 		}
117 		mpt_done(mpt, reply);
118 		reply = mpt_pop_reply_queue(mpt);
119 	}
120 	return 0;
121 }
122 
123 static int
124 mpt_probe(device_t dev)
125 {
126 	char *desc;
127 
128 	if (pci_get_vendor(dev) != PCI_VENDOR_LSI)
129 		return (ENXIO);
130 
131 	switch ((pci_get_device(dev) & ~1)) {
132 	case PCI_PRODUCT_LSI_FC909:
133 		desc = "LSILogic FC909 FC Adapter";
134 		break;
135 	case PCI_PRODUCT_LSI_FC929:
136 		desc = "LSILogic FC929 FC Adapter";
137 		break;
138 	case PCI_PRODUCT_LSI_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 (getenv_int("mpt_disable", &bitmap)) {
157 		if (bitmap & (1 << mpt->unit)) {
158 			mpt->disabled = 1;
159 		}
160 	}
161 
162 	bitmap = 0;
163 	if (getenv_int("mpt_debug", &bitmap)) {
164 		if (bitmap & (1 << mpt->unit)) {
165 			mpt->verbose = 2;
166 		}
167 	}
168 
169 	cmd = pci_read_config(dev, PCIR_COMMAND, 2);
170 }
171 #else
172 static void
173 mpt_set_options(mpt_softc_t *mpt)
174 {
175 	int tval;
176 
177 	tval = 0;
178 	if (resource_int_value(device_get_name(mpt->dev),
179 	    device_get_unit(mpt->dev), "disable", &tval) == 0 && tval != 0) {
180 		mpt->disabled = 1;
181 	}
182 	tval = 0;
183 	if (resource_int_value(device_get_name(mpt->dev),
184 	    device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) {
185 		mpt->verbose += tval;
186 	}
187 }
188 #endif
189 
190 
191 static int
192 mpt_attach(device_t dev)
193 {
194 	int iqd;
195 	u_int32_t data, cmd;
196 	mpt_softc_t *mpt;
197 
198 	/* Allocate the softc structure */
199 	mpt  = (mpt_softc_t*) device_get_softc(dev);
200 	if (mpt == NULL) {
201 		device_printf(dev, "cannot allocate softc\n");
202 		return (ENOMEM);
203 	}
204 	bzero(mpt, sizeof (mpt_softc_t));
205 	switch ((pci_get_device(dev) & ~1)) {
206 	case PCI_PRODUCT_LSI_FC909:
207 	case PCI_PRODUCT_LSI_FC929:
208 		mpt->is_fc = 1;
209 		break;
210 	default:
211 		break;
212 	}
213 	mpt->dev = dev;
214 	mpt->unit = device_get_unit(dev);
215 	mpt_set_options(mpt);
216 	mpt->verbose += (bootverbose != 0)? 1 : 0;
217 
218 	/* Make sure memory access decoders are enabled */
219 	cmd = pci_read_config(dev, PCIR_COMMAND, 2);
220 	if ((cmd & PCIM_CMD_MEMEN) == 0) {
221 		device_printf(dev, "Memory accesses disabled");
222 		goto bad;
223 	}
224 
225 	/*
226 	 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set.
227 	 */
228 	cmd |=
229 	    PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN |
230 	    PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
231 	pci_write_config(dev, PCIR_COMMAND, cmd, 2);
232 
233 	/*
234 	 * Make sure we've disabled the ROM.
235 	 */
236 	data = pci_read_config(dev, PCIR_BIOS, 4);
237 	data &= ~1;
238 	pci_write_config(dev, PCIR_BIOS, data, 4);
239 
240 
241 	/* Is this part a dual? */
242 	if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929) {
243 		/* Yes; is the previous device the counterpart? */
244 		if (mpt->unit) {
245 			mpt->mpt2 = (mpt_softc_t *)
246 				devclass_get_softc(mpt_devclass, mpt->unit-1);
247 
248 			if ((mpt->mpt2->mpt2 == NULL)
249 			  && (pci_get_vendor(mpt->mpt2->dev) == PCI_VENDOR_LSI)
250 			  && ((pci_get_device(mpt->mpt2->dev) & ~1) == PCI_PRODUCT_LSI_FC929) ) {
251 				/* Yes */
252 				mpt->mpt2->mpt2 = mpt;
253 				if (mpt->verbose) {
254 					device_printf(dev, "Detected dual\n");
255 				}
256 			} else {
257 				/* Nope */
258 				mpt->mpt2 = NULL;
259 			}
260 		}
261 	}
262 
263 	/* Set up the memory regions */
264 	/* Allocate kernel virtual memory for the 9x9's Mem0 region */
265 	mpt->pci_reg_id = MEM_MAP_REG;
266 	mpt->pci_reg = bus_alloc_resource(dev, SYS_RES_MEMORY,
267 			&mpt->pci_reg_id, 0, ~0, 0, RF_ACTIVE);
268 	if (mpt->pci_reg == NULL) {
269 		device_printf(dev, "unable to map any ports\n");
270 		goto bad;
271 	}
272 	mpt->pci_st = rman_get_bustag(mpt->pci_reg);
273 	mpt->pci_sh = rman_get_bushandle(mpt->pci_reg);
274 	/*   Get the Physical Address */
275 	mpt->pci_pa = rman_get_start(mpt->pci_reg);
276 
277 	/* Get a handle to the interrupt */
278 	iqd = 0;
279 	mpt->pci_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &iqd, 0, ~0,
280 	    1, RF_ACTIVE | RF_SHAREABLE);
281 	if (mpt->pci_irq == NULL) {
282 		device_printf(dev, "could not allocate interrupt\n");
283 		goto bad;
284 	}
285 
286 	/* Register the interrupt handler */
287 	if (bus_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, mpt_pci_intr,
288 	    mpt, &mpt->ih)) {
289 		device_printf(dev, "could not setup interrupt\n");
290 		goto bad;
291 	}
292 
293 	MPT_LOCK_SETUP(mpt);
294 
295 	/* Disable interrupts at the part */
296 	mpt_disable_ints(mpt);
297 
298 	/* Allocate dma memory */
299 	if (mpt_dma_mem_alloc(mpt)) {
300 		device_printf(dev, "Could not allocate DMA memory\n");
301 		goto bad;
302 	}
303 
304 	/*
305 	 * Save the PCI config register values
306  	 *
307 	 * Hard resets are known to screw up the BAR for diagnostic
308 	 * memory accesses (Mem1).
309 	 *
310 	 * Using Mem1 is known to make the chip stop responding to
311 	 * configuration space transfers, so we need to save it now
312 	 */
313 
314 	mpt_read_config_regs(mpt);
315 
316 	/* Initialize the hardware */
317 	if (mpt->disabled == 0) {
318 		MPT_LOCK(mpt);
319 		if (mpt_init(mpt, MPT_DB_INIT_HOST) != 0) {
320 			MPT_UNLOCK(mpt);
321 			goto bad;
322 		}
323 
324 		/*
325 		 *  Attach to CAM
326 		 */
327 		MPTLOCK_2_CAMLOCK(mpt);
328 		mpt_cam_attach(mpt);
329 		CAMLOCK_2_MPTLOCK(mpt);
330 		MPT_UNLOCK(mpt);
331 	}
332 
333 	return (0);
334 
335 bad:
336 	mpt_dma_mem_free(mpt);
337 	mpt_free_bus_resources(mpt);
338 
339 	/*
340 	 * but return zero to preserve unit numbering
341 	 */
342 	return (0);
343 }
344 
345 /*
346  * Free bus resources
347  */
348 static void
349 mpt_free_bus_resources(mpt_softc_t *mpt)
350 {
351 	if (mpt->ih) {
352 		bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih);
353 		mpt->ih = 0;
354 	}
355 
356 	if (mpt->pci_irq) {
357 		bus_release_resource(mpt->dev, SYS_RES_IRQ, 0, mpt->pci_irq);
358 		mpt->pci_irq = 0;
359 	}
360 
361 	if (mpt->pci_reg) {
362 		bus_release_resource(mpt->dev, SYS_RES_MEMORY, mpt->pci_reg_id,
363 			mpt->pci_reg);
364 		mpt->pci_reg = 0;
365 	}
366 	MPT_LOCK_DESTROY(mpt);
367 }
368 
369 
370 /*
371  * Disconnect ourselves from the system.
372  */
373 static int
374 mpt_detach(device_t dev)
375 {
376 	mpt_softc_t *mpt;
377 	mpt  = (mpt_softc_t*) device_get_softc(dev);
378 
379 	device_printf(mpt->dev,"mpt_detach!\n");
380 
381 	if (mpt) {
382 		mpt_disable_ints(mpt);
383 		mpt_cam_detach(mpt);
384 		mpt_reset(mpt);
385 		mpt_dma_mem_free(mpt);
386 		mpt_free_bus_resources(mpt);
387 	}
388 	return(0);
389 }
390 
391 
392 /*
393  * Disable the hardware
394  */
395 static int
396 mpt_shutdown(device_t dev)
397 {
398 	mpt_softc_t *mpt;
399 	mpt  = (mpt_softc_t*) device_get_softc(dev);
400 
401 	if (mpt) {
402 		mpt_reset(mpt);
403 	}
404 	return(0);
405 }
406 
407 
408 struct imush {
409 	mpt_softc_t *mpt;
410 	int error;
411 	u_int32_t phys;
412 };
413 
414 static void
415 mpt_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error)
416 {
417 	struct imush *imushp = (struct imush *) arg;
418 	imushp->error = error;
419 	imushp->phys = segs->ds_addr;
420 }
421 
422 
423 static int
424 mpt_dma_mem_alloc(mpt_softc_t *mpt)
425 {
426 	int i, error;
427 	u_char *vptr;
428 	u_int32_t pptr, end;
429 	struct imush im;
430 	device_t dev = mpt->dev;
431 
432 	/* Check if we alreay have allocated the reply memory */
433 	if (mpt->reply_phys != NULL)
434 		return 0;
435 
436 	/*
437 	 * Create a dma tag for this device
438 	 *
439 	 * Align at page boundaries, limit to 32-bit addressing
440 	 * (The chip supports 64-bit addressing, but this driver doesn't)
441 	 */
442 	if (bus_dma_tag_create(NULL, PAGE_SIZE, 0, BUS_SPACE_MAXADDR_32BIT,
443 	    BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT,
444 	    BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED, 0,
445 	    &mpt->parent_dmat) != 0) {
446 		device_printf(dev, "cannot create parent dma tag\n");
447 		return (1);
448 	}
449 
450 	/* Create a child tag for reply buffers */
451 	if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE,
452 	    0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
453 	    NULL, NULL, PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
454 	    &mpt->reply_dmat) != 0) {
455 		device_printf(dev, "cannot create a dma tag for replies\n");
456 		return (1);
457 	}
458 
459 	/* Allocate some DMA accessable memory for replies */
460 	if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply,
461 	    BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) {
462 		device_printf(dev, "cannot allocate %d bytes of reply memory\n",
463 		     PAGE_SIZE);
464 		return (1);
465 	}
466 
467 	im.mpt = mpt;
468 	im.error = 0;
469 
470 	/* Load and lock it into "bus space" */
471 	bus_dmamap_load(mpt->reply_dmat, mpt->reply_dmap, mpt->reply,
472 	    PAGE_SIZE, mpt_map_rquest, &im, 0);
473 
474 	if (im.error) {
475 		device_printf(dev,
476 		    "error %d loading dma map for DMA reply queue\n", im.error);
477 		return (1);
478 	}
479 	mpt->reply_phys = im.phys;
480 
481 	/* Create a child tag for data buffers */
482 	if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE,
483 	    0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
484 	    NULL, NULL, MAXBSIZE, MPT_SGL_MAX, BUS_SPACE_MAXSIZE_32BIT, 0,
485 	    &mpt->buffer_dmat) != 0) {
486 		device_printf(dev,
487 		    "cannot create a dma tag for data buffers\n");
488 		return (1);
489 	}
490 
491 	/* Create a child tag for request buffers */
492 	if (bus_dma_tag_create(mpt->parent_dmat, PAGE_SIZE,
493 	    0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
494 	    NULL, NULL, MPT_REQ_MEM_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
495 	    &mpt->request_dmat) != 0) {
496 		device_printf(dev, "cannot create a dma tag for requests\n");
497 		return (1);
498 	}
499 
500 	/* Allocate some DMA accessable memory for requests */
501 	if (bus_dmamem_alloc(mpt->request_dmat, (void **)&mpt->request,
502 	    BUS_DMA_NOWAIT, &mpt->request_dmap) != 0) {
503 		device_printf(dev,
504 		    "cannot allocate %d bytes of request memory\n",
505 		    MPT_REQ_MEM_SIZE);
506 		return (1);
507 	}
508 
509 	im.mpt = mpt;
510 	im.error = 0;
511 
512 	/* Load and lock it into "bus space" */
513         bus_dmamap_load(mpt->request_dmat, mpt->request_dmap, mpt->request,
514 	    MPT_REQ_MEM_SIZE, mpt_map_rquest, &im, 0);
515 
516 	if (im.error) {
517 		device_printf(dev,
518 		    "error %d loading dma map for DMA request queue\n",
519 		    im.error);
520 		return (1);
521 	}
522 	mpt->request_phys = im.phys;
523 
524 	i = 0;
525 	pptr =  mpt->request_phys;
526 	vptr =  mpt->request;
527 	end = pptr + MPT_REQ_MEM_SIZE;
528 	while(pptr < end) {
529 		request_t *req = &mpt->requests[i];
530 		req->index = i++;
531 
532 		/* Store location of Request Data */
533 		req->req_pbuf = pptr;
534 		req->req_vbuf = vptr;
535 
536 		pptr += MPT_REQUEST_AREA;
537 		vptr += MPT_REQUEST_AREA;
538 
539 		req->sense_pbuf = (pptr - MPT_SENSE_SIZE);
540 		req->sense_vbuf = (vptr - MPT_SENSE_SIZE);
541 
542 		error = bus_dmamap_create(mpt->buffer_dmat, 0, &req->dmap);
543 		if (error) {
544 			device_printf(dev,
545 			     "error %d creating per-cmd DMA maps\n", error);
546 			return (1);
547 		}
548 	}
549 	return (0);
550 }
551 
552 
553 
554 /* Deallocate memory that was allocated by mpt_dma_mem_alloc
555  */
556 static void
557 mpt_dma_mem_free(mpt_softc_t *mpt)
558 {
559 	int i;
560 
561         /* Make sure we aren't double destroying */
562         if (mpt->reply_dmat == 0) {
563 		if (mpt->verbose)
564 			device_printf(mpt->dev,"Already released dma memory\n");
565 		return;
566         }
567 
568 	for (i = 0; i < MPT_MAX_REQUESTS; i++) {
569 		bus_dmamap_destroy(mpt->buffer_dmat, mpt->requests[i].dmap);
570 	}
571 	bus_dmamap_unload(mpt->request_dmat, mpt->request_dmap);
572 	bus_dmamem_free(mpt->request_dmat, mpt->request, mpt->request_dmap);
573 	bus_dma_tag_destroy(mpt->request_dmat);
574 	bus_dma_tag_destroy(mpt->buffer_dmat);
575 	bus_dmamap_unload(mpt->reply_dmat, mpt->reply_dmap);
576 	bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap);
577 	bus_dma_tag_destroy(mpt->reply_dmat);
578 	bus_dma_tag_destroy(mpt->parent_dmat);
579 	mpt->reply_dmat = 0;
580 
581 }
582 
583 
584 
585 /* Reads modifiable (via PCI transactions) config registers */
586 static void
587 mpt_read_config_regs(mpt_softc_t *mpt)
588 {
589 	mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2);
590 	mpt->pci_cfg.LatencyTimer_LineSize =
591 	    pci_read_config(mpt->dev, PCIR_CACHELNSZ, 2);
592 	mpt->pci_cfg.IO_BAR = pci_read_config(mpt->dev, PCIR_MAPS, 4);
593 	mpt->pci_cfg.Mem0_BAR[0] = pci_read_config(mpt->dev, PCIR_MAPS+0x4, 4);
594 	mpt->pci_cfg.Mem0_BAR[1] = pci_read_config(mpt->dev, PCIR_MAPS+0x8, 4);
595 	mpt->pci_cfg.Mem1_BAR[0] = pci_read_config(mpt->dev, PCIR_MAPS+0xC, 4);
596 	mpt->pci_cfg.Mem1_BAR[1] = pci_read_config(mpt->dev, PCIR_MAPS+0x10, 4);
597 	mpt->pci_cfg.ROM_BAR = pci_read_config(mpt->dev, PCIR_BIOS, 4);
598 	mpt->pci_cfg.IntLine = pci_read_config(mpt->dev, PCIR_INTLINE, 1);
599 	mpt->pci_cfg.PMCSR = pci_read_config(mpt->dev, 0x44, 4);
600 }
601 
602 /* Sets modifiable config registers */
603 void
604 mpt_set_config_regs(mpt_softc_t *mpt)
605 {
606 	u_int32_t val;
607 
608 #define MPT_CHECK(reg, offset, size)					\
609 	val = pci_read_config(mpt->dev, offset, size);			\
610 	if (mpt->pci_cfg.reg != val) {					\
611 		device_printf(mpt->dev,					\
612 		    "Restoring " #reg " to 0x%X from 0x%X\n",		\
613 		    mpt->pci_cfg.reg, val);				\
614 	}
615 
616 	if (mpt->verbose) {
617 		MPT_CHECK(Command, PCIR_COMMAND, 2);
618 		MPT_CHECK(LatencyTimer_LineSize, PCIR_CACHELNSZ, 2);
619 		MPT_CHECK(IO_BAR, PCIR_MAPS, 4);
620 		MPT_CHECK(Mem0_BAR[0], PCIR_MAPS+0x4, 4);
621 		MPT_CHECK(Mem0_BAR[1], PCIR_MAPS+0x8, 4);
622 		MPT_CHECK(Mem1_BAR[0], PCIR_MAPS+0xC, 4);
623 		MPT_CHECK(Mem1_BAR[1], PCIR_MAPS+0x10, 4);
624 		MPT_CHECK(ROM_BAR, PCIR_BIOS, 4);
625 		MPT_CHECK(IntLine, PCIR_INTLINE, 1);
626 		MPT_CHECK(PMCSR, 0x44, 4);
627 	}
628 #undef MPT_CHECK
629 
630 	pci_write_config(mpt->dev, PCIR_COMMAND, mpt->pci_cfg.Command, 2);
631 	pci_write_config(mpt->dev, PCIR_CACHELNSZ,
632 	    mpt->pci_cfg.LatencyTimer_LineSize, 2);
633 	pci_write_config(mpt->dev, PCIR_MAPS, mpt->pci_cfg.IO_BAR, 4);
634 	pci_write_config(mpt->dev, PCIR_MAPS+0x4, mpt->pci_cfg.Mem0_BAR[0], 4);
635 	pci_write_config(mpt->dev, PCIR_MAPS+0x8, mpt->pci_cfg.Mem0_BAR[1], 4);
636 	pci_write_config(mpt->dev, PCIR_MAPS+0xC, mpt->pci_cfg.Mem1_BAR[0], 4);
637 	pci_write_config(mpt->dev, PCIR_MAPS+0x10, mpt->pci_cfg.Mem1_BAR[1], 4);
638 	pci_write_config(mpt->dev, PCIR_BIOS, mpt->pci_cfg.ROM_BAR, 4);
639 	pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1);
640 	pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4);
641 }
642 
643 static void
644 mpt_pci_intr(void *arg)
645 {
646 	mpt_softc_t *mpt = arg;
647 	MPT_LOCK(mpt);
648 	mpt_intr(mpt);
649 	MPT_UNLOCK(mpt);
650 }
651