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