]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/mpt/mpt_pci.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / mpt / mpt_pci.c
1 /*-
2  * PCI specific probe and attach routines for LSI Fusion Adapters
3  * FreeBSD Version.
4  *
5  * Copyright (c) 2000, 2001 by Greg Ansley
6  * Partially derived from Matt Jacob's ISP driver.
7  * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 by Matthew Jacob
8  * Feral Software
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice immediately at the beginning of the file, without modification,
16  *    this list of conditions, and the following disclaimer.
17  * 2. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
24  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 /*-
33  * Copyright (c) 2002, 2006 by Matthew Jacob
34  * All rights reserved.
35  * 
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions are
38  * met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
42  *    substantially similar to the "NO WARRANTY" disclaimer below
43  *    ("Disclaimer") and any redistribution must be conditioned upon including
44  *    a substantially similar Disclaimer requirement for further binary
45  *    redistribution.
46  * 3. Neither the names of the above listed copyright holders nor the names
47  *    of any contributors may be used to endorse or promote products derived
48  *    from this software without specific prior written permission.
49  * 
50  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
51  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
54  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
60  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61  *
62  * Support from Chris Ellsworth in order to make SAS adapters work
63  * is gratefully acknowledged.
64  *
65  * Support from LSI-Logic has also gone a great deal toward making this a
66  * workable subsystem and is gratefully acknowledged.
67  */
68 /*
69  * Copyright (c) 2004, Avid Technology, Inc. and its contributors.
70  * Copyright (c) 2005, WHEEL Sp. z o.o.
71  * Copyright (c) 2004, 2005 Justin T. Gibbs
72  * All rights reserved.
73  * 
74  * Redistribution and use in source and binary forms, with or without
75  * modification, are permitted provided that the following conditions are
76  * met:
77  * 1. Redistributions of source code must retain the above copyright
78  *    notice, this list of conditions and the following disclaimer.
79  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
80  *    substantially similar to the "NO WARRANTY" disclaimer below
81  *    ("Disclaimer") and any redistribution must be conditioned upon including
82  *    a substantially similar Disclaimer requirement for further binary
83  *    redistribution.
84  * 3. Neither the names of the above listed copyright holders nor the names
85  *    of any contributors may be used to endorse or promote products derived
86  *    from this software without specific prior written permission.
87  * 
88  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
89  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
90  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
91  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
92  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
93  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
94  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
95  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
96  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
97  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
98  * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99  */
100
101 #include <sys/cdefs.h>
102 __FBSDID("$FreeBSD$");
103
104 #include <dev/mpt/mpt.h>
105 #include <dev/mpt/mpt_cam.h>
106 #include <dev/mpt/mpt_raid.h>
107
108 #if __FreeBSD_version < 700000
109 #define pci_msix_count(x)       0
110 #define pci_msi_count(x)        0
111 #define pci_alloc_msi(x, y)     1
112 #define pci_alloc_msix(x, y)    1
113 #define pci_release_msi(x)      do { ; } while (0)
114 #endif
115
116 #ifndef PCI_VENDOR_LSI
117 #define PCI_VENDOR_LSI                  0x1000
118 #endif
119
120 #ifndef PCI_PRODUCT_LSI_FC909
121 #define PCI_PRODUCT_LSI_FC909           0x0620
122 #endif
123
124 #ifndef PCI_PRODUCT_LSI_FC909A
125 #define PCI_PRODUCT_LSI_FC909A          0x0621
126 #endif
127
128 #ifndef PCI_PRODUCT_LSI_FC919
129 #define PCI_PRODUCT_LSI_FC919           0x0624
130 #endif
131
132 #ifndef PCI_PRODUCT_LSI_FC929
133 #define PCI_PRODUCT_LSI_FC929           0x0622
134 #endif
135
136 #ifndef PCI_PRODUCT_LSI_FC929X
137 #define PCI_PRODUCT_LSI_FC929X          0x0626
138 #endif
139
140 #ifndef PCI_PRODUCT_LSI_FC919X
141 #define PCI_PRODUCT_LSI_FC919X          0x0628
142 #endif
143
144 #ifndef PCI_PRODUCT_LSI_FC7X04X
145 #define PCI_PRODUCT_LSI_FC7X04X         0x0640
146 #endif
147
148 #ifndef PCI_PRODUCT_LSI_FC646
149 #define PCI_PRODUCT_LSI_FC646           0x0646
150 #endif
151
152 #ifndef PCI_PRODUCT_LSI_1030
153 #define PCI_PRODUCT_LSI_1030            0x0030
154 #endif
155
156 #ifndef PCI_PRODUCT_LSI_SAS1064
157 #define PCI_PRODUCT_LSI_SAS1064         0x0050
158 #endif
159
160 #ifndef PCI_PRODUCT_LSI_SAS1064A
161 #define PCI_PRODUCT_LSI_SAS1064A        0x005C
162 #endif
163
164 #ifndef PCI_PRODUCT_LSI_SAS1064E
165 #define PCI_PRODUCT_LSI_SAS1064E        0x0056
166 #endif
167
168 #ifndef PCI_PRODUCT_LSI_SAS1066
169 #define PCI_PRODUCT_LSI_SAS1066         0x005E
170 #endif
171
172 #ifndef PCI_PRODUCT_LSI_SAS1066E
173 #define PCI_PRODUCT_LSI_SAS1066E        0x005A
174 #endif
175
176 #ifndef PCI_PRODUCT_LSI_SAS1068
177 #define PCI_PRODUCT_LSI_SAS1068         0x0054
178 #endif
179
180 #ifndef PCI_PRODUCT_LSI_SAS1068E
181 #define PCI_PRODUCT_LSI_SAS1068E        0x0058
182 #endif
183
184 #ifndef PCI_PRODUCT_LSI_SAS1078
185 #define PCI_PRODUCT_LSI_SAS1078         0x0062
186 #endif
187
188 #ifndef PCI_PRODUCT_LSI_SAS1078DE
189 #define PCI_PRODUCT_LSI_SAS1078DE       0x007C
190 #endif
191
192 #ifndef PCIM_CMD_SERRESPEN
193 #define PCIM_CMD_SERRESPEN      0x0100
194 #endif
195
196
197 #define MPT_IO_BAR      0
198 #define MPT_MEM_BAR     1
199
200 static int mpt_pci_probe(device_t);
201 static int mpt_pci_attach(device_t);
202 static void mpt_free_bus_resources(struct mpt_softc *mpt);
203 static int mpt_pci_detach(device_t);
204 static int mpt_pci_shutdown(device_t);
205 static int mpt_dma_mem_alloc(struct mpt_softc *mpt);
206 static void mpt_dma_mem_free(struct mpt_softc *mpt);
207 static void mpt_read_config_regs(struct mpt_softc *mpt);
208 static void mpt_pci_intr(void *);
209
210 static device_method_t mpt_methods[] = {
211         /* Device interface */
212         DEVMETHOD(device_probe,         mpt_pci_probe),
213         DEVMETHOD(device_attach,        mpt_pci_attach),
214         DEVMETHOD(device_detach,        mpt_pci_detach),
215         DEVMETHOD(device_shutdown,      mpt_pci_shutdown),
216         { 0, 0 }
217 };
218
219 static driver_t mpt_driver = {
220         "mpt", mpt_methods, sizeof(struct mpt_softc)
221 };
222 static devclass_t mpt_devclass;
223 DRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0);
224 MODULE_DEPEND(mpt, pci, 1, 1, 1);
225 MODULE_VERSION(mpt, 1);
226
227 static int
228 mpt_pci_probe(device_t dev)
229 {
230         char *desc;
231
232         if (pci_get_vendor(dev) != PCI_VENDOR_LSI) {
233                 return (ENXIO);
234         }
235
236         switch ((pci_get_device(dev) & ~1)) {
237         case PCI_PRODUCT_LSI_FC909:
238                 desc = "LSILogic FC909 FC Adapter";
239                 break;
240         case PCI_PRODUCT_LSI_FC909A:
241                 desc = "LSILogic FC909A FC Adapter";
242                 break;
243         case PCI_PRODUCT_LSI_FC919:
244                 desc = "LSILogic FC919 FC Adapter";
245                 break;
246         case PCI_PRODUCT_LSI_FC929:
247                 desc = "Dual LSILogic FC929 FC Adapter";
248                 break;
249         case PCI_PRODUCT_LSI_FC919X:
250                 desc = "LSILogic FC919 FC PCI-X Adapter";
251                 break;
252         case PCI_PRODUCT_LSI_FC929X:
253                 desc = "Dual LSILogic FC929X 2Gb/s FC PCI-X Adapter";
254                 break;
255         case PCI_PRODUCT_LSI_FC646:
256                 desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-Express Adapter";
257                 break;
258         case PCI_PRODUCT_LSI_FC7X04X:
259                 desc = "Dual LSILogic FC7X04X 4Gb/s FC PCI-X Adapter";
260                 break;
261         case PCI_PRODUCT_LSI_1030:
262                 desc = "LSILogic 1030 Ultra4 Adapter";
263                 break;
264         case PCI_PRODUCT_LSI_SAS1064:
265         case PCI_PRODUCT_LSI_SAS1064A:
266         case PCI_PRODUCT_LSI_SAS1064E:
267         case PCI_PRODUCT_LSI_SAS1066:
268         case PCI_PRODUCT_LSI_SAS1066E:
269         case PCI_PRODUCT_LSI_SAS1068:
270         case PCI_PRODUCT_LSI_SAS1068E:
271         case PCI_PRODUCT_LSI_SAS1078:
272         case PCI_PRODUCT_LSI_SAS1078DE:
273                 desc = "LSILogic SAS/SATA Adapter";
274                 break;
275         default:
276                 return (ENXIO);
277         }
278
279         device_set_desc(dev, desc);
280         return (0);
281 }
282
283 #if     __FreeBSD_version < 500000  
284 static void
285 mpt_set_options(struct mpt_softc *mpt)
286 {
287         int bitmap;
288
289         bitmap = 0;
290         if (getenv_int("mpt_disable", &bitmap)) {
291                 if (bitmap & (1 << mpt->unit)) {
292                         mpt->disabled = 1;
293                 }
294         }
295         bitmap = 0;
296         if (getenv_int("mpt_debug", &bitmap)) {
297                 if (bitmap & (1 << mpt->unit)) {
298                         mpt->verbose = MPT_PRT_DEBUG;
299                 }
300         }
301         bitmap = 0;
302         if (getenv_int("mpt_debug1", &bitmap)) {
303                 if (bitmap & (1 << mpt->unit)) {
304                         mpt->verbose = MPT_PRT_DEBUG1;
305                 }
306         }
307         bitmap = 0;
308         if (getenv_int("mpt_debug2", &bitmap)) {
309                 if (bitmap & (1 << mpt->unit)) {
310                         mpt->verbose = MPT_PRT_DEBUG2;
311                 }
312         }
313         bitmap = 0;
314         if (getenv_int("mpt_debug3", &bitmap)) {
315                 if (bitmap & (1 << mpt->unit)) {
316                         mpt->verbose = MPT_PRT_DEBUG3;
317                 }
318         }
319
320         mpt->cfg_role = MPT_ROLE_DEFAULT;
321         bitmap = 0;
322         if (getenv_int("mpt_nil_role", &bitmap)) {
323                 if (bitmap & (1 << mpt->unit)) {
324                         mpt->cfg_role = 0;
325                 }
326                 mpt->do_cfg_role = 1;
327         }
328         bitmap = 0;
329         if (getenv_int("mpt_tgt_role", &bitmap)) {
330                 if (bitmap & (1 << mpt->unit)) {
331                         mpt->cfg_role |= MPT_ROLE_TARGET;
332                 }
333                 mpt->do_cfg_role = 1;
334         }
335         bitmap = 0;
336         if (getenv_int("mpt_ini_role", &bitmap)) {
337                 if (bitmap & (1 << mpt->unit)) {
338                         mpt->cfg_role |= MPT_ROLE_INITIATOR;
339                 }
340                 mpt->do_cfg_role = 1;
341         }
342         mpt->msi_enable = 0;
343 }
344 #else
345 static void
346 mpt_set_options(struct mpt_softc *mpt)
347 {
348         int tval;
349
350         tval = 0;
351         if (resource_int_value(device_get_name(mpt->dev),
352             device_get_unit(mpt->dev), "disable", &tval) == 0 && tval != 0) {
353                 mpt->disabled = 1;
354         }
355         tval = 0;
356         if (resource_int_value(device_get_name(mpt->dev),
357             device_get_unit(mpt->dev), "debug", &tval) == 0 && tval != 0) {
358                 mpt->verbose = tval;
359         }
360         tval = -1;
361         if (resource_int_value(device_get_name(mpt->dev),
362             device_get_unit(mpt->dev), "role", &tval) == 0 && tval >= 0 &&
363             tval <= 3) {
364                 mpt->cfg_role = tval;
365                 mpt->do_cfg_role = 1;
366         }
367
368         tval = 0;
369         mpt->msi_enable = 0;
370         if (resource_int_value(device_get_name(mpt->dev),
371             device_get_unit(mpt->dev), "msi_enable", &tval) == 0 && tval == 1) {
372                 mpt->msi_enable = 1;
373         }
374 }
375 #endif
376
377
378 static void
379 mpt_link_peer(struct mpt_softc *mpt)
380 {
381         struct mpt_softc *mpt2;
382
383         if (mpt->unit == 0) {
384                 return;
385         }
386         /*
387          * XXX: depends on probe order
388          */
389         mpt2 = (struct mpt_softc *)devclass_get_softc(mpt_devclass,mpt->unit-1);
390
391         if (mpt2 == NULL) {
392                 return;
393         }
394         if (pci_get_vendor(mpt2->dev) != pci_get_vendor(mpt->dev)) {
395                 return;
396         }
397         if (pci_get_device(mpt2->dev) != pci_get_device(mpt->dev)) {
398                 return;
399         }
400         mpt->mpt2 = mpt2;
401         mpt2->mpt2 = mpt;
402         if (mpt->verbose >= MPT_PRT_DEBUG) {
403                 mpt_prt(mpt, "linking with peer (mpt%d)\n",
404                     device_get_unit(mpt2->dev));
405         }
406 }
407
408 static void
409 mpt_unlink_peer(struct mpt_softc *mpt)
410 {
411         if (mpt->mpt2) {
412                 mpt->mpt2->mpt2 = NULL;
413         }
414 }
415
416
417 static int
418 mpt_pci_attach(device_t dev)
419 {
420         struct mpt_softc *mpt;
421         int               iqd;
422         uint32_t          data, cmd;
423
424         /* Allocate the softc structure */
425         mpt  = (struct mpt_softc*)device_get_softc(dev);
426         if (mpt == NULL) {
427                 device_printf(dev, "cannot allocate softc\n");
428                 return (ENOMEM);
429         }
430         memset(mpt, 0, sizeof(struct mpt_softc));
431         switch ((pci_get_device(dev) & ~1)) {
432         case PCI_PRODUCT_LSI_FC909:
433         case PCI_PRODUCT_LSI_FC909A:
434         case PCI_PRODUCT_LSI_FC919:
435         case PCI_PRODUCT_LSI_FC929:
436         case PCI_PRODUCT_LSI_FC919X:
437         case PCI_PRODUCT_LSI_FC646:
438         case PCI_PRODUCT_LSI_FC7X04X:
439                 mpt->is_fc = 1;
440                 break;
441         case PCI_PRODUCT_LSI_SAS1064:
442         case PCI_PRODUCT_LSI_SAS1064A:
443         case PCI_PRODUCT_LSI_SAS1064E:
444         case PCI_PRODUCT_LSI_SAS1066:
445         case PCI_PRODUCT_LSI_SAS1066E:
446         case PCI_PRODUCT_LSI_SAS1068:
447         case PCI_PRODUCT_LSI_SAS1068E:
448         case PCI_PRODUCT_LSI_SAS1078:
449         case PCI_PRODUCT_LSI_SAS1078DE:
450                 mpt->is_sas = 1;
451                 break;
452         default:
453                 mpt->is_spi = 1;
454                 break;
455         }
456         mpt->dev = dev;
457         mpt->unit = device_get_unit(dev);
458         mpt->raid_resync_rate = MPT_RAID_RESYNC_RATE_DEFAULT;
459         mpt->raid_mwce_setting = MPT_RAID_MWCE_DEFAULT;
460         mpt->raid_queue_depth = MPT_RAID_QUEUE_DEPTH_DEFAULT;
461         mpt->verbose = MPT_PRT_NONE;
462         mpt->role = MPT_ROLE_NONE;
463         mpt->mpt_ini_id = MPT_INI_ID_NONE;
464 #ifdef __sparc64__
465         if (mpt->is_spi)
466                 mpt->mpt_ini_id = OF_getscsinitid(dev);
467 #endif
468         mpt_set_options(mpt);
469         if (mpt->verbose == MPT_PRT_NONE) {
470                 mpt->verbose = MPT_PRT_WARN;
471                 /* Print INFO level (if any) if bootverbose is set */
472                 mpt->verbose += (bootverbose != 0)? 1 : 0;
473         }
474         /* Make sure memory access decoders are enabled */
475         cmd = pci_read_config(dev, PCIR_COMMAND, 2);
476         if ((cmd & PCIM_CMD_MEMEN) == 0) {
477                 device_printf(dev, "Memory accesses disabled");
478                 return (ENXIO);
479         }
480
481         /*
482          * Make sure that SERR, PERR, WRITE INVALIDATE and BUSMASTER are set.
483          */
484         cmd |=
485             PCIM_CMD_SERRESPEN | PCIM_CMD_PERRESPEN |
486             PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
487         pci_write_config(dev, PCIR_COMMAND, cmd, 2);
488
489         /*
490          * Make sure we've disabled the ROM.
491          */
492         data = pci_read_config(dev, PCIR_BIOS, 4);
493         data &= ~1;
494         pci_write_config(dev, PCIR_BIOS, data, 4);
495
496         /*
497          * Is this part a dual?
498          * If so, link with our partner (around yet)
499          */
500         if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929 ||
501             (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC646 ||
502             (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC7X04X ||
503             (pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_1030) {
504                 mpt_link_peer(mpt);
505         }
506
507         /*
508          * Set up register access.  PIO mode is required for
509          * certain reset operations (but must be disabled for
510          * some cards otherwise).
511          */
512         mpt->pci_pio_rid = PCIR_BAR(MPT_IO_BAR);
513         mpt->pci_pio_reg = bus_alloc_resource(dev, SYS_RES_IOPORT,
514                             &mpt->pci_pio_rid, 0, ~0, 0, RF_ACTIVE);
515         if (mpt->pci_pio_reg == NULL) {
516                 device_printf(dev, "unable to map registers in PIO mode\n");
517                 goto bad;
518         }
519         mpt->pci_pio_st = rman_get_bustag(mpt->pci_pio_reg);
520         mpt->pci_pio_sh = rman_get_bushandle(mpt->pci_pio_reg);
521
522         /* Allocate kernel virtual memory for the 9x9's Mem0 region */
523         mpt->pci_mem_rid = PCIR_BAR(MPT_MEM_BAR);
524         mpt->pci_reg = bus_alloc_resource(dev, SYS_RES_MEMORY,
525                         &mpt->pci_mem_rid, 0, ~0, 0, RF_ACTIVE);
526         if (mpt->pci_reg == NULL) {
527                 device_printf(dev, "Unable to memory map registers.\n");
528                 if (mpt->is_sas) {
529                         device_printf(dev, "Giving Up.\n");
530                         goto bad;
531                 }
532                 device_printf(dev, "Falling back to PIO mode.\n");
533                 mpt->pci_st = mpt->pci_pio_st;
534                 mpt->pci_sh = mpt->pci_pio_sh;
535         } else {
536                 mpt->pci_st = rman_get_bustag(mpt->pci_reg);
537                 mpt->pci_sh = rman_get_bushandle(mpt->pci_reg);
538         }
539
540         /* Get a handle to the interrupt */
541         iqd = 0;
542         if (mpt->msi_enable) {
543                 /*
544                  * First try to alloc an MSI-X message.  If that
545                  * fails, then try to alloc an MSI message instead.
546                  */
547                 if (pci_msix_count(dev) == 1) {
548                         mpt->pci_msi_count = 1;
549                         if (pci_alloc_msix(dev, &mpt->pci_msi_count) == 0) {
550                                 iqd = 1;
551                         } else {
552                                 mpt->pci_msi_count = 0;
553                         }
554                 }
555                 if (iqd == 0 && pci_msi_count(dev) == 1) {
556                         mpt->pci_msi_count = 1;
557                         if (pci_alloc_msi(dev, &mpt->pci_msi_count) == 0) {
558                                 iqd = 1;
559                         } else {
560                                 mpt->pci_msi_count = 0;
561                         }
562                 }
563         }
564         mpt->pci_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &iqd,
565             RF_ACTIVE | RF_SHAREABLE);
566         if (mpt->pci_irq == NULL) {
567                 device_printf(dev, "could not allocate interrupt\n");
568                 goto bad;
569         }
570
571         MPT_LOCK_SETUP(mpt);
572
573         /* Disable interrupts at the part */
574         mpt_disable_ints(mpt);
575
576         /* Register the interrupt handler */
577         if (mpt_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, NULL, mpt_pci_intr,
578             mpt, &mpt->ih)) {
579                 device_printf(dev, "could not setup interrupt\n");
580                 goto bad;
581         }
582
583         /* Allocate dma memory */
584 /* XXX JGibbs -Should really be done based on IOCFacts. */
585         if (mpt_dma_mem_alloc(mpt)) {
586                 mpt_prt(mpt, "Could not allocate DMA memory\n");
587                 goto bad;
588         }
589
590         /*
591          * Save the PCI config register values
592          *
593          * Hard resets are known to screw up the BAR for diagnostic
594          * memory accesses (Mem1).
595          *
596          * Using Mem1 is known to make the chip stop responding to 
597          * configuration space transfers, so we need to save it now
598          */
599
600         mpt_read_config_regs(mpt);
601
602         /*
603          * Disable PIO until we need it
604          */
605         if (mpt->is_sas) {
606                 pci_disable_io(dev, SYS_RES_IOPORT);
607         }
608
609         /* Initialize the hardware */
610         if (mpt->disabled == 0) {
611                 if (mpt_attach(mpt) != 0) {
612                         goto bad;
613                 }
614         } else {
615                 mpt_prt(mpt, "device disabled at user request\n");
616                 goto bad;
617         }
618
619         mpt->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, mpt_pci_shutdown,
620             dev, SHUTDOWN_PRI_DEFAULT);
621
622         if (mpt->eh == NULL) {
623                 mpt_prt(mpt, "shutdown event registration failed\n");
624                 (void) mpt_detach(mpt);
625                 goto bad;
626         }
627         return (0);
628
629 bad:
630         mpt_dma_mem_free(mpt);
631         mpt_free_bus_resources(mpt);
632         mpt_unlink_peer(mpt);
633
634         MPT_LOCK_DESTROY(mpt);
635
636         /*
637          * but return zero to preserve unit numbering
638          */
639         return (0);
640 }
641
642 /*
643  * Free bus resources
644  */
645 static void
646 mpt_free_bus_resources(struct mpt_softc *mpt)
647 {
648         if (mpt->ih) {
649                 bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih);
650                 mpt->ih = 0;
651         }
652
653         if (mpt->pci_irq) {
654                 bus_release_resource(mpt->dev, SYS_RES_IRQ,
655                     mpt->pci_msi_count ? 1 : 0, mpt->pci_irq);
656                 mpt->pci_irq = 0;
657         }
658
659         if (mpt->pci_msi_count) {
660                 pci_release_msi(mpt->dev);
661                 mpt->pci_msi_count = 0;
662         }
663                 
664         if (mpt->pci_pio_reg) {
665                 bus_release_resource(mpt->dev, SYS_RES_IOPORT, mpt->pci_pio_rid,
666                         mpt->pci_pio_reg);
667                 mpt->pci_pio_reg = 0;
668         }
669         if (mpt->pci_reg) {
670                 bus_release_resource(mpt->dev, SYS_RES_MEMORY, mpt->pci_mem_rid,
671                         mpt->pci_reg);
672                 mpt->pci_reg = 0;
673         }
674         MPT_LOCK_DESTROY(mpt);
675 }
676
677
678 /*
679  * Disconnect ourselves from the system.
680  */
681 static int
682 mpt_pci_detach(device_t dev)
683 {
684         struct mpt_softc *mpt;
685
686         mpt  = (struct mpt_softc*)device_get_softc(dev);
687
688         if (mpt) {
689                 mpt_disable_ints(mpt);
690                 mpt_detach(mpt);
691                 mpt_reset(mpt, /*reinit*/FALSE);
692                 mpt_dma_mem_free(mpt);
693                 mpt_free_bus_resources(mpt);
694                 mpt_raid_free_mem(mpt);
695                 if (mpt->eh != NULL) {
696                         EVENTHANDLER_DEREGISTER(shutdown_post_sync, mpt->eh);
697                 }
698         }
699         return(0);
700 }
701
702
703 /*
704  * Disable the hardware
705  */
706 static int
707 mpt_pci_shutdown(device_t dev)
708 {
709         struct mpt_softc *mpt;
710
711         mpt = (struct mpt_softc *)device_get_softc(dev);
712         if (mpt) {
713                 int r;
714                 r = mpt_shutdown(mpt);
715                 return (r);
716         }
717         return(0);
718 }
719
720 static int
721 mpt_dma_mem_alloc(struct mpt_softc *mpt)
722 {
723         int i, error, nsegs;
724         uint8_t *vptr;
725         uint32_t pptr, end;
726         size_t len;
727         struct mpt_map_info mi;
728
729         /* Check if we alreay have allocated the reply memory */
730         if (mpt->reply_phys != 0) {
731                 return 0;
732         }
733
734         len = sizeof (request_t) * MPT_MAX_REQUESTS(mpt);
735 #ifdef  RELENG_4
736         mpt->request_pool = (request_t *)malloc(len, M_DEVBUF, M_WAITOK);
737         if (mpt->request_pool == NULL) {
738                 mpt_prt(mpt, "cannot allocate request pool\n");
739                 return (1);
740         }
741         memset(mpt->request_pool, 0, len);
742 #else
743         mpt->request_pool = (request_t *)malloc(len, M_DEVBUF, M_WAITOK|M_ZERO);
744         if (mpt->request_pool == NULL) {
745                 mpt_prt(mpt, "cannot allocate request pool\n");
746                 return (1);
747         }
748 #endif
749
750         /*
751          * Create a parent dma tag for this device.
752          *
753          * Align at byte boundaries,
754          * Limit to 32-bit addressing for request/reply queues.
755          */
756         if (mpt_dma_tag_create(mpt, /*parent*/bus_get_dma_tag(mpt->dev),
757             /*alignment*/1, /*boundary*/0, /*lowaddr*/BUS_SPACE_MAXADDR,
758             /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL,
759             /*maxsize*/BUS_SPACE_MAXSIZE_32BIT,
760             /*nsegments*/BUS_SPACE_MAXSIZE_32BIT,
761             /*maxsegsz*/BUS_SPACE_UNRESTRICTED, /*flags*/0,
762             &mpt->parent_dmat) != 0) {
763                 mpt_prt(mpt, "cannot create parent dma tag\n");
764                 return (1);
765         }
766
767         /* Create a child tag for reply buffers */
768         if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE, 0,
769             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
770             NULL, NULL, 2 * PAGE_SIZE, 1, BUS_SPACE_MAXSIZE_32BIT, 0,
771             &mpt->reply_dmat) != 0) {
772                 mpt_prt(mpt, "cannot create a dma tag for replies\n");
773                 return (1);
774         }
775
776         /* Allocate some DMA accessable memory for replies */
777         if (bus_dmamem_alloc(mpt->reply_dmat, (void **)&mpt->reply,
778             BUS_DMA_NOWAIT, &mpt->reply_dmap) != 0) {
779                 mpt_prt(mpt, "cannot allocate %lu bytes of reply memory\n",
780                     (u_long) (2 * PAGE_SIZE));
781                 return (1);
782         }
783
784         mi.mpt = mpt;
785         mi.error = 0;
786
787         /* Load and lock it into "bus space" */
788         bus_dmamap_load(mpt->reply_dmat, mpt->reply_dmap, mpt->reply,
789             2 * PAGE_SIZE, mpt_map_rquest, &mi, 0);
790
791         if (mi.error) {
792                 mpt_prt(mpt, "error %d loading dma map for DMA reply queue\n",
793                     mi.error);
794                 return (1);
795         }
796         mpt->reply_phys = mi.phys;
797
798         /* Create a child tag for data buffers */
799
800         /*
801          * XXX: we should say that nsegs is 'unrestricted, but that
802          * XXX: tickles a horrible bug in the busdma code. Instead,
803          * XXX: we'll derive a reasonable segment limit from MPT_MAXPHYS
804          */
805         nsegs = (MPT_MAXPHYS / PAGE_SIZE) + 1;
806         if (mpt_dma_tag_create(mpt, mpt->parent_dmat, 1,
807             0, BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
808             NULL, NULL, MAXBSIZE, nsegs, BUS_SPACE_MAXSIZE_32BIT, 0,
809             &mpt->buffer_dmat) != 0) {
810                 mpt_prt(mpt, "cannot create a dma tag for data buffers\n");
811                 return (1);
812         }
813
814         /* Create a child tag for request buffers */
815         if (mpt_dma_tag_create(mpt, mpt->parent_dmat, PAGE_SIZE, 0,
816             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
817             NULL, NULL, MPT_REQ_MEM_SIZE(mpt), 1, BUS_SPACE_MAXSIZE_32BIT, 0,
818             &mpt->request_dmat) != 0) {
819                 mpt_prt(mpt, "cannot create a dma tag for requests\n");
820                 return (1);
821         }
822
823         /* Allocate some DMA accessable memory for requests */
824         if (bus_dmamem_alloc(mpt->request_dmat, (void **)&mpt->request,
825             BUS_DMA_NOWAIT, &mpt->request_dmap) != 0) {
826                 mpt_prt(mpt, "cannot allocate %d bytes of request memory\n",
827                     MPT_REQ_MEM_SIZE(mpt));
828                 return (1);
829         }
830
831         mi.mpt = mpt;
832         mi.error = 0;
833
834         /* Load and lock it into "bus space" */
835         bus_dmamap_load(mpt->request_dmat, mpt->request_dmap, mpt->request,
836             MPT_REQ_MEM_SIZE(mpt), mpt_map_rquest, &mi, 0);
837
838         if (mi.error) {
839                 mpt_prt(mpt, "error %d loading dma map for DMA request queue\n",
840                     mi.error);
841                 return (1);
842         }
843         mpt->request_phys = mi.phys;
844
845         /*
846          * Now create per-request dma maps
847          */
848         i = 0;
849         pptr =  mpt->request_phys;
850         vptr =  mpt->request;
851         end = pptr + MPT_REQ_MEM_SIZE(mpt);
852         while(pptr < end) {
853                 request_t *req = &mpt->request_pool[i];
854                 req->index = i++;
855
856                 /* Store location of Request Data */
857                 req->req_pbuf = pptr;
858                 req->req_vbuf = vptr;
859
860                 pptr += MPT_REQUEST_AREA;
861                 vptr += MPT_REQUEST_AREA;
862
863                 req->sense_pbuf = (pptr - MPT_SENSE_SIZE);
864                 req->sense_vbuf = (vptr - MPT_SENSE_SIZE);
865
866                 error = bus_dmamap_create(mpt->buffer_dmat, 0, &req->dmap);
867                 if (error) {
868                         mpt_prt(mpt, "error %d creating per-cmd DMA maps\n",
869                             error);
870                         return (1);
871                 }
872         }
873
874         return (0);
875 }
876
877
878
879 /* Deallocate memory that was allocated by mpt_dma_mem_alloc 
880  */
881 static void
882 mpt_dma_mem_free(struct mpt_softc *mpt)
883 {
884         int i;
885
886         /* Make sure we aren't double destroying */
887         if (mpt->reply_dmat == 0) {
888                 mpt_lprt(mpt, MPT_PRT_DEBUG, "already released dma memory\n");
889                 return;
890         }
891                 
892         for (i = 0; i < MPT_MAX_REQUESTS(mpt); i++) {
893                 bus_dmamap_destroy(mpt->buffer_dmat, mpt->request_pool[i].dmap);
894         }
895         bus_dmamap_unload(mpt->request_dmat, mpt->request_dmap);
896         bus_dmamem_free(mpt->request_dmat, mpt->request, mpt->request_dmap);
897         bus_dma_tag_destroy(mpt->request_dmat);
898         bus_dma_tag_destroy(mpt->buffer_dmat);
899         bus_dmamap_unload(mpt->reply_dmat, mpt->reply_dmap);
900         bus_dmamem_free(mpt->reply_dmat, mpt->reply, mpt->reply_dmap);
901         bus_dma_tag_destroy(mpt->reply_dmat);
902         bus_dma_tag_destroy(mpt->parent_dmat);
903         mpt->reply_dmat = 0;
904         free(mpt->request_pool, M_DEVBUF);
905         mpt->request_pool = 0;
906
907 }
908
909
910
911 /* Reads modifiable (via PCI transactions) config registers */
912 static void
913 mpt_read_config_regs(struct mpt_softc *mpt)
914 {
915         mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2);
916         mpt->pci_cfg.LatencyTimer_LineSize =
917             pci_read_config(mpt->dev, PCIR_CACHELNSZ, 2);
918         mpt->pci_cfg.IO_BAR = pci_read_config(mpt->dev, PCIR_BAR(0), 4);
919         mpt->pci_cfg.Mem0_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(1), 4);
920         mpt->pci_cfg.Mem0_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(2), 4);
921         mpt->pci_cfg.Mem1_BAR[0] = pci_read_config(mpt->dev, PCIR_BAR(3), 4);
922         mpt->pci_cfg.Mem1_BAR[1] = pci_read_config(mpt->dev, PCIR_BAR(4), 4);
923         mpt->pci_cfg.ROM_BAR = pci_read_config(mpt->dev, PCIR_BIOS, 4);
924         mpt->pci_cfg.IntLine = pci_read_config(mpt->dev, PCIR_INTLINE, 1);
925         mpt->pci_cfg.PMCSR = pci_read_config(mpt->dev, 0x44, 4);
926 }
927
928 /* Sets modifiable config registers */
929 void
930 mpt_set_config_regs(struct mpt_softc *mpt)
931 {
932         uint32_t val;
933
934 #define MPT_CHECK(reg, offset, size)                                    \
935         val = pci_read_config(mpt->dev, offset, size);                  \
936         if (mpt->pci_cfg.reg != val) {                                  \
937                 mpt_prt(mpt,                                            \
938                     "Restoring " #reg " to 0x%X from 0x%X\n",           \
939                     mpt->pci_cfg.reg, val);                             \
940         }
941
942         if (mpt->verbose >= MPT_PRT_DEBUG) {
943                 MPT_CHECK(Command, PCIR_COMMAND, 2);
944                 MPT_CHECK(LatencyTimer_LineSize, PCIR_CACHELNSZ, 2);
945                 MPT_CHECK(IO_BAR, PCIR_BAR(0), 4);
946                 MPT_CHECK(Mem0_BAR[0], PCIR_BAR(1), 4);
947                 MPT_CHECK(Mem0_BAR[1], PCIR_BAR(2), 4);
948                 MPT_CHECK(Mem1_BAR[0], PCIR_BAR(3), 4);
949                 MPT_CHECK(Mem1_BAR[1], PCIR_BAR(4), 4);
950                 MPT_CHECK(ROM_BAR, PCIR_BIOS, 4);
951                 MPT_CHECK(IntLine, PCIR_INTLINE, 1);
952                 MPT_CHECK(PMCSR, 0x44, 4);
953         }
954 #undef MPT_CHECK
955
956         pci_write_config(mpt->dev, PCIR_COMMAND, mpt->pci_cfg.Command, 2);
957         pci_write_config(mpt->dev, PCIR_CACHELNSZ,
958             mpt->pci_cfg.LatencyTimer_LineSize, 2);
959         pci_write_config(mpt->dev, PCIR_BAR(0), mpt->pci_cfg.IO_BAR, 4);
960         pci_write_config(mpt->dev, PCIR_BAR(1), mpt->pci_cfg.Mem0_BAR[0], 4);
961         pci_write_config(mpt->dev, PCIR_BAR(2), mpt->pci_cfg.Mem0_BAR[1], 4);
962         pci_write_config(mpt->dev, PCIR_BAR(3), mpt->pci_cfg.Mem1_BAR[0], 4);
963         pci_write_config(mpt->dev, PCIR_BAR(4), mpt->pci_cfg.Mem1_BAR[1], 4);
964         pci_write_config(mpt->dev, PCIR_BIOS, mpt->pci_cfg.ROM_BAR, 4);
965         pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1);
966         pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4);
967 }
968
969 static void
970 mpt_pci_intr(void *arg)
971 {
972         struct mpt_softc *mpt;
973
974         mpt = (struct mpt_softc *)arg;
975         MPT_LOCK(mpt);
976         mpt_intr(mpt);
977         MPT_UNLOCK(mpt);
978 }