xref: /freebsd/sys/dev/aac/aac_pci.c (revision 329e817fcc97aa847765c5171cc89a81a0b25527)
135863739SMike Smith /*-
2718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3718cf2ccSPedro F. Giffuni  *
435863739SMike Smith  * Copyright (c) 2000 Michael Smith
5c6eafcf2SScott Long  * Copyright (c) 2001 Scott Long
635863739SMike Smith  * Copyright (c) 2000 BSDi
7fadfef89SScott Long  * Copyright (c) 2001 Adaptec, Inc.
835863739SMike Smith  * All rights reserved.
935863739SMike Smith  *
1035863739SMike Smith  * Redistribution and use in source and binary forms, with or without
1135863739SMike Smith  * modification, are permitted provided that the following conditions
1235863739SMike Smith  * are met:
1335863739SMike Smith  * 1. Redistributions of source code must retain the above copyright
1435863739SMike Smith  *    notice, this list of conditions and the following disclaimer.
1535863739SMike Smith  * 2. Redistributions in binary form must reproduce the above copyright
1635863739SMike Smith  *    notice, this list of conditions and the following disclaimer in the
1735863739SMike Smith  *    documentation and/or other materials provided with the distribution.
1835863739SMike Smith  *
1935863739SMike Smith  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2035863739SMike Smith  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2135863739SMike Smith  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2235863739SMike Smith  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2335863739SMike Smith  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2435863739SMike Smith  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2535863739SMike Smith  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2635863739SMike Smith  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2735863739SMike Smith  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2835863739SMike Smith  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2935863739SMike Smith  * SUCH DAMAGE.
3035863739SMike Smith  */
3135863739SMike Smith 
32aad970f1SDavid E. O'Brien #include <sys/cdefs.h>
33aad970f1SDavid E. O'Brien __FBSDID("$FreeBSD$");
34aad970f1SDavid E. O'Brien 
3535863739SMike Smith /*
3635863739SMike Smith  * PCI bus interface and resource allocation.
3735863739SMike Smith  */
3835863739SMike Smith 
39f6c4dd3fSScott Long #include "opt_aac.h"
40f6c4dd3fSScott Long 
4135863739SMike Smith #include <sys/param.h>
4235863739SMike Smith #include <sys/systm.h>
4335863739SMike Smith #include <sys/kernel.h>
44fe12f24bSPoul-Henning Kamp #include <sys/module.h>
4535863739SMike Smith 
469e2e96d8SScott Long #include <sys/bio.h>
4735863739SMike Smith #include <sys/bus.h>
4835863739SMike Smith #include <sys/conf.h>
4935863739SMike Smith #include <sys/disk.h>
5035863739SMike Smith 
5135863739SMike Smith #include <machine/bus.h>
5235863739SMike Smith #include <machine/resource.h>
5335863739SMike Smith #include <sys/rman.h>
5435863739SMike Smith 
55dc5f7dd0SWarner Losh #include <dev/pci/pcireg.h>
56dc5f7dd0SWarner Losh #include <dev/pci/pcivar.h>
5735863739SMike Smith 
5835863739SMike Smith #include <dev/aac/aacreg.h>
590b0594cdSScott Long #include <sys/aac_ioctl.h>
6035863739SMike Smith #include <dev/aac/aacvar.h>
6135863739SMike Smith 
6235863739SMike Smith static int	aac_pci_probe(device_t dev);
6335863739SMike Smith static int	aac_pci_attach(device_t dev);
6435863739SMike Smith 
65da4882c2SMarius Strobl static int aac_enable_msi = 1;
66da4882c2SMarius Strobl SYSCTL_INT(_hw_aac, OID_AUTO, enable_msi, CTLFLAG_RDTUN, &aac_enable_msi, 0,
67da4882c2SMarius Strobl     "Enable MSI interrupts");
68da4882c2SMarius Strobl 
6935863739SMike Smith static device_method_t aac_methods[] = {
7035863739SMike Smith 	/* Device interface */
7135863739SMike Smith 	DEVMETHOD(device_probe,		aac_pci_probe),
7235863739SMike Smith 	DEVMETHOD(device_attach,	aac_pci_attach),
7335863739SMike Smith 	DEVMETHOD(device_detach,	aac_detach),
7435863739SMike Smith 	DEVMETHOD(device_suspend,	aac_suspend),
7535863739SMike Smith 	DEVMETHOD(device_resume,	aac_resume),
7635863739SMike Smith 
774b7ec270SMarius Strobl 	DEVMETHOD_END
7835863739SMike Smith };
7935863739SMike Smith 
8035863739SMike Smith static driver_t aac_pci_driver = {
8135863739SMike Smith 	"aac",
8235863739SMike Smith 	aac_methods,
8335863739SMike Smith 	sizeof(struct aac_softc)
8435863739SMike Smith };
8535863739SMike Smith 
86e45bef2aSMike Smith static devclass_t	aac_devclass;
87e45bef2aSMike Smith 
88da4882c2SMarius Strobl DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, NULL, NULL);
89b3d93fd0SMatt Jacob MODULE_DEPEND(aac, pci, 1, 1, 1);
90b3d93fd0SMatt Jacob 
91da4882c2SMarius Strobl static const struct aac_ident
9235863739SMike Smith {
9335863739SMike Smith 	u_int16_t		vendor;
9435863739SMike Smith 	u_int16_t		device;
9535863739SMike Smith 	u_int16_t		subvendor;
9635863739SMike Smith 	u_int16_t		subdevice;
9735863739SMike Smith 	int			hwif;
98fe3cb0e1SScott Long 	int			quirks;
99da4882c2SMarius Strobl 	const char		*desc;
10035863739SMike Smith } aac_identifiers[] = {
101a6d35632SScott Long 	{0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, 0,
102fe3cb0e1SScott Long 	"Dell PERC 2/Si"},
103a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x0002, AAC_HWIF_I960RX, 0,
104fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
105a6d35632SScott Long 	{0x1028, 0x0003, 0x1028, 0x0003, AAC_HWIF_I960RX, 0,
106fe3cb0e1SScott Long 	"Dell PERC 3/Si"},
107a6d35632SScott Long 	{0x1028, 0x0004, 0x1028, 0x00d0, AAC_HWIF_I960RX, 0,
108fe3cb0e1SScott Long 	"Dell PERC 3/Si"},
109a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x00d1, AAC_HWIF_I960RX, 0,
110fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
111a6d35632SScott Long 	{0x1028, 0x0002, 0x1028, 0x00d9, AAC_HWIF_I960RX, 0,
112fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
113a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x0106, AAC_HWIF_I960RX, 0,
114fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
115a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x011b, AAC_HWIF_I960RX, 0,
116fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
117a6d35632SScott Long 	{0x1028, 0x000a, 0x1028, 0x0121, AAC_HWIF_I960RX, 0,
118fe3cb0e1SScott Long 	"Dell PERC 3/Di"},
119a6d35632SScott Long 	{0x1011, 0x0046, 0x9005, 0x0364, AAC_HWIF_STRONGARM, 0,
120fe3cb0e1SScott Long 	"Adaptec AAC-364"},
1214b00f859SScott Long 	{0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
1224b00f859SScott Long 	 AAC_FLAGS_BROKEN_MEMMAP, "Adaptec SCSI RAID 5400S"},
123a6d35632SScott Long 	{0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, AAC_FLAGS_PERC2QC,
124a6d35632SScott Long 	 "Dell PERC 2/QC"},
125a6d35632SScott Long 	{0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, 0,
126a9f3d2c7SScott Long 	 "HP NetRaid-4M"},
127a6d35632SScott Long 	{0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
128a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
129a6d35632SScott Long 	{0x9005, 0x0285, 0x1028, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
130a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Dell PERC 320/DC"},
131a6d35632SScott Long 	{0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
132a6d35632SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2120S"},
1339d5be300SScott Long 	{0x9005, 0x0285, 0x9005, 0x0290, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1347598d049SChristian Brueffer 	 "Adaptec SATA RAID 2410SA"},
135ad452e65SScott Long 	{0x9005, 0x0285, 0x1028, 0x0291, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
136ad452e65SScott Long 	 "Dell CERC SATA RAID 2"},
137ad452e65SScott Long 	{0x9005, 0x0285, 0x9005, 0x0292, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1387598d049SChristian Brueffer 	 "Adaptec SATA RAID 2810SA"},
139b1e56e58SScott Long 	{0x9005, 0x0285, 0x9005, 0x0293, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
1407598d049SChristian Brueffer 	 "Adaptec SATA RAID 21610SA"},
14116ee26fdSPaul Saab 	{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
14216ee26fdSPaul Saab 	 "HP ML110 G2 (Adaptec 2610SA)"},
14321e5a222SMarius Strobl 	{0x9005, 0x0286, 0x9005, 0x028c, AAC_HWIF_RKT, AAC_FLAGS_NOMSI,
144ecefe571SScott Long 	 "Adaptec SCSI RAID 2230S"},
1454afedc31SScott Long 	{0x9005, 0x0286, 0x9005, 0x028d, AAC_HWIF_RKT, 0,
1464afedc31SScott Long 	 "Adaptec SCSI RAID 2130S"},
1477cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1487cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
1497cb209f5SScott Long 	{0x9005, 0x0285, 0x17aa, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1507cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Legend S220"},
1517cb209f5SScott Long 	{0x9005, 0x0285, 0x17aa, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
1527cb209f5SScott Long 	 AAC_FLAGS_256FIBS, "Legend S230"},
1537cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0288, AAC_HWIF_I960RX, 0,
1547cb209f5SScott Long 	 "Adaptec SCSI RAID 3230S"},
1557cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0289, AAC_HWIF_I960RX, 0,
1567cb209f5SScott Long 	 "Adaptec SCSI RAID 3240S"},
1577cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028a, AAC_HWIF_I960RX, 0,
1587cb209f5SScott Long 	 "Adaptec SCSI RAID 2020ZCR"},
1597cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x028b, AAC_HWIF_I960RX, 0,
1607cb209f5SScott Long 	 "Adaptec SCSI RAID 2025ZCR"},
16121e5a222SMarius Strobl 	{0x9005, 0x0286, 0x9005, 0x029b, AAC_HWIF_RKT, AAC_FLAGS_NOMSI,
1627cb209f5SScott Long 	 "Adaptec SATA RAID 2820SA"},
1637cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029c, AAC_HWIF_RKT, 0,
1647cb209f5SScott Long 	 "Adaptec SATA RAID 2620SA"},
1657cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029d, AAC_HWIF_RKT, 0,
1667cb209f5SScott Long 	 "Adaptec SATA RAID 2420SA"},
1677cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029e, AAC_HWIF_RKT, 0,
1687598d049SChristian Brueffer 	 "ICP ICP9024RO SCSI RAID"},
1697cb209f5SScott Long 	{0x9005, 0x0286, 0x9005, 0x029f, AAC_HWIF_RKT, 0,
1707598d049SChristian Brueffer 	 "ICP ICP9014RO SCSI RAID"},
1717cb209f5SScott Long 	{0x9005, 0x0285, 0x9005, 0x0294, AAC_HWIF_I960RX, 0,
1727cb209f5SScott Long 	 "Adaptec SATA RAID 2026ZCR"},
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,
182e71d3b9cSEd Maste 	 "Adaptec RAID 4000"},
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 };
283da4882c2SMarius Strobl 
284da4882c2SMarius Strobl static const struct aac_ident
2857ea2d558SEd Maste aac_family_identifiers[] = {
2867ea2d558SEd Maste 	{0x9005, 0x0285, 0, 0, AAC_HWIF_I960RX, 0,
2877ea2d558SEd Maste 	 "Adaptec RAID Controller"},
2887ea2d558SEd Maste 	{0x9005, 0x0286, 0, 0, AAC_HWIF_RKT, 0,
2897ea2d558SEd Maste 	 "Adaptec RAID Controller"},
2907ea2d558SEd Maste 	{0, 0, 0, 0, 0, 0, 0}
2917ea2d558SEd Maste };
29235863739SMike Smith 
293da4882c2SMarius Strobl static const struct aac_ident *
2942419217bSScott Long aac_find_ident(device_t dev)
2952419217bSScott Long {
296da4882c2SMarius Strobl 	const struct aac_ident *m;
2977ea2d558SEd Maste 	u_int16_t vendid, devid, sub_vendid, sub_devid;
2987ea2d558SEd Maste 
2997ea2d558SEd Maste 	vendid = pci_get_vendor(dev);
3007ea2d558SEd Maste 	devid = pci_get_device(dev);
3017ea2d558SEd Maste 	sub_vendid = pci_get_subvendor(dev);
3027ea2d558SEd Maste 	sub_devid = pci_get_subdevice(dev);
3032419217bSScott Long 
3042419217bSScott Long 	for (m = aac_identifiers; m->vendor != 0; m++) {
3057ea2d558SEd Maste 		if ((m->vendor == vendid) && (m->device == devid) &&
3067ea2d558SEd Maste 		    (m->subvendor == sub_vendid) &&
3077ea2d558SEd Maste 		    (m->subdevice == sub_devid))
3087ea2d558SEd Maste 			return (m);
3097ea2d558SEd Maste 	}
3107ea2d558SEd Maste 
3117ea2d558SEd Maste 	for (m = aac_family_identifiers; m->vendor != 0; m++) {
3127ea2d558SEd Maste 		if ((m->vendor == vendid) && (m->device == devid))
3132419217bSScott Long 			return (m);
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 {
324da4882c2SMarius Strobl 	const 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;
342da4882c2SMarius Strobl 	const struct aac_ident *id;
34321e5a222SMarius Strobl 	int count, error, rid;
34435863739SMike Smith 
34531a0399eSEd Maste 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
34635863739SMike Smith 
34735863739SMike Smith 	/*
34835863739SMike Smith 	 * Initialise softc.
34935863739SMike Smith 	 */
35035863739SMike Smith 	sc = device_get_softc(dev);
35135863739SMike Smith 	sc->aac_dev = dev;
35235863739SMike Smith 
35335863739SMike Smith 	/* assume failure is 'not configured' */
35435863739SMike Smith 	error = ENXIO;
35535863739SMike Smith 
35635863739SMike Smith 	/*
35735863739SMike Smith 	 * Verify that the adapter is correctly set up in PCI space.
35835863739SMike Smith 	 */
359da4882c2SMarius Strobl 	pci_enable_busmaster(dev);
360da4882c2SMarius Strobl 	if (!(pci_read_config(dev, PCIR_COMMAND, 2) & PCIM_CMD_BUSMASTEREN)) {
361da4882c2SMarius Strobl 		device_printf(dev, "can't enable bus-master feature\n");
36235863739SMike Smith 		goto out;
36335863739SMike Smith 	}
36435863739SMike Smith 
36535863739SMike Smith 	/*
36621e5a222SMarius Strobl 	 * Detect the hardware interface version, set up the bus interface
36721e5a222SMarius Strobl 	 * indirection.
36821e5a222SMarius Strobl 	 */
36921e5a222SMarius Strobl 	id = aac_find_ident(dev);
37021e5a222SMarius Strobl 	sc->aac_hwif = id->hwif;
37121e5a222SMarius Strobl 	switch(sc->aac_hwif) {
37221e5a222SMarius Strobl 	case AAC_HWIF_I960RX:
37321e5a222SMarius Strobl 	case AAC_HWIF_NARK:
37421e5a222SMarius Strobl 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
37521e5a222SMarius Strobl 		    "set hardware up for i960Rx/NARK");
37621e5a222SMarius Strobl 		sc->aac_if = &aac_rx_interface;
37721e5a222SMarius Strobl 		break;
37821e5a222SMarius Strobl 	case AAC_HWIF_STRONGARM:
37921e5a222SMarius Strobl 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
38021e5a222SMarius Strobl 		    "set hardware up for StrongARM");
38121e5a222SMarius Strobl 		sc->aac_if = &aac_sa_interface;
38221e5a222SMarius Strobl 		break;
38321e5a222SMarius Strobl 	case AAC_HWIF_RKT:
38421e5a222SMarius Strobl 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
38521e5a222SMarius Strobl 		    "set hardware up for Rocket/MIPS");
38621e5a222SMarius Strobl 		sc->aac_if = &aac_rkt_interface;
38721e5a222SMarius Strobl 		break;
38821e5a222SMarius Strobl 	default:
38921e5a222SMarius Strobl 		sc->aac_hwif = AAC_HWIF_UNKNOWN;
39021e5a222SMarius Strobl 		device_printf(dev, "unknown hardware type\n");
39121e5a222SMarius Strobl 		goto out;
39221e5a222SMarius Strobl 	}
39321e5a222SMarius Strobl 
39421e5a222SMarius Strobl 	/* Set up quirks */
39521e5a222SMarius Strobl 	sc->flags = id->quirks;
39621e5a222SMarius Strobl 
39721e5a222SMarius Strobl 	/*
398da4882c2SMarius Strobl 	 * Allocate the PCI register window(s).
39935863739SMike Smith 	 */
400da4882c2SMarius Strobl 	rid = PCIR_BAR(0);
401da4882c2SMarius Strobl 	if ((sc->aac_regs_res0 = bus_alloc_resource_any(dev,
402da4882c2SMarius Strobl 	    SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) {
403da4882c2SMarius Strobl 		device_printf(dev, "can't allocate register window 0\n");
40435863739SMike Smith 		goto out;
40535863739SMike Smith 	}
406ff0991c4SAttilio Rao 	sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
407ff0991c4SAttilio Rao 	sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
40835863739SMike Smith 
409ff0991c4SAttilio Rao 	if (sc->aac_hwif == AAC_HWIF_NARK) {
410da4882c2SMarius Strobl 		rid = PCIR_BAR(1);
411da4882c2SMarius Strobl 		if ((sc->aac_regs_res1 = bus_alloc_resource_any(dev,
412da4882c2SMarius Strobl 		    SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) {
413da4882c2SMarius Strobl 			device_printf(dev,
414da4882c2SMarius Strobl 			    "can't allocate register window 1\n");
415ff0991c4SAttilio Rao 			goto out;
416ff0991c4SAttilio Rao 		}
417ff0991c4SAttilio Rao 		sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
418ff0991c4SAttilio Rao 		sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
419ff0991c4SAttilio Rao 	} else {
420ff0991c4SAttilio Rao 		sc->aac_regs_res1 = sc->aac_regs_res0;
421ff0991c4SAttilio Rao 		sc->aac_btag1 = sc->aac_btag0;
422ff0991c4SAttilio Rao 		sc->aac_bhandle1 = sc->aac_bhandle0;
423ff0991c4SAttilio Rao 	}
42435863739SMike Smith 
42535863739SMike Smith 	/*
426da4882c2SMarius Strobl 	 * Allocate the interrupt.
427da4882c2SMarius Strobl 	 */
428da4882c2SMarius Strobl 	rid = 0;
4290cfcfc19SMarius Strobl 	if (aac_enable_msi != 0 && (sc->flags & AAC_FLAGS_NOMSI) == 0) {
430da4882c2SMarius Strobl 		count = 1;
4310cfcfc19SMarius Strobl 		if (pci_alloc_msi(dev, &count) == 0)
432da4882c2SMarius Strobl 			rid = 1;
433da4882c2SMarius Strobl 	}
434da4882c2SMarius Strobl 	if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
4350cfcfc19SMarius Strobl 	    &rid, RF_ACTIVE | (rid != 0 ? 0 : RF_SHAREABLE))) == NULL) {
436da4882c2SMarius Strobl 		device_printf(dev, "can't allocate interrupt\n");
437da4882c2SMarius Strobl 		goto out;
438da4882c2SMarius Strobl 	}
439da4882c2SMarius Strobl 
440da4882c2SMarius Strobl 	/*
44135863739SMike Smith 	 * Allocate the parent bus DMA tag appropriate for our PCI interface.
44235863739SMike Smith 	 *
44335863739SMike Smith 	 * Note that some of these controllers are 64-bit capable.
44435863739SMike Smith 	 */
445da4882c2SMarius Strobl 	if (bus_dma_tag_create(bus_get_dma_tag(dev),	/* parent */
44655b44675SEd Maste 			       PAGE_SIZE, 0,		/* algnmnt, boundary */
447a6d35632SScott Long 			       BUS_SPACE_MAXADDR,	/* lowaddr */
44835863739SMike Smith 			       BUS_SPACE_MAXADDR, 	/* highaddr */
44935863739SMike Smith 			       NULL, NULL, 		/* filter, filterarg */
450a6d35632SScott Long 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
4517cb209f5SScott Long 			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
45235863739SMike Smith 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
453a6d35632SScott Long 			       0,			/* flags */
454f6b1c44dSScott Long 			       NULL, NULL,		/* No locking needed */
45535863739SMike Smith 			       &sc->aac_parent_dmat)) {
456da4882c2SMarius Strobl 		device_printf(dev, "can't allocate parent DMA tag\n");
45735863739SMike Smith 		goto out;
45835863739SMike Smith 	}
45935863739SMike Smith 
46035863739SMike Smith 	/*
46135863739SMike Smith 	 * Do bus-independent initialisation.
46235863739SMike Smith 	 */
46335863739SMike Smith 	error = aac_attach(sc);
46435863739SMike Smith 
46535863739SMike Smith out:
46635863739SMike Smith 	if (error)
46735863739SMike Smith 		aac_free(sc);
46835863739SMike Smith 	return(error);
46935863739SMike Smith }
470608d7ac2SScott Long 
471608d7ac2SScott Long /*
472608d7ac2SScott Long  * Do nothing driver that will attach to the SCSI channels of a Dell PERC
473608d7ac2SScott Long  * controller.  This is needed to keep the power management subsystem from
474608d7ac2SScott Long  * trying to power down these devices.
475608d7ac2SScott Long  */
476608d7ac2SScott Long static int aacch_probe(device_t dev);
477608d7ac2SScott Long static int aacch_attach(device_t dev);
478608d7ac2SScott Long static int aacch_detach(device_t dev);
479608d7ac2SScott Long 
480608d7ac2SScott Long static device_method_t aacch_methods[] = {
481608d7ac2SScott Long 	/* Device interface */
482608d7ac2SScott Long 	DEVMETHOD(device_probe,		aacch_probe),
483608d7ac2SScott Long 	DEVMETHOD(device_attach,	aacch_attach),
484608d7ac2SScott Long 	DEVMETHOD(device_detach,	aacch_detach),
485da4882c2SMarius Strobl 	DEVMETHOD_END
486608d7ac2SScott Long };
487608d7ac2SScott Long 
488608d7ac2SScott Long static driver_t aacch_driver = {
489608d7ac2SScott Long 	"aacch",
490608d7ac2SScott Long 	aacch_methods,
4910cfcfc19SMarius Strobl 	1	/* no softc */
492608d7ac2SScott Long };
493608d7ac2SScott Long 
494608d7ac2SScott Long static devclass_t	aacch_devclass;
495da4882c2SMarius Strobl DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, NULL, NULL);
49616bc63ecSWarner Losh MODULE_PNP_INFO("U16:vendor;U16:device;", pci, aac,
497*329e817fSWarner Losh     aac_identifiers, nitems(aac_identifiers) - 1);
498608d7ac2SScott Long 
499608d7ac2SScott Long static int
500608d7ac2SScott Long aacch_probe(device_t dev)
501608d7ac2SScott Long {
502608d7ac2SScott Long 
5031b3a4f4eSScott Long 	if ((pci_get_vendor(dev) != 0x9005) ||
5041b3a4f4eSScott Long 	    (pci_get_device(dev) != 0x00c5))
505608d7ac2SScott Long 		return (ENXIO);
506608d7ac2SScott Long 
507608d7ac2SScott Long 	device_set_desc(dev, "AAC RAID Channel");
508608d7ac2SScott Long 	return (-10);
509608d7ac2SScott Long }
510608d7ac2SScott Long 
511608d7ac2SScott Long static int
5120cfcfc19SMarius Strobl aacch_attach(device_t dev __unused)
513608d7ac2SScott Long {
514608d7ac2SScott Long 
515608d7ac2SScott Long 	return (0);
516608d7ac2SScott Long }
517608d7ac2SScott Long 
518608d7ac2SScott Long static int
5190cfcfc19SMarius Strobl aacch_detach(device_t dev __unused)
520608d7ac2SScott Long {
521608d7ac2SScott Long 
522608d7ac2SScott Long 	return (0);
523608d7ac2SScott Long }
524