From 90bea385446a712c3d1c7126eedf1742d310409c Mon Sep 17 00:00:00 2001 From: marius Date: Fri, 9 Aug 2013 18:57:18 +0000 Subject: [PATCH] MFC: r254004 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 at 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] Approved by: re (kib) git-svn-id: svn://svn.freebsd.org/base/releng/9.2@254154 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/aac/aac_pci.c | 73 ++++++++++++++++++++++--------------------- sys/dev/aac/aacvar.h | 8 ++--- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c index f768c8b2..b7383835 100644 --- a/sys/dev/aac/aac_pci.c +++ b/sys/dev/aac/aac_pci.c @@ -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, ®) == 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. */ diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h index 18ae0b21..0950a2f6 100644 --- a/sys/dev/aac/aacvar.h +++ b/sys/dev/aac/aacvar.h @@ -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) \ -- 2.42.0