mpt_pci.c revision 224493
1119418Sobrien/*-
2102596Smjacob * PCI specific probe and attach routines for LSI Fusion Adapters
3101704Smjacob * FreeBSD Version.
4101704Smjacob *
5119418Sobrien * Copyright (c) 2000, 2001 by Greg Ansley
6101704Smjacob * Partially derived from Matt Jacob's ISP driver.
7119418Sobrien * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 by Matthew Jacob
8119418Sobrien * Feral Software
9119418Sobrien * All rights reserved.
10101704Smjacob *
11101704Smjacob * Redistribution and use in source and binary forms, with or without
12101704Smjacob * modification, are permitted provided that the following conditions
13101704Smjacob * are met:
14101704Smjacob * 1. Redistributions of source code must retain the above copyright
15101704Smjacob *    notice immediately at the beginning of the file, without modification,
16101704Smjacob *    this list of conditions, and the following disclaimer.
17101704Smjacob * 2. The name of the author may not be used to endorse or promote products
18101704Smjacob *    derived from this software without specific prior written permission.
19101704Smjacob *
20101704Smjacob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21101704Smjacob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22101704Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23101704Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24101704Smjacob * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25101704Smjacob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26101704Smjacob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27101704Smjacob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28101704Smjacob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29101704Smjacob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30101704Smjacob * SUCH DAMAGE.
31101704Smjacob */
32156000Smjacob/*-
33156000Smjacob * Copyright (c) 2002, 2006 by Matthew Jacob
34156000Smjacob * All rights reserved.
35156000Smjacob *
36156000Smjacob * Redistribution and use in source and binary forms, with or without
37156000Smjacob * modification, are permitted provided that the following conditions are
38156000Smjacob * met:
39156000Smjacob * 1. Redistributions of source code must retain the above copyright
40156000Smjacob *    notice, this list of conditions and the following disclaimer.
41156000Smjacob * 2. Redistributions in binary form must reproduce at minimum a disclaimer
42156000Smjacob *    substantially similar to the "NO WARRANTY" disclaimer below
43156000Smjacob *    ("Disclaimer") and any redistribution must be conditioned upon including
44156000Smjacob *    a substantially similar Disclaimer requirement for further binary
45156000Smjacob *    redistribution.
46156000Smjacob * 3. Neither the names of the above listed copyright holders nor the names
47156000Smjacob *    of any contributors may be used to endorse or promote products derived
48156000Smjacob *    from this software without specific prior written permission.
49156000Smjacob *
50156000Smjacob * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
51156000Smjacob * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52156000Smjacob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53156000Smjacob * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
54156000Smjacob * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55156000Smjacob * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56156000Smjacob * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57156000Smjacob * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58156000Smjacob * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59156000Smjacob * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
60156000Smjacob * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61156000Smjacob *
62156000Smjacob * Support from Chris Ellsworth in order to make SAS adapters work
63156000Smjacob * is gratefully acknowledged.
64159052Smjacob *
65159052Smjacob * Support from LSI-Logic has also gone a great deal toward making this a
66159052Smjacob * workable subsystem and is gratefully acknowledged.
67156000Smjacob */
68147883Sscottl/*
69147883Sscottl * Copyright (c) 2004, Avid Technology, Inc. and its contributors.
70147883Sscottl * Copyright (c) 2005, WHEEL Sp. z o.o.
71147883Sscottl * Copyright (c) 2004, 2005 Justin T. Gibbs
72147883Sscottl * All rights reserved.
73147883Sscottl *
74147883Sscottl * Redistribution and use in source and binary forms, with or without
75147883Sscottl * modification, are permitted provided that the following conditions are
76147883Sscottl * met:
77147883Sscottl * 1. Redistributions of source code must retain the above copyright
78147883Sscottl *    notice, this list of conditions and the following disclaimer.
79147883Sscottl * 2. Redistributions in binary form must reproduce at minimum a disclaimer
80147883Sscottl *    substantially similar to the "NO WARRANTY" disclaimer below
81147883Sscottl *    ("Disclaimer") and any redistribution must be conditioned upon including
82147883Sscottl *    a substantially similar Disclaimer requirement for further binary
83147883Sscottl *    redistribution.
84148679Sgibbs * 3. Neither the names of the above listed copyright holders nor the names
85148679Sgibbs *    of any contributors may be used to endorse or promote products derived
86148679Sgibbs *    from this software without specific prior written permission.
87147883Sscottl *
88147883Sscottl * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
89147883Sscottl * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90147883Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91147883Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
92147883Sscottl * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
93147883Sscottl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
94147883Sscottl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
95147883Sscottl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
96147883Sscottl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
97147883Sscottl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
98147883Sscottl * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99147883Sscottl */
100101704Smjacob
101119418Sobrien#include <sys/cdefs.h>
102119418Sobrien__FBSDID("$FreeBSD: head/sys/dev/mpt/mpt_pci.c 224493 2011-07-29 18:35:10Z marius $");
103119418Sobrien
104147883Sscottl#include <dev/mpt/mpt.h>
105147883Sscottl#include <dev/mpt/mpt_cam.h>
106147883Sscottl#include <dev/mpt/mpt_raid.h>
107102199Smjacob
108165814Smjacob#if __FreeBSD_version < 700000
109166721Sjhb#define	pci_msix_count(x)	0
110165814Smjacob#define	pci_msi_count(x)	0
111165814Smjacob#define	pci_alloc_msi(x, y)	1
112166721Sjhb#define	pci_alloc_msix(x, y)	1
113165814Smjacob#define	pci_release_msi(x)	do { ; } while (0)
114165814Smjacob#endif
115101704Smjacob
116101704Smjacob#ifndef	PCI_VENDOR_LSI
117101704Smjacob#define	PCI_VENDOR_LSI			0x1000
118101704Smjacob#endif
119101704Smjacob
120101704Smjacob#ifndef	PCI_PRODUCT_LSI_FC909
121101704Smjacob#define	PCI_PRODUCT_LSI_FC909		0x0620
122101704Smjacob#endif
123101704Smjacob
124102596Smjacob#ifndef	PCI_PRODUCT_LSI_FC909A
125102596Smjacob#define	PCI_PRODUCT_LSI_FC909A		0x0621
126102596Smjacob#endif
127102596Smjacob
128103829Smjacob#ifndef	PCI_PRODUCT_LSI_FC919
129103829Smjacob#define	PCI_PRODUCT_LSI_FC919		0x0624
130103829Smjacob#endif
131103829Smjacob
132101704Smjacob#ifndef	PCI_PRODUCT_LSI_FC929
133101704Smjacob#define	PCI_PRODUCT_LSI_FC929		0x0622
134101704Smjacob#endif
135101704Smjacob
136150007Smjacob#ifndef	PCI_PRODUCT_LSI_FC929X
137150007Smjacob#define	PCI_PRODUCT_LSI_FC929X		0x0626
138150007Smjacob#endif
139150007Smjacob
140159494Smjacob#ifndef	PCI_PRODUCT_LSI_FC919X
141159494Smjacob#define	PCI_PRODUCT_LSI_FC919X		0x0628
142159494Smjacob#endif
143159494Smjacob
144158279Smjacob#ifndef	PCI_PRODUCT_LSI_FC7X04X
145158279Smjacob#define	PCI_PRODUCT_LSI_FC7X04X		0x0640
146158279Smjacob#endif
147158279Smjacob
148162140Smjacob#ifndef	PCI_PRODUCT_LSI_FC646
149162140Smjacob#define	PCI_PRODUCT_LSI_FC646		0x0646
150162140Smjacob#endif
151162140Smjacob
152101704Smjacob#ifndef	PCI_PRODUCT_LSI_1030
153101704Smjacob#define	PCI_PRODUCT_LSI_1030		0x0030
154101704Smjacob#endif
155101704Smjacob
156155521Smjacob#ifndef	PCI_PRODUCT_LSI_SAS1064
157155521Smjacob#define PCI_PRODUCT_LSI_SAS1064		0x0050
158155521Smjacob#endif
159155521Smjacob
160155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1064A
161155521Smjacob#define PCI_PRODUCT_LSI_SAS1064A	0x005C
162155521Smjacob#endif
163155521Smjacob
164155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1064E
165155521Smjacob#define PCI_PRODUCT_LSI_SAS1064E	0x0056
166155521Smjacob#endif
167155521Smjacob
168155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1066
169155521Smjacob#define PCI_PRODUCT_LSI_SAS1066		0x005E
170155521Smjacob#endif
171155521Smjacob
172155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1066E
173155521Smjacob#define PCI_PRODUCT_LSI_SAS1066E	0x005A
174155521Smjacob#endif
175155521Smjacob
176155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1068
177155521Smjacob#define PCI_PRODUCT_LSI_SAS1068		0x0054
178155521Smjacob#endif
179155521Smjacob
180155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1068E
181155521Smjacob#define PCI_PRODUCT_LSI_SAS1068E	0x0058
182155521Smjacob#endif
183155521Smjacob
184155521Smjacob#ifndef PCI_PRODUCT_LSI_SAS1078
185172219Sambrisko#define PCI_PRODUCT_LSI_SAS1078		0x0062
186155521Smjacob#endif
187155521Smjacob
188178896Sdelphij#ifndef	PCI_PRODUCT_LSI_SAS1078DE
189178896Sdelphij#define	PCI_PRODUCT_LSI_SAS1078DE	0x007C
190178896Sdelphij#endif
191178896Sdelphij
192102303Smjacob#ifndef	PCIM_CMD_SERRESPEN
193102303Smjacob#define	PCIM_CMD_SERRESPEN	0x0100
194102303Smjacob#endif
195101704Smjacob
196147883Sscottlstatic int mpt_pci_probe(device_t);
197147883Sscottlstatic int mpt_pci_attach(device_t);
198147883Sscottlstatic void mpt_free_bus_resources(struct mpt_softc *mpt);
199147883Sscottlstatic int mpt_pci_detach(device_t);
200147883Sscottlstatic int mpt_pci_shutdown(device_t);
201147883Sscottlstatic int mpt_dma_mem_alloc(struct mpt_softc *mpt);
202147883Sscottlstatic void mpt_dma_mem_free(struct mpt_softc *mpt);
203147883Sscottlstatic void mpt_read_config_regs(struct mpt_softc *mpt);
204224493Smarius#if 0
205224493Smariusstatic void mpt_set_config_regs(struct mpt_softc *mpt);
206224493Smarius#endif
207102199Smjacobstatic void mpt_pci_intr(void *);
208101704Smjacob
209101704Smjacobstatic device_method_t mpt_methods[] = {
210101704Smjacob	/* Device interface */
211147883Sscottl	DEVMETHOD(device_probe,		mpt_pci_probe),
212147883Sscottl	DEVMETHOD(device_attach,	mpt_pci_attach),
213147883Sscottl	DEVMETHOD(device_detach,	mpt_pci_detach),
214147883Sscottl	DEVMETHOD(device_shutdown,	mpt_pci_shutdown),
215101704Smjacob	{ 0, 0 }
216101704Smjacob};
217101704Smjacob
218101704Smjacobstatic driver_t mpt_driver = {
219147883Sscottl	"mpt", mpt_methods, sizeof(struct mpt_softc)
220101704Smjacob};
221101704Smjacobstatic devclass_t mpt_devclass;
222101704SmjacobDRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0);
223165058SmjacobMODULE_DEPEND(mpt, pci, 1, 1, 1);
224101704SmjacobMODULE_VERSION(mpt, 1);
225101704Smjacob
226101704Smjacobstatic int
227147883Sscottlmpt_pci_probe(device_t dev)
228101704Smjacob{
229101704Smjacob	char *desc;
230101704Smjacob
231160290Smjacob	if (pci_get_vendor(dev) != PCI_VENDOR_LSI) {
232101704Smjacob		return (ENXIO);
233160290Smjacob	}
234101704Smjacob
235101704Smjacob	switch ((pci_get_device(dev) & ~1)) {
236101704Smjacob	case PCI_PRODUCT_LSI_FC909:
237101704Smjacob		desc = "LSILogic FC909 FC Adapter";
238101704Smjacob		break;
239102596Smjacob	case PCI_PRODUCT_LSI_FC909A:
240102596Smjacob		desc = "LSILogic FC909A FC Adapter";
241102596Smjacob		break;
242103829Smjacob	case PCI_PRODUCT_LSI_FC919:
243103829Smjacob		desc = "LSILogic FC919 FC Adapter";
244103829Smjacob		break;
245101704Smjacob	case PCI_PRODUCT_LSI_FC929:
246162140Smjacob		desc = "Dual LSILogic FC929 FC Adapter";
247101704Smjacob		break;
248159494Smjacob	case PCI_PRODUCT_LSI_FC919X:
249162140Smjacob		desc = "LSILogic FC919 FC PCI-X Adapter";
250159494Smjacob		break;
251150007Smjacob	case PCI_PRODUCT_LSI_FC929X:
252162140Smjacob		desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter";
253150007Smjacob		break;
254162140Smjacob	case PCI_PRODUCT_LSI_FC646:
255162140Smjacob		desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter";
256162140Smjacob		break;
257158279Smjacob	case PCI_PRODUCT_LSI_FC7X04X:
258162140Smjacob		desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter";
259158279Smjacob		break;
260101704Smjacob	case PCI_PRODUCT_LSI_1030:
261101704Smjacob		desc = "LSILogic 1030 Ultra4 Adapter";
262101704Smjacob		break;
263155521Smjacob	case PCI_PRODUCT_LSI_SAS1064:
264155521Smjacob	case PCI_PRODUCT_LSI_SAS1064A:
265155521Smjacob	case PCI_PRODUCT_LSI_SAS1064E:
266155521Smjacob	case PCI_PRODUCT_LSI_SAS1066:
267155521Smjacob	case PCI_PRODUCT_LSI_SAS1066E:
268155521Smjacob	case PCI_PRODUCT_LSI_SAS1068:
269155521Smjacob	case PCI_PRODUCT_LSI_SAS1068E:
270155521Smjacob	case PCI_PRODUCT_LSI_SAS1078:
271178896Sdelphij	case PCI_PRODUCT_LSI_SAS1078DE:
272162140Smjacob		desc = "LSILogic SAS/SATA Adapter";
273155521Smjacob		break;
274101704Smjacob	default:
275101704Smjacob		return (ENXIO);
276101704Smjacob	}
277101704Smjacob
278101704Smjacob	device_set_desc(dev, desc);
279147883Sscottl	return (0);
280101704Smjacob}
281101704Smjacob
282157117Smjacob#if	__FreeBSD_version < 500000
283101704Smjacobstatic void
284147883Sscottlmpt_set_options(struct mpt_softc *mpt)
285101704Smjacob{
286101704Smjacob	int bitmap;
287101704Smjacob
288101704Smjacob	bitmap = 0;
289101704Smjacob	if (getenv_int("mpt_disable", &bitmap)) {
290101704Smjacob		if (bitmap & (1 << mpt->unit)) {
291101704Smjacob			mpt->disabled = 1;
292101704Smjacob		}
293101704Smjacob	}
294101704Smjacob	bitmap = 0;
295101704Smjacob	if (getenv_int("mpt_debug", &bitmap)) {
296101704Smjacob		if (bitmap & (1 << mpt->unit)) {
297147883Sscottl			mpt->verbose = MPT_PRT_DEBUG;
298101704Smjacob		}
299101704Smjacob	}
300157117Smjacob	bitmap = 0;
301157662Smjacob	if (getenv_int("mpt_debug1", &bitmap)) {
302157117Smjacob		if (bitmap & (1 << mpt->unit)) {
303157662Smjacob			mpt->verbose = MPT_PRT_DEBUG1;
304157117Smjacob		}
305157117Smjacob	}
306157117Smjacob	bitmap = 0;
307157662Smjacob	if (getenv_int("mpt_debug2", &bitmap)) {
308157117Smjacob		if (bitmap & (1 << mpt->unit)) {
309157662Smjacob			mpt->verbose = MPT_PRT_DEBUG2;
310157117Smjacob		}
311157117Smjacob	}
312157117Smjacob	bitmap = 0;
313157662Smjacob	if (getenv_int("mpt_debug3", &bitmap)) {
314157117Smjacob		if (bitmap & (1 << mpt->unit)) {
315157662Smjacob			mpt->verbose = MPT_PRT_DEBUG3;
316157117Smjacob		}
317157117Smjacob	}
318160290Smjacob
319160290Smjacob	mpt->cfg_role = MPT_ROLE_DEFAULT;
320160290Smjacob	bitmap = 0;
321160290Smjacob	if (getenv_int("mpt_nil_role", &bitmap)) {
322160290Smjacob		if (bitmap & (1 << mpt->unit)) {
323160290Smjacob			mpt->cfg_role = 0;
324160290Smjacob		}
325160290Smjacob		mpt->do_cfg_role = 1;
326160290Smjacob	}
327160290Smjacob	bitmap = 0;
328160290Smjacob	if (getenv_int("mpt_tgt_role", &bitmap)) {
329160290Smjacob		if (bitmap & (1 << mpt->unit)) {
330160290Smjacob			mpt->cfg_role |= MPT_ROLE_TARGET;
331160290Smjacob		}
332160290Smjacob		mpt->do_cfg_role = 1;
333160290Smjacob	}
334160290Smjacob	bitmap = 0;
335160290Smjacob	if (getenv_int("mpt_ini_role", &bitmap)) {
336160290Smjacob		if (bitmap & (1 << mpt->unit)) {
337160290Smjacob			mpt->cfg_role |= MPT_ROLE_INITIATOR;
338160290Smjacob		}
339160290Smjacob		mpt->do_cfg_role = 1;
340160290Smjacob	}
341164416Smjacob	mpt->msi_enable = 0;
342101704Smjacob}
343101704Smjacob#else
344101704Smjacobstatic void
345147883Sscottlmpt_set_options(struct mpt_softc *mpt)
346101704Smjacob{
347101704Smjacob	int tval;
348101704Smjacob
349101704Smjacob	tval = 0;
350101704Smjacob	if (resource_int_value(device_get_name(mpt->dev),
351101704Smjacob	    device_get_unit(mpt->dev), "disable", &tval) == 0 && tval != 0) {
352101704Smjacob		mpt->disabled = 1;
353101704Smjacob	}
354101704Smjacob	tval = 0;
355101704Smjacob	if (resource_int_value(device_get_name(mpt->dev),
356101704Smjacob	    device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) {
357159041Smjacob		mpt->verbose = tval;
358101704Smjacob	}
359160290Smjacob	tval = -1;
360157117Smjacob	if (resource_int_value(device_get_name(mpt->dev),
361160290Smjacob	    device_get_unit(mpt->dev), "role", &tval) == 0 && tval >= 0 &&
362157117Smjacob	    tval <= 3) {
363160290Smjacob		mpt->cfg_role = tval;
364160290Smjacob		mpt->do_cfg_role = 1;
365157117Smjacob	}
366164416Smjacob	tval = 0;
367164417Smjacob	mpt->msi_enable = 0;
368223985Smarius	if (mpt->is_sas)
369223985Smarius		mpt->msi_enable = 1;
370164416Smjacob	if (resource_int_value(device_get_name(mpt->dev),
371223985Smarius	    device_get_unit(mpt->dev), "msi_enable", &tval) == 0) {
372223985Smarius		mpt->msi_enable = tval;
373164416Smjacob	}
374101704Smjacob}
375101704Smjacob#endif
376101704Smjacob
377102303Smjacobstatic void
378147883Sscottlmpt_link_peer(struct mpt_softc *mpt)
379102303Smjacob{
380147883Sscottl	struct mpt_softc *mpt2;
381102303Smjacob
382157662Smjacob	if (mpt->unit == 0) {
383102303Smjacob		return;
384157662Smjacob	}
385102303Smjacob	/*
386102303Smjacob	 * XXX: depends on probe order
387102303Smjacob	 */
388147883Sscottl	mpt2 = (struct mpt_softc *)devclass_get_softc(mpt_devclass,mpt->unit-1);
389102303Smjacob
390102303Smjacob	if (mpt2 == NULL) {
391102303Smjacob		return;
392102303Smjacob	}
393102303Smjacob	if (pci_get_vendor(mpt2->dev) != pci_get_vendor(mpt->dev)) {
394102303Smjacob		return;
395102303Smjacob	}
396102303Smjacob	if (pci_get_device(mpt2->dev) != pci_get_device(mpt->dev)) {
397102303Smjacob		return;
398102303Smjacob	}
399102303Smjacob	mpt->mpt2 = mpt2;
400102303Smjacob	mpt2->mpt2 = mpt;
401147883Sscottl	if (mpt->verbose >= MPT_PRT_DEBUG) {
402147883Sscottl		mpt_prt(mpt, "linking with peer (mpt%d)\n",
403102303Smjacob		    device_get_unit(mpt2->dev));
404102303Smjacob	}
405102303Smjacob}
406102303Smjacob
407157662Smjacobstatic void
408157662Smjacobmpt_unlink_peer(struct mpt_softc *mpt)
409157662Smjacob{
410224493Smarius
411157662Smjacob	if (mpt->mpt2) {
412157662Smjacob		mpt->mpt2->mpt2 = NULL;
413157662Smjacob	}
414157662Smjacob}
415102303Smjacob
416101704Smjacobstatic int
417147883Sscottlmpt_pci_attach(device_t dev)
418101704Smjacob{
419147883Sscottl	struct mpt_softc *mpt;
420147883Sscottl	int		  iqd;
421147883Sscottl	uint32_t	  data, cmd;
422210943Smjacob	int		  mpt_io_bar, mpt_mem_bar;
423101704Smjacob
424101704Smjacob	/* Allocate the softc structure */
425147883Sscottl	mpt  = (struct mpt_softc*)device_get_softc(dev);
426101704Smjacob	if (mpt == NULL) {
427101704Smjacob		device_printf(dev, "cannot allocate softc\n");
428101704Smjacob		return (ENOMEM);
429101704Smjacob	}
430157354Smjacob	memset(mpt, 0, sizeof(struct mpt_softc));
431101704Smjacob	switch ((pci_get_device(dev) & ~1)) {
432101704Smjacob	case PCI_PRODUCT_LSI_FC909:
433102596Smjacob	case PCI_PRODUCT_LSI_FC909A:
434103829Smjacob	case PCI_PRODUCT_LSI_FC919:
435101704Smjacob	case PCI_PRODUCT_LSI_FC929:
436159494Smjacob	case PCI_PRODUCT_LSI_FC919X:
437162140Smjacob	case PCI_PRODUCT_LSI_FC646:
438158279Smjacob	case PCI_PRODUCT_LSI_FC7X04X:
439101704Smjacob		mpt->is_fc = 1;
440101704Smjacob		break;
441155521Smjacob	case PCI_PRODUCT_LSI_SAS1064:
442155521Smjacob	case PCI_PRODUCT_LSI_SAS1064A:
443155521Smjacob	case PCI_PRODUCT_LSI_SAS1064E:
444155521Smjacob	case PCI_PRODUCT_LSI_SAS1066:
445155521Smjacob	case PCI_PRODUCT_LSI_SAS1066E:
446155521Smjacob	case PCI_PRODUCT_LSI_SAS1068:
447155521Smjacob	case PCI_PRODUCT_LSI_SAS1068E:
448155521Smjacob	case PCI_PRODUCT_LSI_SAS1078:
449178896Sdelphij	case PCI_PRODUCT_LSI_SAS1078DE:
450155521Smjacob		mpt->is_sas = 1;
451155521Smjacob		break;
452101704Smjacob	default:
453159178Smjacob		mpt->is_spi = 1;
454101704Smjacob		break;
455101704Smjacob	}
456101704Smjacob	mpt->dev = dev;
457101704Smjacob	mpt->unit = device_get_unit(dev);
458147883Sscottl	mpt->raid_resync_rate = MPT_RAID_RESYNC_RATE_DEFAULT;
459147883Sscottl	mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT;
460147883Sscottl	mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT;
461155521Smjacob	mpt->verbose = MPT_PRT_NONE;
462157662Smjacob	mpt->role = MPT_ROLE_NONE;
463207287Smarius	mpt->mpt_ini_id = MPT_INI_ID_NONE;
464207287Smarius#ifdef __sparc64__
465207287Smarius	if (mpt->is_spi)
466207287Smarius		mpt->mpt_ini_id = OF_getscsinitid(dev);
467207287Smarius#endif
468101704Smjacob	mpt_set_options(mpt);
469155521Smjacob	if (mpt->verbose == MPT_PRT_NONE) {
470155521Smjacob		mpt->verbose = MPT_PRT_WARN;
471155521Smjacob		/* Print INFO level (if any) if bootverbose is set */
472155521Smjacob		mpt->verbose += (bootverbose != 0)? 1 : 0;
473155521Smjacob	}
474101704Smjacob	/* Make sure memory access decoders are enabled */
475101704Smjacob	cmd = pci_read_config(dev, PCIR_COMMAND, 2);
476101704Smjacob	if ((cmd & PCIM_CMD_MEMEN) == 0) {
477101704Smjacob		device_printf(dev, "Memory accesses disabled");
478157662Smjacob		return (ENXIO);
479101704Smjacob	}
480101704Smjacob
481101704Smjacob	/*
482101704Smjacob	 * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set.
483101704Smjacob	 */
484101704Smjacob	cmd |=
485101704Smjacob	    PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN |
486101704Smjacob	    PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
487101704Smjacob	pci_write_config(dev, PCIR_COMMAND, cmd, 2);
488101704Smjacob
489101704Smjacob	/*
490101704Smjacob	 * Make sure we've disabled the ROM.
491101704Smjacob	 */
492101704Smjacob	data = pci_read_config(dev, PCIR_BIOS, 4);
493201275Sjhb	data &= ~PCIM_BIOS_ENABLE;
494101704Smjacob	pci_write_config(dev, PCIR_BIOS, data, 4);
495101704Smjacob
496102303Smjacob	/*
497102303Smjacob	 * Is this part a dual?
498102303Smjacob	 * If so, link with our partner (around yet)
499102303Smjacob	 */
500102303Smjacob	if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929 ||
501162140Smjacob	    (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC646 ||
502158279Smjacob	    (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC7X04X ||
503102303Smjacob	    (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_1030) {
504102303Smjacob		mpt_link_peer(mpt);
505101704Smjacob	}
506101704Smjacob
507147883Sscottl	/*
508210943Smjacob	 * Figure out which are the I/O and MEM Bars
509210943Smjacob	 */
510210943Smjacob	data = pci_read_config(dev, PCIR_BAR(0), 4);
511210943Smjacob	if (PCI_BAR_IO(data)) {
512210943Smjacob		/* BAR0 is IO, BAR1 is memory */
513210943Smjacob		mpt_io_bar = 0;
514210943Smjacob		mpt_mem_bar = 1;
515210943Smjacob	} else {
516210943Smjacob		/* BAR0 is memory, BAR1 is IO */
517210943Smjacob		mpt_mem_bar = 0;
518210943Smjacob		mpt_io_bar = 1;
519210943Smjacob	}
520210943Smjacob
521210943Smjacob	/*
522147883Sscottl	 * Set up register access.  PIO mode is required for
523155521Smjacob	 * certain reset operations (but must be disabled for
524155521Smjacob	 * some cards otherwise).
525147883Sscottl	 */
526223985Smarius	mpt_io_bar = PCIR_BAR(mpt_io_bar);
527216764Sjhb	mpt->pci_pio_reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
528223985Smarius	    &mpt_io_bar, RF_ACTIVE);
529147883Sscottl	if (mpt->pci_pio_reg == NULL) {
530147883Sscottl		device_printf(dev, "unable to map registers in PIO mode\n");
531147883Sscottl		goto bad;
532147883Sscottl	}
533147883Sscottl	mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg);
534147883Sscottl	mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg);
535147883Sscottl
536101704Smjacob	/* Allocate kernel virtual memory for the 9x9's Mem0 region */
537223985Smarius	mpt_mem_bar = PCIR_BAR(mpt_mem_bar);
538216764Sjhb	mpt->pci_reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
539223985Smarius	    &mpt_mem_bar, RF_ACTIVE);
540101704Smjacob	if (mpt->pci_reg == NULL) {
541147883Sscottl		device_printf(dev, "Unable to memory map registers.\n");
542155521Smjacob		if (mpt->is_sas) {
543155521Smjacob			device_printf(dev, "Giving Up.\n");
544155521Smjacob			goto bad;
545155521Smjacob		}
546147883Sscottl		device_printf(dev, "Falling back to PIO mode.\n");
547147883Sscottl		mpt->pci_st = mpt->pci_pio_st;
548147883Sscottl		mpt->pci_sh = mpt->pci_pio_sh;
549147883Sscottl	} else {
550147883Sscottl		mpt->pci_st = rman_get_bustag(mpt->pci_reg);
551147883Sscottl		mpt->pci_sh = rman_get_bushandle(mpt->pci_reg);
552101704Smjacob	}
553101704Smjacob
554101704Smjacob	/* Get a handle to the interrupt */
555101704Smjacob	iqd = 0;
556166721Sjhb	if (mpt->msi_enable) {
557166721Sjhb		/*
558166721Sjhb		 * First try to alloc an MSI-X message.  If that
559166721Sjhb		 * fails, then try to alloc an MSI message instead.
560166721Sjhb		 */
561166721Sjhb		if (pci_msix_count(dev) == 1) {
562166721Sjhb			mpt->pci_msi_count = 1;
563166721Sjhb			if (pci_alloc_msix(dev, &mpt->pci_msi_count) == 0) {
564166721Sjhb				iqd = 1;
565166721Sjhb			} else {
566166721Sjhb				mpt->pci_msi_count = 0;
567166721Sjhb			}
568164416Smjacob		}
569166721Sjhb		if (iqd == 0 && pci_msi_count(dev) == 1) {
570166721Sjhb			mpt->pci_msi_count = 1;
571166721Sjhb			if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) {
572166721Sjhb				iqd = 1;
573166721Sjhb			} else {
574166721Sjhb				mpt->pci_msi_count = 0;
575166721Sjhb			}
576166721Sjhb		}
577166721Sjhb	}
578127135Snjl	mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
579223985Smarius	    RF_ACTIVE | (mpt->pci_msi_count ? 0 : RF_SHAREABLE));
580101704Smjacob	if (mpt->pci_irq == NULL) {
581101704Smjacob		device_printf(dev, "could not allocate interrupt\n");
582101704Smjacob		goto bad;
583101704Smjacob	}
584101704Smjacob
585147883Sscottl	MPT_LOCK_SETUP(mpt);
586147883Sscottl
587147883Sscottl	/* Disable interrupts at the part */
588147883Sscottl	mpt_disable_ints(mpt);
589147883Sscottl
590101704Smjacob	/* Register the interrupt handler */
591166935Smjacob	if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr,
592101704Smjacob	    mpt, &mpt->ih)) {
593101704Smjacob		device_printf(dev, "could not setup interrupt\n");
594101704Smjacob		goto bad;
595101704Smjacob	}
596101704Smjacob
597101704Smjacob	/* Allocate dma memory */
598101704Smjacob	if (mpt_dma_mem_alloc(mpt)) {
599159091Smjacob		mpt_prt(mpt, "Could not allocate DMA memory\n");
600101704Smjacob		goto bad;
601101704Smjacob	}
602101704Smjacob
603102199Smjacob	/*
604102199Smjacob	 * Save the PCI config register values
605102199Smjacob 	 *
606102199Smjacob	 * Hard resets are known to screw up the BAR for diagnostic
607102199Smjacob	 * memory accesses (Mem1).
608102199Smjacob	 *
609102199Smjacob	 * Using Mem1 is known to make the chip stop responding to
610102199Smjacob	 * configuration space transfers, so we need to save it now
611102199Smjacob	 */
612101704Smjacob
613101704Smjacob	mpt_read_config_regs(mpt);
614101704Smjacob
615155521Smjacob	/*
616155521Smjacob	 * Disable PIO until we need it
617155521Smjacob	 */
618159919Smjacob	if (mpt->is_sas) {
619159919Smjacob		pci_disable_io(dev, SYS_RES_IOPORT);
620159919Smjacob	}
621155521Smjacob
622101704Smjacob	/* Initialize the hardware */
623101704Smjacob	if (mpt->disabled == 0) {
624147883Sscottl		if (mpt_attach(mpt) != 0) {
625101704Smjacob			goto bad;
626102199Smjacob		}
627157117Smjacob	} else {
628157117Smjacob		mpt_prt(mpt, "device disabled at user request\n");
629157117Smjacob		goto bad;
630101704Smjacob	}
631101704Smjacob
632157117Smjacob	mpt->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, mpt_pci_shutdown,
633157117Smjacob	    dev, SHUTDOWN_PRI_DEFAULT);
634157117Smjacob
635157117Smjacob	if (mpt->eh == NULL) {
636157117Smjacob		mpt_prt(mpt, "shutdown event registration failed\n");
637157117Smjacob		(void) mpt_detach(mpt);
638157117Smjacob		goto bad;
639157117Smjacob	}
640101704Smjacob	return (0);
641101704Smjacob
642101704Smjacobbad:
643101704Smjacob	mpt_dma_mem_free(mpt);
644101704Smjacob	mpt_free_bus_resources(mpt);
645157662Smjacob	mpt_unlink_peer(mpt);
646101704Smjacob
647157662Smjacob	MPT_LOCK_DESTROY(mpt);
648157662Smjacob
649101704Smjacob	/*
650101704Smjacob	 * but return zero to preserve unit numbering
651101704Smjacob	 */
652101704Smjacob	return (0);
653101704Smjacob}
654101704Smjacob
655102199Smjacob/*
656101704Smjacob * Free bus resources
657101704Smjacob */
658101704Smjacobstatic void
659147883Sscottlmpt_free_bus_resources(struct mpt_softc *mpt)
660101704Smjacob{
661224493Smarius
662101704Smjacob	if (mpt->ih) {
663101704Smjacob		bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih);
664223985Smarius		mpt->ih = NULL;
665101704Smjacob	}
666101704Smjacob
667101704Smjacob	if (mpt->pci_irq) {
668164305Sjhb		bus_release_resource(mpt->dev, SYS_RES_IRQ,
669223985Smarius		    rman_get_rid(mpt->pci_irq), mpt->pci_irq);
670223985Smarius		mpt->pci_irq = NULL;
671101704Smjacob	}
672101704Smjacob
673164305Sjhb	if (mpt->pci_msi_count) {
674164305Sjhb		pci_release_msi(mpt->dev);
675164305Sjhb		mpt->pci_msi_count = 0;
676164305Sjhb	}
677164305Sjhb
678147883Sscottl	if (mpt->pci_pio_reg) {
679223985Smarius		bus_release_resource(mpt->dev, SYS_RES_IOPORT,
680223985Smarius		    rman_get_rid(mpt->pci_pio_reg), mpt->pci_pio_reg);
681223985Smarius		mpt->pci_pio_reg = NULL;
682147883Sscottl	}
683101704Smjacob	if (mpt->pci_reg) {
684223985Smarius		bus_release_resource(mpt->dev, SYS_RES_MEMORY,
685223985Smarius		    rman_get_rid(mpt->pci_reg), mpt->pci_reg);
686223985Smarius		mpt->pci_reg = NULL;
687101704Smjacob	}
688102199Smjacob	MPT_LOCK_DESTROY(mpt);
689101704Smjacob}
690101704Smjacob
691102199Smjacob/*
692101704Smjacob * Disconnect ourselves from the system.
693101704Smjacob */
694101704Smjacobstatic int
695147883Sscottlmpt_pci_detach(device_t dev)
696101704Smjacob{
697147883Sscottl	struct mpt_softc *mpt;
698101704Smjacob
699147883Sscottl	mpt  = (struct mpt_softc*)device_get_softc(dev);
700101704Smjacob
701101704Smjacob	if (mpt) {
702101704Smjacob		mpt_disable_ints(mpt);
703147883Sscottl		mpt_detach(mpt);
704147883Sscottl		mpt_reset(mpt, /*reinit*/FALSE);
705101704Smjacob		mpt_dma_mem_free(mpt);
706101704Smjacob		mpt_free_bus_resources(mpt);
707158982Smjacob		mpt_raid_free_mem(mpt);
708158982Smjacob		if (mpt->eh != NULL) {
709180152Sjhb                        EVENTHANDLER_DEREGISTER(shutdown_post_sync, mpt->eh);
710147883Sscottl		}
711101704Smjacob	}
712101704Smjacob	return(0);
713101704Smjacob}
714101704Smjacob
715102199Smjacob/*
716101704Smjacob * Disable the hardware
717101704Smjacob */
718101704Smjacobstatic int
719147883Sscottlmpt_pci_shutdown(device_t dev)
720101704Smjacob{
721147883Sscottl	struct mpt_softc *mpt;
722101704Smjacob
723147883Sscottl	mpt = (struct mpt_softc *)device_get_softc(dev);
724157117Smjacob	if (mpt) {
725157117Smjacob		int r;
726157117Smjacob		r = mpt_shutdown(mpt);
727157117Smjacob		return (r);
728157117Smjacob	}
729101704Smjacob	return(0);
730101704Smjacob}
731101704Smjacob
732101704Smjacobstatic int
733147883Sscottlmpt_dma_mem_alloc(struct mpt_softc *mpt)
734101704Smjacob{
735103871Smjacob	size_t len;
736147883Sscottl	struct mpt_map_info mi;
737101704Smjacob
738101704Smjacob	/* Check if we alreay have allocated the reply memory */
739123740Speter	if (mpt->reply_phys != 0) {
740101704Smjacob		return 0;
741103871Smjacob	}
742101704Smjacob
743147883Sscottl	len = sizeof (request_t) * MPT_MAX_REQUESTS(mpt);
744103871Smjacob#ifdef	RELENG_4
745147883Sscottl	mpt->request_pool = (request_t *)malloc(len, M_DEVBUF, M_WAITOK);
746103871Smjacob	if (mpt->request_pool == NULL) {
747159091Smjacob		mpt_prt(mpt, "cannot allocate request pool\n");
748103871Smjacob		return (1);
749103871Smjacob	}
750157354Smjacob	memset(mpt->request_pool, 0, len);
751103871Smjacob#else
752147883Sscottl	mpt->request_pool = (request_t *)malloc(len, M_DEVBUF, M_WAITOK|M_ZERO);
753103871Smjacob	if (mpt->request_pool == NULL) {
754159091Smjacob		mpt_prt(mpt, "cannot allocate request pool\n");
755103871Smjacob		return (1);
756103871Smjacob	}
757103871Smjacob#endif
758103871Smjacob
759101704Smjacob	/*
760155521Smjacob	 * Create a parent dma tag for this device.
761101704Smjacob	 *
762159091Smjacob	 * Align at byte boundaries,
763159091Smjacob	 * Limit to 32-bit addressing for request/reply queues.
764101704Smjacob	 */
765164314Sjb	if (mpt_dma_tag_create(mpt, /*parent*/bus_get_dma_tag(mpt->dev),
766164314Sjb	    /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR,
767147883Sscottl	    /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL,
768147883Sscottl	    /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
769209961Smarius	    /*nsegments*/BUS_SPACE_UNRESTRICTED,
770209961Smarius	    /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0,
771147883Sscottl	    &mpt->parent_dmat) != 0) {
772159091Smjacob		mpt_prt(mpt, "cannot create parent dma tag\n");
773101704Smjacob		return (1);
774101704Smjacob	}
775101704Smjacob
776101704Smjacob	/* Create a child tag for reply buffers */
777159091Smjacob	if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE, 0,
778159091Smjacob	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
779155521Smjacob	    NULL, NULL, 2 * PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
780147883Sscottl	    &mpt->reply_dmat) != 0) {
781159091Smjacob		mpt_prt(mpt, "cannot create a dma tag for replies\n");
782101704Smjacob		return (1);
783101704Smjacob	}
784101704Smjacob
785220945Smarius	/* Allocate some DMA accessible memory for replies */
786101704Smjacob	if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply,
787101704Smjacob	    BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) {
788159091Smjacob		mpt_prt(mpt, "cannot allocate %lu bytes of reply memory\n",
789155521Smjacob		    (u_long) (2 * PAGE_SIZE));
790101704Smjacob		return (1);
791101704Smjacob	}
792101704Smjacob
793147883Sscottl	mi.mpt = mpt;
794147883Sscottl	mi.error = 0;
795101704Smjacob
796101704Smjacob	/* Load and lock it into "bus space" */
797101704Smjacob	bus_dmamap_load(mpt->reply_dmat, mpt->reply_dmap, mpt->reply,
798155521Smjacob	    2 * PAGE_SIZE, mpt_map_rquest, &mi, 0);
799101704Smjacob
800147883Sscottl	if (mi.error) {
801159091Smjacob		mpt_prt(mpt, "error %d loading dma map for DMA reply queue\n",
802159091Smjacob		    mi.error);
803101704Smjacob		return (1);
804101704Smjacob	}
805147883Sscottl	mpt->reply_phys = mi.phys;
806101704Smjacob
807101704Smjacob	return (0);
808101704Smjacob}
809101704Smjacob
810101704Smjacob/* Deallocate memory that was allocated by mpt_dma_mem_alloc
811101704Smjacob */
812101704Smjacobstatic void
813147883Sscottlmpt_dma_mem_free(struct mpt_softc *mpt)
814101704Smjacob{
815101704Smjacob
816101704Smjacob        /* Make sure we aren't double destroying */
817101704Smjacob        if (mpt->reply_dmat == 0) {
818159091Smjacob		mpt_lprt(mpt, MPT_PRT_DEBUG, "already released dma memory\n");
819101704Smjacob		return;
820101704Smjacob        }
821101704Smjacob
822101704Smjacob	bus_dmamap_unload(mpt->reply_dmat, mpt->reply_dmap);
823101704Smjacob	bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap);
824101704Smjacob	bus_dma_tag_destroy(mpt->reply_dmat);
825101704Smjacob	bus_dma_tag_destroy(mpt->parent_dmat);
826223985Smarius	mpt->reply_dmat = NULL;
827103871Smjacob	free(mpt->request_pool, M_DEVBUF);
828223985Smarius	mpt->request_pool = NULL;
829101704Smjacob}
830101704Smjacob
831101704Smjacob/* Reads modifiable (via PCI transactions) config registers */
832101704Smjacobstatic void
833147883Sscottlmpt_read_config_regs(struct mpt_softc *mpt)
834101704Smjacob{
835224493Smarius
836101704Smjacob	mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2);
837101704Smjacob	mpt->pci_cfg.LatencyTimer_LineSize =
838101704Smjacob	    pci_read_config(mpt->dev, PCIR_CACHELNSZ, 2);
839119690Sjhb	mpt->pci_cfg.IO_BAR = pci_read_config(mpt->dev, PCIR_BAR(0), 4);
840119690Sjhb	mpt->pci_cfg.Mem0_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(1), 4);
841119690Sjhb	mpt->pci_cfg.Mem0_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(2), 4);
842119690Sjhb	mpt->pci_cfg.Mem1_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(3), 4);
843119690Sjhb	mpt->pci_cfg.Mem1_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(4), 4);
844101704Smjacob	mpt->pci_cfg.ROM_BAR = pci_read_config(mpt->dev, PCIR_BIOS, 4);
845101704Smjacob	mpt->pci_cfg.IntLine = pci_read_config(mpt->dev, PCIR_INTLINE, 1);
846101704Smjacob	mpt->pci_cfg.PMCSR = pci_read_config(mpt->dev, 0x44, 4);
847101704Smjacob}
848101704Smjacob
849224493Smarius#if 0
850101704Smjacob/* Sets modifiable config registers */
851224493Smariusstatic void
852147883Sscottlmpt_set_config_regs(struct mpt_softc *mpt)
853101704Smjacob{
854147883Sscottl	uint32_t val;
855101704Smjacob
856101704Smjacob#define MPT_CHECK(reg, offset, size)					\
857101704Smjacob	val = pci_read_config(mpt->dev, offset, size);			\
858101704Smjacob	if (mpt->pci_cfg.reg != val) {					\
859103914Smjacob		mpt_prt(mpt,						\
860101704Smjacob		    "Restoring " #reg " to 0x%X from 0x%X\n",		\
861101704Smjacob		    mpt->pci_cfg.reg, val);				\
862101704Smjacob	}
863101704Smjacob
864147883Sscottl	if (mpt->verbose >= MPT_PRT_DEBUG) {
865101704Smjacob		MPT_CHECK(Command, PCIR_COMMAND, 2);
866101704Smjacob		MPT_CHECK(LatencyTimer_LineSize, PCIR_CACHELNSZ, 2);
867119690Sjhb		MPT_CHECK(IO_BAR, PCIR_BAR(0), 4);
868119690Sjhb		MPT_CHECK(Mem0_BAR[0], PCIR_BAR(1), 4);
869119690Sjhb		MPT_CHECK(Mem0_BAR[1], PCIR_BAR(2), 4);
870119690Sjhb		MPT_CHECK(Mem1_BAR[0], PCIR_BAR(3), 4);
871119690Sjhb		MPT_CHECK(Mem1_BAR[1], PCIR_BAR(4), 4);
872101704Smjacob		MPT_CHECK(ROM_BAR, PCIR_BIOS, 4);
873101704Smjacob		MPT_CHECK(IntLine, PCIR_INTLINE, 1);
874101704Smjacob		MPT_CHECK(PMCSR, 0x44, 4);
875101704Smjacob	}
876101704Smjacob#undef MPT_CHECK
877101704Smjacob
878101704Smjacob	pci_write_config(mpt->dev, PCIR_COMMAND, mpt->pci_cfg.Command, 2);
879101704Smjacob	pci_write_config(mpt->dev, PCIR_CACHELNSZ,
880101704Smjacob	    mpt->pci_cfg.LatencyTimer_LineSize, 2);
881119690Sjhb	pci_write_config(mpt->dev, PCIR_BAR(0), mpt->pci_cfg.IO_BAR, 4);
882119690Sjhb	pci_write_config(mpt->dev, PCIR_BAR(1), mpt->pci_cfg.Mem0_BAR[0], 4);
883119690Sjhb	pci_write_config(mpt->dev, PCIR_BAR(2), mpt->pci_cfg.Mem0_BAR[1], 4);
884119690Sjhb	pci_write_config(mpt->dev, PCIR_BAR(3), mpt->pci_cfg.Mem1_BAR[0], 4);
885119690Sjhb	pci_write_config(mpt->dev, PCIR_BAR(4), mpt->pci_cfg.Mem1_BAR[1], 4);
886101704Smjacob	pci_write_config(mpt->dev, PCIR_BIOS, mpt->pci_cfg.ROM_BAR, 4);
887101704Smjacob	pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1);
888101704Smjacob	pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4);
889101704Smjacob}
890224493Smarius#endif
891102199Smjacob
892102199Smjacobstatic void
893102199Smjacobmpt_pci_intr(void *arg)
894102199Smjacob{
895147883Sscottl	struct mpt_softc *mpt;
896147883Sscottl
897147883Sscottl	mpt = (struct mpt_softc *)arg;
898102199Smjacob	MPT_LOCK(mpt);
899147883Sscottl	mpt_intr(mpt);
900102199Smjacob	MPT_UNLOCK(mpt);
901102199Smjacob}
902