Don't attach to Dell PERC2/QC cards that have a firmware rev of 1.x. This

check is complicated by the fact that the Adaptec 5400S cards claim to use
1.x firmware also.  PERC2/QC 1.x firmware is not compatible with this driver
and will cause a system hang.

MFC after:	3 days
This commit is contained in:
Scott Long 2002-02-06 01:34:09 +00:00
parent 0b94a0e9f9
commit fe94b852b3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=90275
4 changed files with 51 additions and 0 deletions

View file

@ -100,6 +100,7 @@ static void aac_unmap_command(struct aac_command *cm);
/* Hardware Interface */
static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
int error);
static int aac_check_firmware(struct aac_softc *sc);
static int aac_init(struct aac_softc *sc);
static int aac_sync_command(struct aac_softc *sc, u_int32_t command,
u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
@ -258,6 +259,12 @@ aac_attach(struct aac_softc *sc)
/* mark controller as suspended until we get ourselves organised */
sc->aac_state |= AAC_STATE_SUSPEND;
/*
* Check that the firmware on the card is supported.
*/
if ((error = aac_check_firmware(sc)) != 0)
return(error);
/*
* Allocate command structures.
*/
@ -1345,6 +1352,39 @@ aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
sc->aac_common_busaddr = segs[0].ds_addr;
}
/*
* Retrieve the firmware version numbers. Dell PERC2/QC cards with
* firmware version 1.x are not compatible with this driver.
*/
static int
aac_check_firmware(struct aac_softc *sc)
{
u_int32_t major, minor;
debug_called(1);
if (sc->quirks & AAC_QUIRK_PERC2QC) {
if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
NULL)) {
device_printf(sc->aac_dev,
"Error reading firmware version\n");
return (EIO);
}
/* These numbers are stored as ASCII! */
major = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 4) & 0xff) - 0x30;
minor = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 8) & 0xff) - 0x30;
if (major == 1) {
device_printf(sc->aac_dev,
"Firmware version %d.%d is not supported.\n",
major, minor);
return (EINVAL);
}
}
return (0);
}
static int
aac_init(struct aac_softc *sc)
{

View file

@ -295,6 +295,14 @@ aac_pci_attach(device_t dev)
goto out;
}
/*
* Check for quirky hardware
*/
if (pci_get_subdevice(dev) == 0x1364 &&
pci_get_subvendor(dev) == 0x9005)
sc->quirks |= AAC_QUIRK_PERC2QC;
/*
* Do bus-independent initialisation.
*/

View file

@ -523,6 +523,7 @@ struct aac_adapter_info {
*/
#define AAC_MONKER_INITSTRUCT 0x05
#define AAC_MONKER_SYNCFIB 0x0c
#define AAC_MONKER_GETKERNVER 0x11
/*
* Adapter Status Register

View file

@ -356,6 +356,8 @@ struct aac_softc
#define AAC_AIFFLAGS_PENDING (1 << 1)
#define AAC_AIFFLAGS_EXIT (1 << 2)
#define AAC_AIFFLAGS_EXITED (1 << 3)
u_int32_t quirks;
#define AAC_QUIRK_PERC2QC (1 << 0)
};