xref: /freebsd/sys/dev/aac/aac_pci.c (revision 1f568583614663a51361f694f39cfd48a85a95e0)
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 
6335863739SMike Smith static device_method_t aac_methods[] = {
6435863739SMike Smith 	/* Device interface */
6535863739SMike Smith 	DEVMETHOD(device_probe,		aac_pci_probe),
6635863739SMike Smith 	DEVMETHOD(device_attach,	aac_pci_attach),
6735863739SMike Smith 	DEVMETHOD(device_detach,	aac_detach),
6835863739SMike Smith 	DEVMETHOD(device_suspend,	aac_suspend),
6935863739SMike Smith 	DEVMETHOD(device_resume,	aac_resume),
7035863739SMike Smith 
7135863739SMike Smith 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
7235863739SMike Smith 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
7335863739SMike Smith 	{ 0, 0 }
7435863739SMike Smith };
7535863739SMike Smith 
7635863739SMike Smith static driver_t aac_pci_driver = {
7735863739SMike Smith 	"aac",
7835863739SMike Smith 	aac_methods,
7935863739SMike Smith 	sizeof(struct aac_softc)
8035863739SMike Smith };
8135863739SMike Smith 
82e45bef2aSMike Smith static devclass_t	aac_devclass;
83e45bef2aSMike Smith 
8435863739SMike Smith DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
85b3d93fd0SMatt Jacob MODULE_DEPEND(aac, pci, 1, 1, 1);
86b3d93fd0SMatt Jacob 
8735863739SMike Smith 
8835863739SMike Smith struct aac_ident
8935863739SMike Smith {
9035863739SMike Smith 	u_int16_t		vendor;
9135863739SMike Smith 	u_int16_t		device;
9235863739SMike Smith 	u_int16_t		subvendor;
9335863739SMike Smith 	u_int16_t		subdevice;
9435863739SMike Smith 	int			hwif;
95fe3cb0e1SScott Long 	int			quirks;
9635863739SMike Smith 	char			*desc;
9735863739SMike Smith } aac_identifiers[] = {
98a6d35632SScott Long 	{0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, 0,
99fe3cb0e1SScott Long 	"Dell PERC 2/Si"},
100a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, 0,
101fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
102a6d35632SScott Long 	{0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, 0,
103fe3cb0e1SScott Long 	"Dell PERC 3/Si"},
104a6d35632SScott Long 	{0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, 0,
105fe3cb0e1SScott Long 	"Dell PERC 3/Si"},
106a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, 0,
107fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
108a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, 0,
109fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
110a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, 0,
111fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
112a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x011b, AAC_HWIF_I960RX, 0,
113fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
114a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x0121, AAC_HWIF_I960RX, 0,
115fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
116a6d35632SScott Long 	{0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, 0,
117fe3cb0e1SScott Long 	"Adaptec AAC-364"},
1184b00f859SScott Long 	{0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
1194b00f859SScott Long 	 AAC_FLAGS_BROKEN_MEMMAP, "Adaptec SCSI RAID 5400S"},
120a6d35632SScott Long 	{0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, AAC_FLAGS_PERC2QC,
121a6d35632SScott Long 	 "Dell PERC 2/QC"},
122a6d35632SScott Long 	{0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, 0,
123a9f3d2c7SScott Long 	 "HP NetRaid-4M"},
124a6d35632SScott Long 	{0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
125a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
126a6d35632SScott Long 	{0x9005, 0x0285, 0x1028, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
127a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Dell PERC 320/DC"},
128a6d35632SScott Long 	{0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
129a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2120S"},
1309d5be300SScott Long 	{0x9005, 0x0285, 0x9005, 0x0290, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1317598d049SChristian Brueffer 	 "Adaptec SATA RAID 2410SA"},
132ad452e65SScott Long 	{0x9005, 0x0285, 0x1028, 0x0291, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
133ad452e65SScott Long 	 "Dell CERC SATA RAID 2"},
134ad452e65SScott Long 	{0x9005, 0x0285, 0x9005, 0x0292, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1357598d049SChristian Brueffer 	 "Adaptec SATA RAID 2810SA"},
136b1e56e58SScott Long 	{0x9005, 0x0285, 0x9005, 0x0293, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1377598d049SChristian Brueffer 	 "Adaptec SATA RAID 21610SA"},
13816ee26fdSPaul Saab 	{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
13916ee26fdSPaul Saab 	 "HP ML110 G2 (Adaptec 2610SA)"},
140ecefe571SScott Long 	{0x9005, 0x0286, 0x9005, 0x028c, AAC_HWIF_RKT, 0,
141ecefe571SScott Long 	 "Adaptec SCSI RAID 2230S"},
1424afedc31SScott Long 	{0x9005, 0x0286, 0x9005, 0x028d, AAC_HWIF_RKT, 0,
1434afedc31SScott Long 	 "Adaptec SCSI RAID 2130S"},
1447cb209f5SScott Long 
1457cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1467cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
1477cb209f5SScott Long 	{0x9005, 0x0285, 0x17aa, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1487cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Legend S220"},
1497cb209f5SScott Long 	{0x9005, 0x0285, 0x17aa, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1507cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Legend S230"},
1517cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0288, AAC_HWIF_I960RX, 0,
1527cb209f5SScott Long 	 "Adaptec SCSI RAID 3230S"},
1537cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0289, AAC_HWIF_I960RX, 0,
1547cb209f5SScott Long 	 "Adaptec SCSI RAID 3240S"},
1557cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028a, AAC_HWIF_I960RX, 0,
1567cb209f5SScott Long 	 "Adaptec SCSI RAID 2020ZCR"},
1577cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028b, AAC_HWIF_I960RX, 0,
1587cb209f5SScott Long 	 "Adaptec SCSI RAID 2025ZCR"},
1597cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029b, AAC_HWIF_RKT, 0,
1607cb209f5SScott Long 	 "Adaptec SATA RAID 2820SA"},
1617cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029c, AAC_HWIF_RKT, 0,
1627cb209f5SScott Long 	 "Adaptec SATA RAID 2620SA"},
1637cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029d, AAC_HWIF_RKT, 0,
1647cb209f5SScott Long 	 "Adaptec SATA RAID 2420SA"},
1657cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029e, AAC_HWIF_RKT, 0,
1667598d049SChristian Brueffer 	 "ICP ICP9024RO SCSI RAID"},
1677cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029f, AAC_HWIF_RKT, 0,
1687598d049SChristian Brueffer 	 "ICP ICP9014RO SCSI RAID"},
1697cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0294, AAC_HWIF_I960RX, 0,
1707cb209f5SScott Long 	 "Adaptec SATA RAID 2026ZCR"},
1717cb209f5SScott Long 	{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, 0,
1727cb209f5SScott Long 	 "Adaptec SATA RAID 2610SA"},
1737cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0296, AAC_HWIF_I960RX, 0,
1747cb209f5SScott Long 	 "Adaptec SCSI RAID 2240S"},
1757cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0297, AAC_HWIF_I960RX, 0,
1767cb209f5SScott Long 	 "Adaptec SAS RAID 4005SAS"},
1777cb209f5SScott Long 	{0x9005, 0x0285, 0x1014, 0x02f2, AAC_HWIF_I960RX, 0,
1787cb209f5SScott Long 	 "IBM ServeRAID 8i"},
1792792e509SEd Maste 	{0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
1802792e509SEd Maste 	 "IBM ServeRAID 8i"},
1817cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
1827cb209f5SScott Long 	 "Adaptec SAS RAID 4000SAS"},
1837cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
1847cb209f5SScott Long 	 "Adaptec SAS RAID 4800SAS"},
1857cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
1867cb209f5SScott Long 	 "Adaptec SAS RAID 4805SAS"},
1877cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028e, AAC_HWIF_I960RX, 0,
1887cb209f5SScott Long 	 "Adaptec SATA RAID 2020SA ZCR"},
1897cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028f, AAC_HWIF_I960RX, 0,
1907cb209f5SScott Long 	 "Adaptec SATA RAID 2025SA ZCR"},
1917cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x02a4, AAC_HWIF_I960RX, 0,
1927598d049SChristian Brueffer 	 "ICP ICP9085LI SAS RAID"},
1937cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x02a5, AAC_HWIF_I960RX, 0,
1947598d049SChristian Brueffer 	 "ICP ICP5085BR SAS RAID"},
1957cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x02a0, AAC_HWIF_RKT, 0,
1967598d049SChristian Brueffer 	 "ICP ICP9047MA SATA RAID"},
1977cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x02a1, AAC_HWIF_RKT, 0,
1987598d049SChristian Brueffer 	 "ICP ICP9087MA SATA RAID"},
1992792e509SEd Maste 	{0x9005, 0x0286, 0x9005, 0x02a6, AAC_HWIF_RKT, 0,
2002792e509SEd Maste 	 "ICP9067MA SATA RAID"},
2012792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b5, AAC_HWIF_I960RX, 0,
2022792e509SEd Maste 	 "Adaptec RAID 5445"},
2032792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b6, AAC_HWIF_I960RX, 0,
2042792e509SEd Maste 	 "Adaptec RAID 5805"},
2052792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b7, AAC_HWIF_I960RX, 0,
2062792e509SEd Maste 	 "Adaptec RAID 5085"},
2072792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b8, AAC_HWIF_I960RX, 0,
2082792e509SEd Maste 	 "ICP RAID ICP5445SL"},
2092792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02b9, AAC_HWIF_I960RX, 0,
2102792e509SEd Maste 	 "ICP RAID ICP5085SL"},
2112792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02ba, AAC_HWIF_I960RX, 0,
2122792e509SEd Maste 	 "ICP RAID ICP5805SL"},
213afa3f6dfSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bb, AAC_HWIF_I960RX, 0,
214afa3f6dfSEd Maste 	 "Adaptec RAID 3405"},
215afa3f6dfSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bc, AAC_HWIF_I960RX, 0,
216afa3f6dfSEd Maste 	 "Adaptec RAID 3805"},
2172792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bd, AAC_HWIF_I960RX, 0,
2182792e509SEd Maste 	 "Adaptec RAID 31205"},
2192792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02be, AAC_HWIF_I960RX, 0,
2202792e509SEd Maste 	 "Adaptec RAID 31605"},
2212792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02bf, AAC_HWIF_I960RX, 0,
2222792e509SEd Maste 	 "ICP RAID ICP5045BL"},
2232792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c0, AAC_HWIF_I960RX, 0,
2242792e509SEd Maste 	 "ICP RAID ICP5085BL"},
2252792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c1, AAC_HWIF_I960RX, 0,
2262792e509SEd Maste 	 "ICP RAID ICP5125BR"},
2272792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c2, AAC_HWIF_I960RX, 0,
2282792e509SEd Maste 	 "ICP RAID ICP5165BR"},
2292792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c3, AAC_HWIF_I960RX, 0,
2302792e509SEd Maste 	 "Adaptec RAID 51205"},
2312792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c4, AAC_HWIF_I960RX, 0,
2322792e509SEd Maste 	 "Adaptec RAID 51605"},
2332792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c5, AAC_HWIF_I960RX, 0,
2342792e509SEd Maste 	 "ICP RAID ICP5125SL"},
2352792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c6, AAC_HWIF_I960RX, 0,
2362792e509SEd Maste 	 "ICP RAID ICP5165SL"},
2372792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c7, AAC_HWIF_I960RX, 0,
2382792e509SEd Maste 	 "Adaptec RAID 3085"},
2392792e509SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02c8, AAC_HWIF_I960RX, 0,
2402792e509SEd Maste 	 "ICP RAID ICP5805BL"},
2418af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02ce, AAC_HWIF_I960RX, 0,
2428af086fdSEd Maste 	 "Adaptec RAID 51245"},
2438af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02cf, AAC_HWIF_I960RX, 0,
2448af086fdSEd Maste 	 "Adaptec RAID 51645"},
2458af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d0, AAC_HWIF_I960RX, 0,
2468af086fdSEd Maste 	 "Adaptec RAID 52445"},
2478af086fdSEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d1, AAC_HWIF_I960RX, 0,
2488af086fdSEd Maste         "Adaptec RAID 5405"},
2491f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d4, AAC_HWIF_I960RX, 0,
2501f568583SEd Maste         "Adaptec RAID 2045"},
2511f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d5, AAC_HWIF_I960RX, 0,
2521f568583SEd Maste         "Adaptec RAID 2405"},
2531f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d6, AAC_HWIF_I960RX, 0,
2541f568583SEd Maste         "Adaptec RAID 2445"},
2551f568583SEd Maste 	{0x9005, 0x0285, 0x9005, 0x02d7, AAC_HWIF_I960RX, 0,
2561f568583SEd Maste         "Adaptec RAID 2805"},
257eae94b67SScott Long 	{0x9005, 0x0286, 0x1014, 0x9580, AAC_HWIF_RKT, 0,
258eae94b67SScott Long 	 "IBM ServeRAID-8k"},
2592792e509SEd Maste 	{0x9005, 0x0285, 0x1014, 0x034d, AAC_HWIF_I960RX, 0,
2602792e509SEd Maste 	 "IBM ServeRAID 8s"},
2618af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x7aac, AAC_HWIF_I960RX, 0,
2628af086fdSEd Maste 	 "Sun STK RAID REM"},
2638af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x7aae, AAC_HWIF_I960RX, 0,
2648af086fdSEd Maste 	 "Sun STK RAID EM"},
2658af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x286, AAC_HWIF_I960RX, 0,
2668af086fdSEd Maste 	 "SG-XPCIESAS-R-IN"},
2678af086fdSEd Maste 	{0x9005, 0x0285, 0x108e, 0x287, AAC_HWIF_I960RX, 0,
2688af086fdSEd Maste 	 "SG-XPCIESAS-R-EX"},
269e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2b5, AAC_HWIF_I960RX, 0,
270e9faf6c2SEd Maste 	 "AOC-USAS-S4i"},
271e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2b6, AAC_HWIF_I960RX, 0,
272e9faf6c2SEd Maste 	 "AOC-USAS-S8i"},
273e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2c9, AAC_HWIF_I960RX, 0,
274e9faf6c2SEd Maste 	 "AOC-USAS-S4iR"},
275e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2ca, AAC_HWIF_I960RX, 0,
276e9faf6c2SEd Maste 	 "AOC-USAS-S8iR"},
277e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2d2, AAC_HWIF_I960RX, 0,
278e9faf6c2SEd Maste 	 "AOC-USAS-S8i-LP"},
279e9faf6c2SEd Maste 	{0x9005, 0x0285, 0x15d9, 0x2d3, AAC_HWIF_I960RX, 0,
280e9faf6c2SEd Maste 	 "AOC-USAS-S8iR-LP"},
281fe3cb0e1SScott Long 	{0, 0, 0, 0, 0, 0, 0}
28235863739SMike Smith };
2837ea2d558SEd Maste 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 
2922419217bSScott Long static struct aac_ident *
2932419217bSScott Long aac_find_ident(device_t dev)
2942419217bSScott Long {
2952419217bSScott Long 	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 
3152419217bSScott Long 	return (NULL);
3162419217bSScott Long }
3172419217bSScott Long 
318914da7d0SScott Long /*
31935863739SMike Smith  * Determine whether this is one of our supported adapters.
32035863739SMike Smith  */
32135863739SMike Smith static int
32235863739SMike Smith aac_pci_probe(device_t dev)
32335863739SMike Smith {
3242419217bSScott Long 	struct aac_ident *id;
32535863739SMike Smith 
32631a0399eSEd Maste 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
32735863739SMike Smith 
3282419217bSScott Long 	if ((id = aac_find_ident(dev)) != NULL) {
3292419217bSScott Long 		device_set_desc(dev, id->desc);
330494f3ca1SWarner Losh 		return(BUS_PROBE_DEFAULT);
33135863739SMike Smith 	}
33235863739SMike Smith 	return(ENXIO);
33335863739SMike Smith }
33435863739SMike Smith 
335914da7d0SScott Long /*
33635863739SMike Smith  * Allocate resources for our device, set up the bus interface.
33735863739SMike Smith  */
33835863739SMike Smith static int
33935863739SMike Smith aac_pci_attach(device_t dev)
34035863739SMike Smith {
34135863739SMike Smith 	struct aac_softc *sc;
3422419217bSScott Long 	struct aac_ident *id;
3432419217bSScott Long 	int error;
34435863739SMike Smith 	u_int32_t command;
34535863739SMike Smith 
34631a0399eSEd Maste 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
34735863739SMike Smith 
34835863739SMike Smith 	/*
34935863739SMike Smith 	 * Initialise softc.
35035863739SMike Smith 	 */
35135863739SMike Smith 	sc = device_get_softc(dev);
35235863739SMike Smith 	bzero(sc, sizeof(*sc));
35335863739SMike Smith 	sc->aac_dev = dev;
35435863739SMike Smith 
35535863739SMike Smith 	/* assume failure is 'not configured' */
35635863739SMike Smith 	error = ENXIO;
35735863739SMike Smith 
35835863739SMike Smith 	/*
35935863739SMike Smith 	 * Verify that the adapter is correctly set up in PCI space.
36035863739SMike Smith 	 */
36135863739SMike Smith 	command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
36235863739SMike Smith 	command |= PCIM_CMD_BUSMASTEREN;
36335863739SMike Smith 	pci_write_config(dev, PCIR_COMMAND, command, 2);
36435863739SMike Smith 	command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
36535863739SMike Smith 	if (!(command & PCIM_CMD_BUSMASTEREN)) {
36635863739SMike Smith 		device_printf(sc->aac_dev, "can't enable bus-master feature\n");
36735863739SMike Smith 		goto out;
36835863739SMike Smith 	}
36935863739SMike Smith 	if ((command & PCIM_CMD_MEMEN) == 0) {
37035863739SMike Smith 		device_printf(sc->aac_dev, "memory window not available\n");
37135863739SMike Smith 		goto out;
37235863739SMike Smith 	}
37335863739SMike Smith 
37435863739SMike Smith 	/*
37535863739SMike Smith 	 * Allocate the PCI register window.
37635863739SMike Smith 	 */
3775b80c0d7SScott Long 	sc->aac_regs_rid = PCIR_BAR(0);
3785f96beb9SNate Lawson 	if ((sc->aac_regs_resource = bus_alloc_resource_any(sc->aac_dev,
379914da7d0SScott Long 							    SYS_RES_MEMORY,
380914da7d0SScott Long 							    &sc->aac_regs_rid,
3815f96beb9SNate Lawson 							    RF_ACTIVE)) ==
3825f96beb9SNate Lawson 							    NULL) {
383914da7d0SScott Long 		device_printf(sc->aac_dev,
384914da7d0SScott Long 			      "couldn't allocate register window\n");
38535863739SMike Smith 		goto out;
38635863739SMike Smith 	}
38735863739SMike Smith 	sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
38835863739SMike Smith 	sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
38935863739SMike Smith 
39035863739SMike Smith 	/* assume failure is 'out of memory' */
39135863739SMike Smith 	error = ENOMEM;
39235863739SMike Smith 
39335863739SMike Smith 	/*
39435863739SMike Smith 	 * Allocate the parent bus DMA tag appropriate for our PCI interface.
39535863739SMike Smith 	 *
39635863739SMike Smith 	 * Note that some of these controllers are 64-bit capable.
39735863739SMike Smith 	 */
39835863739SMike Smith 	if (bus_dma_tag_create(NULL, 			/* parent */
399cbfd045bSScott Long 			       PAGE_SIZE, 0,		/* algnmnt, boundary */
400a6d35632SScott Long 			       BUS_SPACE_MAXADDR,	/* lowaddr */
40135863739SMike Smith 			       BUS_SPACE_MAXADDR, 	/* highaddr */
40235863739SMike Smith 			       NULL, NULL, 		/* filter, filterarg */
403a6d35632SScott Long 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
4047cb209f5SScott Long 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
40535863739SMike Smith 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
406a6d35632SScott Long 			       0,			/* flags */
407f6b1c44dSScott Long 			       NULL, NULL,		/* No locking needed */
40835863739SMike Smith 			       &sc->aac_parent_dmat)) {
40935863739SMike Smith 		device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
41035863739SMike Smith 		goto out;
41135863739SMike Smith 	}
41235863739SMike Smith 
41335863739SMike Smith 	/*
414c6eafcf2SScott Long 	 * Detect the hardware interface version, set up the bus interface
415c6eafcf2SScott Long 	 * indirection.
41635863739SMike Smith 	 */
4172419217bSScott Long 	id = aac_find_ident(dev);
4182419217bSScott Long 	sc->aac_hwif = id->hwif;
41935863739SMike Smith 	switch(sc->aac_hwif) {
42035863739SMike Smith 	case AAC_HWIF_I960RX:
42131a0399eSEd Maste 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx");
42235863739SMike Smith 		sc->aac_if = aac_rx_interface;
42335863739SMike Smith 		break;
42435863739SMike Smith 	case AAC_HWIF_STRONGARM:
42531a0399eSEd Maste 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
42635863739SMike Smith 		sc->aac_if = aac_sa_interface;
42735863739SMike Smith 		break;
428b3457b51SScott Long 	case AAC_HWIF_FALCON:
42931a0399eSEd Maste 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Falcon/PPC");
430b3457b51SScott Long 		sc->aac_if = aac_fa_interface;
431b3457b51SScott Long 		break;
4324afedc31SScott Long 	case AAC_HWIF_RKT:
43331a0399eSEd Maste 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
4344afedc31SScott Long 		sc->aac_if = aac_rkt_interface;
4354afedc31SScott Long 		break;
4364afedc31SScott Long 	default:
4374afedc31SScott Long 		sc->aac_hwif = AAC_HWIF_UNKNOWN;
4380b94a66eSMike Smith 		device_printf(sc->aac_dev, "unknown hardware type\n");
4390b94a66eSMike Smith 		error = ENXIO;
4400b94a66eSMike Smith 		goto out;
4410b94a66eSMike Smith 	}
44235863739SMike Smith 
4432419217bSScott Long 	/* Set up quirks */
4442419217bSScott Long 	sc->flags = id->quirks;
445fe94b852SScott Long 
446fe94b852SScott Long 	/*
44735863739SMike Smith 	 * Do bus-independent initialisation.
44835863739SMike Smith 	 */
44935863739SMike Smith 	error = aac_attach(sc);
45035863739SMike Smith 
45135863739SMike Smith out:
45235863739SMike Smith 	if (error)
45335863739SMike Smith 		aac_free(sc);
45435863739SMike Smith 	return(error);
45535863739SMike Smith }
456608d7ac2SScott Long 
457608d7ac2SScott Long /*
458608d7ac2SScott Long  * Do nothing driver that will attach to the SCSI channels of a Dell PERC
459608d7ac2SScott Long  * controller.  This is needed to keep the power management subsystem from
460608d7ac2SScott Long  * trying to power down these devices.
461608d7ac2SScott Long  */
462608d7ac2SScott Long static int aacch_probe(device_t dev);
463608d7ac2SScott Long static int aacch_attach(device_t dev);
464608d7ac2SScott Long static int aacch_detach(device_t dev);
465608d7ac2SScott Long 
466608d7ac2SScott Long static device_method_t aacch_methods[] = {
467608d7ac2SScott Long 	/* Device interface */
468608d7ac2SScott Long 	DEVMETHOD(device_probe,		aacch_probe),
469608d7ac2SScott Long 	DEVMETHOD(device_attach,	aacch_attach),
470608d7ac2SScott Long 	DEVMETHOD(device_detach,	aacch_detach),
471608d7ac2SScott Long 	{ 0, 0 }
472608d7ac2SScott Long };
473608d7ac2SScott Long 
474608d7ac2SScott Long struct aacch_softc {
475608d7ac2SScott Long 	device_t	dev;
476608d7ac2SScott Long };
477608d7ac2SScott Long 
478608d7ac2SScott Long static driver_t aacch_driver = {
479608d7ac2SScott Long 	"aacch",
480608d7ac2SScott Long 	aacch_methods,
481608d7ac2SScott Long 	sizeof(struct aacch_softc)
482608d7ac2SScott Long };
483608d7ac2SScott Long 
484608d7ac2SScott Long static devclass_t	aacch_devclass;
485608d7ac2SScott Long DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, 0, 0);
486608d7ac2SScott Long 
487608d7ac2SScott Long static int
488608d7ac2SScott Long aacch_probe(device_t dev)
489608d7ac2SScott Long {
490608d7ac2SScott Long 
4911b3a4f4eSScott Long 	if ((pci_get_vendor(dev) != 0x9005) ||
4921b3a4f4eSScott Long 	    (pci_get_device(dev) != 0x00c5))
493608d7ac2SScott Long 		return (ENXIO);
494608d7ac2SScott Long 
495608d7ac2SScott Long 	device_set_desc(dev, "AAC RAID Channel");
496608d7ac2SScott Long 	return (-10);
497608d7ac2SScott Long }
498608d7ac2SScott Long 
499608d7ac2SScott Long static int
500608d7ac2SScott Long aacch_attach(device_t dev)
501608d7ac2SScott Long {
502608d7ac2SScott Long 	struct aacch_softc *sc;
503608d7ac2SScott Long 
504608d7ac2SScott Long 	sc = device_get_softc(dev);
505608d7ac2SScott Long 
506608d7ac2SScott Long 	sc->dev = dev;
507608d7ac2SScott Long 
508608d7ac2SScott Long 	return (0);
509608d7ac2SScott Long }
510608d7ac2SScott Long 
511608d7ac2SScott Long static int
512608d7ac2SScott Long aacch_detach(device_t dev)
513608d7ac2SScott Long {
514608d7ac2SScott Long 
515608d7ac2SScott Long 	return (0);
516608d7ac2SScott Long }
517