As it turns out, MSIs are broken with 2820SA so introduce an AAC_FLAGS_NOMSI

quirk and apply it to these controllers [1]. The same problem was reported
for 2230S, in which case it wasn't actually clear whether the culprit is the
controller or the mainboard, though. In order to be on the safe side, flag
MSIs as being broken with the latter type of controller as well. Given that
these are the only reports of MSI-related breakage with aac(4) so far and
OSes like OpenSolaris unconditionally employ MSIs for all adapters of this
family, however, it doesn't seem warranted to generally disable the use of
MSIs in aac(4).
While it, simplify the MSI allocation logic a bit; there's no need to check
for the presence of the MSI capability on our own as pci_alloc_msi(9) will
just fail when these kind of interrupts are not available.
Reported and tested by: David Boyd [1]

MFC after:	3 days
This commit is contained in:
Marius Strobl 2013-08-06 18:55:59 +00:00
parent 54a6317360
commit 21e5a2223c
2 changed files with 41 additions and 40 deletions

View File

@ -139,7 +139,7 @@ static const struct aac_ident
"Adaptec SATA RAID 21610SA"},
{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
"HP ML110 G2 (Adaptec 2610SA)"},
{0x9005, 0x0286, 0x9005, 0x028c, AAC_HWIF_RKT, 0,
{0x9005, 0x0286, 0x9005, 0x028c, AAC_HWIF_RKT, AAC_FLAGS_NOMSI,
"Adaptec SCSI RAID 2230S"},
{0x9005, 0x0286, 0x9005, 0x028d, AAC_HWIF_RKT, 0,
"Adaptec SCSI RAID 2130S"},
@ -157,7 +157,7 @@ static const struct aac_ident
"Adaptec SCSI RAID 2020ZCR"},
{0x9005, 0x0285, 0x9005, 0x028b, AAC_HWIF_I960RX, 0,
"Adaptec SCSI RAID 2025ZCR"},
{0x9005, 0x0286, 0x9005, 0x029b, AAC_HWIF_RKT, 0,
{0x9005, 0x0286, 0x9005, 0x029b, AAC_HWIF_RKT, AAC_FLAGS_NOMSI,
"Adaptec SATA RAID 2820SA"},
{0x9005, 0x0286, 0x9005, 0x029c, AAC_HWIF_RKT, 0,
"Adaptec SATA RAID 2620SA"},
@ -311,7 +311,6 @@ aac_find_ident(device_t dev)
if ((m->vendor == vendid) && (m->device == devid))
return (m);
}
return (NULL);
}
@ -340,7 +339,7 @@ aac_pci_attach(device_t dev)
{
struct aac_softc *sc;
const struct aac_ident *id;
int count, error, reg, rid;
int count, error, rid;
fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
@ -362,6 +361,38 @@ aac_pci_attach(device_t dev)
goto out;
}
/*
* Detect the hardware interface version, set up the bus interface
* indirection.
*/
id = aac_find_ident(dev);
sc->aac_hwif = id->hwif;
switch(sc->aac_hwif) {
case AAC_HWIF_I960RX:
case AAC_HWIF_NARK:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
"set hardware up for i960Rx/NARK");
sc->aac_if = &aac_rx_interface;
break;
case AAC_HWIF_STRONGARM:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
"set hardware up for StrongARM");
sc->aac_if = &aac_sa_interface;
break;
case AAC_HWIF_RKT:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B,
"set hardware up for Rocket/MIPS");
sc->aac_if = &aac_rkt_interface;
break;
default:
sc->aac_hwif = AAC_HWIF_UNKNOWN;
device_printf(dev, "unknown hardware type\n");
goto out;
}
/* Set up quirks */
sc->flags = id->quirks;
/*
* Allocate the PCI register window(s).
*/
@ -395,8 +426,8 @@ aac_pci_attach(device_t dev)
*/
rid = 0;
count = 0;
if (aac_enable_msi != 0 && pci_find_cap(dev, PCIY_MSI, &reg) == 0) {
count = pci_msi_count(dev);
if (aac_enable_msi != 0 && (sc->flags & AAC_FLAGS_NOMSI) == 0 &&
(count = pci_msi_count(dev)) != 0) {
if (count > 1)
count = 1;
else
@ -430,36 +461,6 @@ aac_pci_attach(device_t dev)
goto out;
}
/*
* Detect the hardware interface version, set up the bus interface
* indirection.
*/
id = aac_find_ident(dev);
sc->aac_hwif = id->hwif;
switch(sc->aac_hwif) {
case AAC_HWIF_I960RX:
case AAC_HWIF_NARK:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK");
sc->aac_if = &aac_rx_interface;
break;
case AAC_HWIF_STRONGARM:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
sc->aac_if = &aac_sa_interface;
break;
case AAC_HWIF_RKT:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
sc->aac_if = &aac_rkt_interface;
break;
default:
sc->aac_hwif = AAC_HWIF_UNKNOWN;
device_printf(dev, "unknown hardware type\n");
error = ENXIO;
goto out;
}
/* Set up quirks */
sc->flags = id->quirks;
/*
* Do bus-independent initialisation.
*/

View File

@ -62,7 +62,7 @@ SYSCTL_DECL(_hw_aac);
* The firmware interface allows for a 16-bit s/g list length. We limit
* ourselves to a reasonable maximum and ensure alignment.
*/
#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */
#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */
/*
* We allocate a small set of FIBs for the adapter to use to send us messages.
@ -224,7 +224,7 @@ struct aac_common {
/* buffer for text messages from the controller */
char ac_printf[AAC_PRINTF_BUFSIZE];
/* fib for synchronous commands */
struct aac_fib ac_sync_fib;
};
@ -406,12 +406,13 @@ struct aac_softc
#define AAC_FLAGS_NO4GB (1 << 6) /* Can't access host mem >2GB */
#define AAC_FLAGS_256FIBS (1 << 7) /* Can only do 256 commands */
#define AAC_FLAGS_BROKEN_MEMMAP (1 << 8) /* Broken HostPhysMemPages */
#define AAC_FLAGS_SLAVE (1 << 9)
#define AAC_FLAGS_SLAVE (1 << 9)
#define AAC_FLAGS_MASTER (1 << 10)
#define AAC_FLAGS_NEW_COMM (1 << 11) /* New comm. interface supported */
#define AAC_FLAGS_RAW_IO (1 << 12) /* Raw I/O interface */
#define AAC_FLAGS_ARRAY_64BIT (1 << 13) /* 64-bit array size */
#define AAC_FLAGS_LBA_64BIT (1 << 14) /* 64-bit LBA support */
#define AAC_FLAGS_NOMSI (1 << 31) /* Broken MSI */
u_int32_t supported_options;
u_int32_t scsi_method_id;
@ -527,7 +528,6 @@ struct aac_code_lookup {
sc->aac_qstat[qname].q_max = 0; \
} while (0)
#define AACQ_COMMAND_QUEUE(name, index) \
static __inline void \
aac_initq_ ## name (struct aac_softc *sc) \