xref: /freebsd/sys/dev/aac/aac_pci.c (revision 21e5a2223c70047269d7e13ec60332d82f6524dc)
135863739SMike Smith /*-
235863739SMike Smith  * Copyright (c) 2000 Michael Smith
3c6eafcf2SScott Long  * Copyright (c) 2001 Scott Long
435863739SMike Smith  * Copyright (c) 2000 BSDi
5fadfef89SScott Long  * Copyright (c) 2001 Adaptec, Inc.
635863739SMike Smith  * All rights reserved.
735863739SMike Smith  *
835863739SMike Smith  * Redistribution and use in source and binary forms, with or without
935863739SMike Smith  * modification, are permitted provided that the following conditions
1035863739SMike Smith  * are met:
1135863739SMike Smith  * 1. Redistributions of source code must retain the above copyright
1235863739SMike Smith  *    notice, this list of conditions and the following disclaimer.
1335863739SMike Smith  * 2. Redistributions in binary form must reproduce the above copyright
1435863739SMike Smith  *    notice, this list of conditions and the following disclaimer in the
1535863739SMike Smith  *    documentation and/or other materials provided with the distribution.
1635863739SMike Smith  *
1735863739SMike Smith  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1835863739SMike Smith  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1935863739SMike Smith  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2035863739SMike Smith  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2135863739SMike Smith  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2235863739SMike Smith  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2335863739SMike Smith  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2435863739SMike Smith  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2535863739SMike Smith  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2635863739SMike Smith  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2735863739SMike Smith  * SUCH DAMAGE.
2835863739SMike Smith  */
2935863739SMike Smith 
30aad970f1SDavid E. O'Brien #include <sys/cdefs.h>
31aad970f1SDavid E. O'Brien __FBSDID("$FreeBSD$");
32aad970f1SDavid E. O'Brien 
3335863739SMike Smith /*
3435863739SMike Smith  * PCI bus interface and resource allocation.
3535863739SMike Smith  */
3635863739SMike Smith 
37f6c4dd3fSScott Long #include "opt_aac.h"
38f6c4dd3fSScott Long 
3935863739SMike Smith #include <sys/param.h>
4035863739SMike Smith #include <sys/systm.h>
4135863739SMike Smith #include <sys/kernel.h>
42fe12f24bSPoul-Henning Kamp #include <sys/module.h>
4335863739SMike Smith 
449e2e96d8SScott Long #include <sys/bio.h>
4535863739SMike Smith #include <sys/bus.h>
4635863739SMike Smith #include <sys/conf.h>
4735863739SMike Smith #include <sys/disk.h>
4835863739SMike Smith 
4935863739SMike Smith #include <machine/bus.h>
5035863739SMike Smith #include <machine/resource.h>
5135863739SMike Smith #include <sys/rman.h>
5235863739SMike Smith 
53dc5f7dd0SWarner Losh #include <dev/pci/pcireg.h>
54dc5f7dd0SWarner Losh #include <dev/pci/pcivar.h>
5535863739SMike Smith 
5635863739SMike Smith #include <dev/aac/aacreg.h>
570b0594cdSScott Long #include <sys/aac_ioctl.h>
5835863739SMike Smith #include <dev/aac/aacvar.h>
5935863739SMike Smith 
6035863739SMike Smith static int	aac_pci_probe(device_t dev);
6135863739SMike Smith static int	aac_pci_attach(device_t dev);
6235863739SMike Smith 
63da4882c2SMarius Strobl static int aac_enable_msi = 1;
64da4882c2SMarius Strobl TUNABLE_INT("hw.aac.enable_msi", &aac_enable_msi);
65da4882c2SMarius Strobl SYSCTL_INT(_hw_aac, OID_AUTO, enable_msi, CTLFLAG_RDTUN, &aac_enable_msi, 0,
66da4882c2SMarius Strobl     "Enable MSI interrupts");
67da4882c2SMarius Strobl 
6835863739SMike Smith static device_method_t aac_methods[] = {
6935863739SMike Smith 	/* Device interface */
7035863739SMike Smith 	DEVMETHOD(device_probe,		aac_pci_probe),
7135863739SMike Smith 	DEVMETHOD(device_attach,	aac_pci_attach),
7235863739SMike Smith 	DEVMETHOD(device_detach,	aac_detach),
7335863739SMike Smith 	DEVMETHOD(device_suspend,	aac_suspend),
7435863739SMike Smith 	DEVMETHOD(device_resume,	aac_resume),
7535863739SMike Smith 
764b7ec270SMarius Strobl 	DEVMETHOD_END
7735863739SMike Smith };
7835863739SMike Smith 
7935863739SMike Smith static driver_t aac_pci_driver = {
8035863739SMike Smith 	"aac",
8135863739SMike Smith 	aac_methods,
8235863739SMike Smith 	sizeof(struct aac_softc)
8335863739SMike Smith };
8435863739SMike Smith 
85e45bef2aSMike Smith static devclass_t	aac_devclass;
86e45bef2aSMike Smith 
87da4882c2SMarius Strobl DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, NULL, NULL);
88b3d93fd0SMatt Jacob MODULE_DEPEND(aac, pci, 1, 1, 1);
89b3d93fd0SMatt Jacob 
90da4882c2SMarius Strobl static const struct aac_ident
9135863739SMike Smith {
9235863739SMike Smith 	u_int16_t		vendor;
9335863739SMike Smith 	u_int16_t		device;
9435863739SMike Smith 	u_int16_t		subvendor;
9535863739SMike Smith 	u_int16_t		subdevice;
9635863739SMike Smith 	int			hwif;
97fe3cb0e1SScott Long 	int			quirks;
98da4882c2SMarius Strobl 	const char		*desc;
9935863739SMike Smith } aac_identifiers[] = {
100a6d35632SScott Long 	{0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, 0,
101fe3cb0e1SScott Long 	"Dell PERC 2/Si"},
102a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, 0,
103fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
104a6d35632SScott Long 	{0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, 0,
105fe3cb0e1SScott Long 	"Dell PERC 3/Si"},
106a6d35632SScott Long 	{0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, 0,
107fe3cb0e1SScott Long 	"Dell PERC 3/Si"},
108a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, 0,
109fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
110a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, 0,
111fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
112a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, 0,
113fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
114a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x011b, AAC_HWIF_I960RX, 0,
115fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
116a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x0121, AAC_HWIF_I960RX, 0,
117fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
118a6d35632SScott Long 	{0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, 0,
119fe3cb0e1SScott Long 	"Adaptec AAC-364"},
1204b00f859SScott Long 	{0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
1214b00f859SScott Long 	 AAC_FLAGS_BROKEN_MEMMAP, "Adaptec SCSI RAID 5400S"},
122a6d35632SScott Long 	{0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, AAC_FLAGS_PERC2QC,
123a6d35632SScott Long 	 "Dell PERC 2/QC"},
124a6d35632SScott Long 	{0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, 0,
125a9f3d2c7SScott Long 	 "HP NetRaid-4M"},
126a6d35632SScott Long 	{0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
127a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
128a6d35632SScott Long 	{0x9005, 0x0285, 0x1028, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
129a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Dell PERC 320/DC"},
130a6d35632SScott Long 	{0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
131a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2120S"},
1329d5be300SScott Long 	{0x9005, 0x0285, 0x9005, 0x0290, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1337598d049SChristian Brueffer 	 "Adaptec SATA RAID 2410SA"},
134ad452e65SScott Long 	{0x9005, 0x0285, 0x1028, 0x0291, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
135ad452e65SScott Long 	 "Dell CERC SATA RAID 2"},
136ad452e65SScott Long 	{0x9005, 0x0285, 0x9005, 0x0292, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1377598d049SChristian Brueffer 	 "Adaptec SATA RAID 2810SA"},
138b1e56e58SScott Long 	{0x9005, 0x0285, 0x9005, 0x0293, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1397598d049SChristian Brueffer 	 "Adaptec SATA RAID 21610SA"},
14016ee26fdSPaul Saab 	{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
14116ee26fdSPaul Saab 	 "HP ML110 G2 (Adaptec 2610SA)"},
142*21e5a222SMarius Strobl 	{0x9005, 0x0286, 0x9005, 0x028c, AAC_HWIF_RKT, AAC_FLAGS_NOMSI,
143ecefe571SScott Long 	 "Adaptec SCSI RAID 2230S"},
1444afedc31SScott Long 	{0x9005, 0x0286, 0x9005, 0x028d, AAC_HWIF_RKT, 0,
1454afedc31SScott Long 	 "Adaptec SCSI RAID 2130S"},
1467cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1477cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
1487cb209f5SScott Long 	{0x9005, 0x0285, 0x17aa, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1497cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Legend S220"},
1507cb209f5SScott Long 	{0x9005, 0x0285, 0x17aa, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1517cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Legend S230"},
1527cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0288, AAC_HWIF_I960RX, 0,
1537cb209f5SScott Long 	 "Adaptec SCSI RAID 3230S"},
1547cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0289, AAC_HWIF_I960RX, 0,
1557cb209f5SScott Long 	 "Adaptec SCSI RAID 3240S"},
1567cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028a, AAC_HWIF_I960RX, 0,
1577cb209f5SScott Long 	 "Adaptec SCSI RAID 2020ZCR"},
1587cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028b, AAC_HWIF_I960RX, 0,
1597cb209f5SScott Long 	 "Adaptec SCSI RAID 2025ZCR"},
160*21e5a222SMarius Strobl 	{0x9005, 0x0286, 0x9005, 0x029b, AAC_HWIF_RKT, AAC_FLAGS_NOMSI,
1617cb209f5SScott Long 	 "Adaptec SATA RAID 2820SA"},
1627cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029c, AAC_HWIF_RKT, 0,
1637cb209f5SScott Long 	 "Adaptec SATA RAID 2620SA"},
1647cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029d, AAC_HWIF_RKT, 0,
1657cb209f5SScott Long 	 "Adaptec SATA RAID 2420SA"},
1667cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029e, AAC_HWIF_RKT, 0,
1677598d049SChristian Brueffer 	 "ICP ICP9024RO SCSI RAID"},
1687cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029f, AAC_HWIF_RKT, 0,
1697598d049SChristian Brueffer 	 "ICP ICP9014RO SCSI RAID"},
1707cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0294, AAC_HWIF_I960RX, 0,
1717cb209f5SScott Long 	 "Adaptec SATA RAID 2026ZCR"},
1727cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0296, AAC_HWIF_I960RX, 0,
1737cb209f5SScott Long 	 "Adaptec SCSI RAID 2240S"},
1747cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0297, AAC_HWIF_I960RX, 0,
1757cb209f5SScott Long 	 "Adaptec SAS RAID 4005SAS"},
1767cb209f5SScott Long 	{0x9005, 0x0285, 0x1014, 0x02f2, AAC_HWIF_I960RX, 0,
1777cb209f5SScott Long 	 "IBM ServeRAID 8i"},
1782792e509SEd Maste 	{0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
1792792e509SEd Maste 	 "IBM ServeRAID 8i"},
1807cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
181e71d3b9cSEd Maste 	 "Adaptec RAID 4000"},
1827cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
1837cb209f5SScott Long 	 "Adaptec SAS RAID 4800SAS"},
1847cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
1857cb209f5SScott Long 	 "Adaptec SAS RAID 4805SAS"},
1867cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028e, AAC_HWIF_I960RX, 0,
1877cb209f5SScott Long 	 "Adaptec SATA RAID 2020SA ZCR"},
1887cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028f, AAC_HWIF_I960RX, 0,
1897cb209f5SScott Long 	 "Adaptec SATA RAID 2025SA ZCR"},
1907cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x02a4, AAC_HWIF_I960RX, 0,
1917598d049SChristian Brueffer 	 "ICP ICP9085LI SAS RAID"},
1927cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x02a5, AAC_HWIF_I960RX, 0,
1937598d049SChristian Brueffer 	 "ICP ICP5085BR SAS RAID"},
1947cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x02a0, AAC_HWIF_RKT, 0,
1957598d049SChristian Brueffer 	 "ICP ICP9047MA SATA RAID"},
1967cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x02a1, AAC_HWIF_RKT, 0,
1977598d049SChristian Brueffer 	 "ICP ICP9087MA SATA RAID"},
1982792e509SEd Maste 	{0x9005, 0x0286, 0x9005, 0x02a6, AAC_HWIF_RKT, 0,
1992792e509SEd Maste 	 "ICP9067MA SATA RAID"},
2002792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b5, AAC_HWIF_I960RX, 0,
2012792e509SEd Maste 	 "Adaptec RAID 5445"},
2022792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b6, AAC_HWIF_I960RX, 0,
2032792e509SEd Maste 	 "Adaptec RAID 5805"},
2042792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b7, AAC_HWIF_I960RX, 0,
2052792e509SEd Maste 	 "Adaptec RAID 5085"},
2062792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b8, AAC_HWIF_I960RX, 0,
2072792e509SEd Maste 	 "ICP RAID ICP5445SL"},
2082792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b9, AAC_HWIF_I960RX, 0,
2092792e509SEd Maste 	 "ICP RAID ICP5085SL"},
2102792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02ba, AAC_HWIF_I960RX, 0,
2112792e509SEd Maste 	 "ICP RAID ICP5805SL"},
212afa3f6dfSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bb, AAC_HWIF_I960RX, 0,
213afa3f6dfSEd Maste 	 "Adaptec RAID 3405"},
214afa3f6dfSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bc, AAC_HWIF_I960RX, 0,
215afa3f6dfSEd Maste 	 "Adaptec RAID 3805"},
2162792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bd, AAC_HWIF_I960RX, 0,
2172792e509SEd Maste 	 "Adaptec RAID 31205"},
2182792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02be, AAC_HWIF_I960RX, 0,
2192792e509SEd Maste 	 "Adaptec RAID 31605"},
2202792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bf, AAC_HWIF_I960RX, 0,
2212792e509SEd Maste 	 "ICP RAID ICP5045BL"},
2222792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c0, AAC_HWIF_I960RX, 0,
2232792e509SEd Maste 	 "ICP RAID ICP5085BL"},
2242792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c1, AAC_HWIF_I960RX, 0,
2252792e509SEd Maste 	 "ICP RAID ICP5125BR"},
2262792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c2, AAC_HWIF_I960RX, 0,
2272792e509SEd Maste 	 "ICP RAID ICP5165BR"},
2282792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c3, AAC_HWIF_I960RX, 0,
2292792e509SEd Maste 	 "Adaptec RAID 51205"},
2302792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c4, AAC_HWIF_I960RX, 0,
2312792e509SEd Maste 	 "Adaptec RAID 51605"},
2322792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c5, AAC_HWIF_I960RX, 0,
2332792e509SEd Maste 	 "ICP RAID ICP5125SL"},
2342792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c6, AAC_HWIF_I960RX, 0,
2352792e509SEd Maste 	 "ICP RAID ICP5165SL"},
2362792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c7, AAC_HWIF_I960RX, 0,
2372792e509SEd Maste 	 "Adaptec RAID 3085"},
2382792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c8, AAC_HWIF_I960RX, 0,
2392792e509SEd Maste 	 "ICP RAID ICP5805BL"},
2408af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02ce, AAC_HWIF_I960RX, 0,
2418af086fdSEd Maste 	 "Adaptec RAID 51245"},
2428af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02cf, AAC_HWIF_I960RX, 0,
2438af086fdSEd Maste 	 "Adaptec RAID 51645"},
2448af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d0, AAC_HWIF_I960RX, 0,
2458af086fdSEd Maste 	 "Adaptec RAID 52445"},
2468af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d1, AAC_HWIF_I960RX, 0,
2478af086fdSEd Maste 	 "Adaptec RAID 5405"},
2481f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d4, AAC_HWIF_I960RX, 0,
2491f568583SEd Maste 	 "Adaptec RAID 2045"},
2501f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d5, AAC_HWIF_I960RX, 0,
2511f568583SEd Maste 	 "Adaptec RAID 2405"},
2521f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d6, AAC_HWIF_I960RX, 0,
2531f568583SEd Maste 	 "Adaptec RAID 2445"},
2541f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d7, AAC_HWIF_I960RX, 0,
2551f568583SEd Maste 	 "Adaptec RAID 2805"},
256eae94b67SScott Long 	{0x9005, 0x0286, 0x1014, 0x9580, AAC_HWIF_RKT, 0,
257eae94b67SScott Long 	 "IBM ServeRAID-8k"},
2582792e509SEd Maste 	{0x9005, 0x0285, 0x1014, 0x034d, AAC_HWIF_I960RX, 0,
2592792e509SEd Maste 	 "IBM ServeRAID 8s"},
2608af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x7aac, AAC_HWIF_I960RX, 0,
2618af086fdSEd Maste 	 "Sun STK RAID REM"},
2628af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x7aae, AAC_HWIF_I960RX, 0,
2638af086fdSEd Maste 	 "Sun STK RAID EM"},
2648af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x286, AAC_HWIF_I960RX, 0,
2658af086fdSEd Maste 	 "SG-XPCIESAS-R-IN"},
2668af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x287, AAC_HWIF_I960RX, 0,
2678af086fdSEd Maste 	 "SG-XPCIESAS-R-EX"},
268e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2b5, AAC_HWIF_I960RX, 0,
269e9faf6c2SEd Maste 	 "AOC-USAS-S4i"},
270e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2b6, AAC_HWIF_I960RX, 0,
271e9faf6c2SEd Maste 	 "AOC-USAS-S8i"},
272e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2c9, AAC_HWIF_I960RX, 0,
273e9faf6c2SEd Maste 	 "AOC-USAS-S4iR"},
274e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2ca, AAC_HWIF_I960RX, 0,
275e9faf6c2SEd Maste 	 "AOC-USAS-S8iR"},
276e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2d2, AAC_HWIF_I960RX, 0,
277e9faf6c2SEd Maste 	 "AOC-USAS-S8i-LP"},
278e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2d3, AAC_HWIF_I960RX, 0,
279e9faf6c2SEd Maste 	 "AOC-USAS-S8iR-LP"},
280fe3cb0e1SScott Long 	{0, 0, 0, 0, 0, 0, 0}
28135863739SMike Smith };
282da4882c2SMarius Strobl 
283da4882c2SMarius Strobl static const struct aac_ident
2847ea2d558SEd Maste aac_family_identifiers[] = {
2857ea2d558SEd Maste 	{0x9005, 0x0285, 0, 0, AAC_HWIF_I960RX, 0,
2867ea2d558SEd Maste 	 "Adaptec RAID Controller"},
2877ea2d558SEd Maste 	{0x9005, 0x0286, 0, 0, AAC_HWIF_RKT, 0,
2887ea2d558SEd Maste 	 "Adaptec RAID Controller"},
2897ea2d558SEd Maste 	{0, 0, 0, 0, 0, 0, 0}
2907ea2d558SEd Maste };
29135863739SMike Smith 
292da4882c2SMarius Strobl static const struct aac_ident *
2932419217bSScott Long aac_find_ident(device_t dev)
2942419217bSScott Long {
295da4882c2SMarius Strobl 	const struct aac_ident *m;
2967ea2d558SEd Maste 	u_int16_t vendid, devid, sub_vendid, sub_devid;
2977ea2d558SEd Maste 
2987ea2d558SEd Maste 	vendid = pci_get_vendor(dev);
2997ea2d558SEd Maste 	devid = pci_get_device(dev);
3007ea2d558SEd Maste 	sub_vendid = pci_get_subvendor(dev);
3017ea2d558SEd Maste 	sub_devid = pci_get_subdevice(dev);
3022419217bSScott Long 
3032419217bSScott Long 	for (m = aac_identifiers; m->vendor != 0; m++) {
3047ea2d558SEd Maste 		if ((m->vendor == vendid) && (m->device == devid) &&
3057ea2d558SEd Maste 		    (m->subvendor == sub_vendid) &&
3067ea2d558SEd Maste 		    (m->subdevice == sub_devid))
3077ea2d558SEd Maste 			return (m);
3087ea2d558SEd Maste 	}
3097ea2d558SEd Maste 
3107ea2d558SEd Maste 	for (m = aac_family_identifiers; m->vendor != 0; m++) {
3117ea2d558SEd Maste 		if ((m->vendor == vendid) && (m->device == devid))
3122419217bSScott Long 			return (m);
3132419217bSScott Long 	}
3142419217bSScott Long 	return (NULL);
3152419217bSScott Long }
3162419217bSScott Long 
317914da7d0SScott Long /*
31835863739SMike Smith  * Determine whether this is one of our supported adapters.
31935863739SMike Smith  */
32035863739SMike Smith static int
32135863739SMike Smith aac_pci_probe(device_t dev)
32235863739SMike Smith {
323da4882c2SMarius Strobl 	const struct aac_ident *id;
32435863739SMike Smith 
32531a0399eSEd Maste 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
32635863739SMike Smith 
3272419217bSScott Long 	if ((id = aac_find_ident(dev)) != NULL) {
3282419217bSScott Long 		device_set_desc(dev, id->desc);
329494f3ca1SWarner Losh 		return(BUS_PROBE_DEFAULT);
33035863739SMike Smith 	}
33135863739SMike Smith 	return(ENXIO);
33235863739SMike Smith }
33335863739SMike Smith 
334914da7d0SScott Long /*
33535863739SMike Smith  * Allocate resources for our device, set up the bus interface.
33635863739SMike Smith  */
33735863739SMike Smith static int
33835863739SMike Smith aac_pci_attach(device_t dev)
33935863739SMike Smith {
34035863739SMike Smith 	struct aac_softc *sc;
341da4882c2SMarius Strobl 	const struct aac_ident *id;
342*21e5a222SMarius Strobl 	int count, error, rid;
34335863739SMike Smith 
34431a0399eSEd Maste 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
34535863739SMike Smith 
34635863739SMike Smith 	/*
34735863739SMike Smith 	 * Initialise softc.
34835863739SMike Smith 	 */
34935863739SMike Smith 	sc = device_get_softc(dev);
35035863739SMike Smith 	sc->aac_dev = dev;
35135863739SMike Smith 
35235863739SMike Smith 	/* assume failure is 'not configured' */
35335863739SMike Smith 	error = ENXIO;
35435863739SMike Smith 
35535863739SMike Smith 	/*
35635863739SMike Smith 	 * Verify that the adapter is correctly set up in PCI space.
35735863739SMike Smith 	 */
358da4882c2SMarius Strobl 	pci_enable_busmaster(dev);
359da4882c2SMarius Strobl 	if (!(pci_read_config(dev, PCIR_COMMAND, 2) & PCIM_CMD_BUSMASTEREN)) {
360da4882c2SMarius Strobl 		device_printf(dev, "can't enable bus-master feature\n");
36135863739SMike Smith 		goto out;
36235863739SMike Smith 	}
36335863739SMike Smith 
36435863739SMike Smith 	/*
365*21e5a222SMarius Strobl 	 * Detect the hardware interface version, set up the bus interface
366*21e5a222SMarius Strobl 	 * indirection.
367*21e5a222SMarius Strobl 	 */
368*21e5a222SMarius Strobl 	id = aac_find_ident(dev);
369*21e5a222SMarius Strobl 	sc->aac_hwif = id->hwif;
370*21e5a222SMarius Strobl 	switch(sc->aac_hwif) {
371*21e5a222SMarius Strobl 	case AAC_HWIF_I960RX:
372*21e5a222SMarius Strobl 	case AAC_HWIF_NARK:
373*21e5a222SMarius Strobl 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
374*21e5a222SMarius Strobl 		    "set hardware up for i960Rx/NARK");
375*21e5a222SMarius Strobl 		sc->aac_if = &aac_rx_interface;
376*21e5a222SMarius Strobl 		break;
377*21e5a222SMarius Strobl 	case AAC_HWIF_STRONGARM:
378*21e5a222SMarius Strobl 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
379*21e5a222SMarius Strobl 		    "set hardware up for StrongARM");
380*21e5a222SMarius Strobl 		sc->aac_if = &aac_sa_interface;
381*21e5a222SMarius Strobl 		break;
382*21e5a222SMarius Strobl 	case AAC_HWIF_RKT:
383*21e5a222SMarius Strobl 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
384*21e5a222SMarius Strobl 		    "set hardware up for Rocket/MIPS");
385*21e5a222SMarius Strobl 		sc->aac_if = &aac_rkt_interface;
386*21e5a222SMarius Strobl 		break;
387*21e5a222SMarius Strobl 	default:
388*21e5a222SMarius Strobl 		sc->aac_hwif = AAC_HWIF_UNKNOWN;
389*21e5a222SMarius Strobl 		device_printf(dev, "unknown hardware type\n");
390*21e5a222SMarius Strobl 		goto out;
391*21e5a222SMarius Strobl 	}
392*21e5a222SMarius Strobl 
393*21e5a222SMarius Strobl 	/* Set up quirks */
394*21e5a222SMarius Strobl 	sc->flags = id->quirks;
395*21e5a222SMarius Strobl 
396*21e5a222SMarius Strobl 	/*
397da4882c2SMarius Strobl 	 * Allocate the PCI register window(s).
39835863739SMike Smith 	 */
399da4882c2SMarius Strobl 	rid = PCIR_BAR(0);
400da4882c2SMarius Strobl 	if ((sc->aac_regs_res0 = bus_alloc_resource_any(dev,
401da4882c2SMarius Strobl 	    SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) {
402da4882c2SMarius Strobl 		device_printf(dev, "can't allocate register window 0\n");
40335863739SMike Smith 		goto out;
40435863739SMike Smith 	}
405ff0991c4SAttilio Rao 	sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
406ff0991c4SAttilio Rao 	sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
40735863739SMike Smith 
408ff0991c4SAttilio Rao 	if (sc->aac_hwif == AAC_HWIF_NARK) {
409da4882c2SMarius Strobl 		rid = PCIR_BAR(1);
410da4882c2SMarius Strobl 		if ((sc->aac_regs_res1 = bus_alloc_resource_any(dev,
411da4882c2SMarius Strobl 		    SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) {
412da4882c2SMarius Strobl 			device_printf(dev,
413da4882c2SMarius Strobl 			    "can't allocate register window 1\n");
414ff0991c4SAttilio Rao 			goto out;
415ff0991c4SAttilio Rao 		}
416ff0991c4SAttilio Rao 		sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
417ff0991c4SAttilio Rao 		sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
418ff0991c4SAttilio Rao 	} else {
419ff0991c4SAttilio Rao 		sc->aac_regs_res1 = sc->aac_regs_res0;
420ff0991c4SAttilio Rao 		sc->aac_btag1 = sc->aac_btag0;
421ff0991c4SAttilio Rao 		sc->aac_bhandle1 = sc->aac_bhandle0;
422ff0991c4SAttilio Rao 	}
42335863739SMike Smith 
42435863739SMike Smith 	/*
425da4882c2SMarius Strobl 	 * Allocate the interrupt.
426da4882c2SMarius Strobl 	 */
427da4882c2SMarius Strobl 	rid = 0;
42820132a22SMarius Strobl 	count = 0;
429*21e5a222SMarius Strobl 	if (aac_enable_msi != 0 && (sc->flags & AAC_FLAGS_NOMSI) == 0 &&
430*21e5a222SMarius Strobl 	    (count = pci_msi_count(dev)) != 0) {
431da4882c2SMarius Strobl 		if (count > 1)
432da4882c2SMarius Strobl 			count = 1;
433da4882c2SMarius Strobl 		else
434da4882c2SMarius Strobl 			count = 0;
435da4882c2SMarius Strobl 		if (count == 1 && pci_alloc_msi(dev, &count) == 0)
436da4882c2SMarius Strobl 			rid = 1;
437da4882c2SMarius Strobl 	}
438da4882c2SMarius Strobl 	if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
439da4882c2SMarius Strobl 	    &rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE))) == NULL) {
440da4882c2SMarius Strobl 		device_printf(dev, "can't allocate interrupt\n");
441da4882c2SMarius Strobl 		goto out;
442da4882c2SMarius Strobl 	}
443da4882c2SMarius Strobl 
444da4882c2SMarius Strobl 	/*
44535863739SMike Smith 	 * Allocate the parent bus DMA tag appropriate for our PCI interface.
44635863739SMike Smith 	 *
44735863739SMike Smith 	 * Note that some of these controllers are 64-bit capable.
44835863739SMike Smith 	 */
449da4882c2SMarius Strobl 	if (bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
45055b44675SEd Maste 			       PAGE_SIZE, 0,		/* algnmnt, boundary */
451a6d35632SScott Long 			       BUS_SPACE_MAXADDR,	/* lowaddr */
45235863739SMike Smith 			       BUS_SPACE_MAXADDR, 	/* highaddr */
45335863739SMike Smith 			       NULL, NULL, 		/* filter, filterarg */
454a6d35632SScott Long 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
4557cb209f5SScott Long 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
45635863739SMike Smith 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
457a6d35632SScott Long 			       0,			/* flags */
458f6b1c44dSScott Long 			       NULL, NULL,		/* No locking needed */
45935863739SMike Smith 			       &sc->aac_parent_dmat)) {
460da4882c2SMarius Strobl 		device_printf(dev, "can't allocate parent DMA tag\n");
46135863739SMike Smith 		goto out;
46235863739SMike Smith 	}
46335863739SMike Smith 
46435863739SMike Smith 	/*
46535863739SMike Smith 	 * Do bus-independent initialisation.
46635863739SMike Smith 	 */
46735863739SMike Smith 	error = aac_attach(sc);
46835863739SMike Smith 
46935863739SMike Smith out:
47035863739SMike Smith 	if (error)
47135863739SMike Smith 		aac_free(sc);
47235863739SMike Smith 	return(error);
47335863739SMike Smith }
474608d7ac2SScott Long 
475608d7ac2SScott Long /*
476608d7ac2SScott Long  * Do nothing driver that will attach to the SCSI channels of a Dell PERC
477608d7ac2SScott Long  * controller.  This is needed to keep the power management subsystem from
478608d7ac2SScott Long  * trying to power down these devices.
479608d7ac2SScott Long  */
480608d7ac2SScott Long static int aacch_probe(device_t dev);
481608d7ac2SScott Long static int aacch_attach(device_t dev);
482608d7ac2SScott Long static int aacch_detach(device_t dev);
483608d7ac2SScott Long 
484608d7ac2SScott Long static device_method_t aacch_methods[] = {
485608d7ac2SScott Long 	/* Device interface */
486608d7ac2SScott Long 	DEVMETHOD(device_probe,		aacch_probe),
487608d7ac2SScott Long 	DEVMETHOD(device_attach,	aacch_attach),
488608d7ac2SScott Long 	DEVMETHOD(device_detach,	aacch_detach),
489da4882c2SMarius Strobl 	DEVMETHOD_END
490608d7ac2SScott Long };
491608d7ac2SScott Long 
492608d7ac2SScott Long struct aacch_softc {
493608d7ac2SScott Long 	device_t	dev;
494608d7ac2SScott Long };
495608d7ac2SScott Long 
496608d7ac2SScott Long static driver_t aacch_driver = {
497608d7ac2SScott Long 	"aacch",
498608d7ac2SScott Long 	aacch_methods,
499608d7ac2SScott Long 	sizeof(struct aacch_softc)
500608d7ac2SScott Long };
501608d7ac2SScott Long 
502608d7ac2SScott Long static devclass_t	aacch_devclass;
503da4882c2SMarius Strobl DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, NULL, NULL);
504608d7ac2SScott Long 
505608d7ac2SScott Long static int
506608d7ac2SScott Long aacch_probe(device_t dev)
507608d7ac2SScott Long {
508608d7ac2SScott Long 
5091b3a4f4eSScott Long 	if ((pci_get_vendor(dev) != 0x9005) ||
5101b3a4f4eSScott Long 	    (pci_get_device(dev) != 0x00c5))
511608d7ac2SScott Long 		return (ENXIO);
512608d7ac2SScott Long 
513608d7ac2SScott Long 	device_set_desc(dev, "AAC RAID Channel");
514608d7ac2SScott Long 	return (-10);
515608d7ac2SScott Long }
516608d7ac2SScott Long 
517608d7ac2SScott Long static int
518608d7ac2SScott Long aacch_attach(device_t dev)
519608d7ac2SScott Long {
520608d7ac2SScott Long 	struct aacch_softc *sc;
521608d7ac2SScott Long 
522608d7ac2SScott Long 	sc = device_get_softc(dev);
523608d7ac2SScott Long 
524608d7ac2SScott Long 	sc->dev = dev;
525608d7ac2SScott Long 
526608d7ac2SScott Long 	return (0);
527608d7ac2SScott Long }
528608d7ac2SScott Long 
529608d7ac2SScott Long static int
530608d7ac2SScott Long aacch_detach(device_t dev)
531608d7ac2SScott Long {
532608d7ac2SScott Long 
533608d7ac2SScott Long 	return (0);
534608d7ac2SScott Long }
535