diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2004-12-26 00:11:25 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2004-12-26 00:11:25 +0000 |
commit | d183791fce4eeb99a399a9ba4c1de10f297d5194 (patch) | |
tree | c931c1a0b509b7c1438df448213491ff507709da /sys/dev/pci | |
parent | f61599123255c5e32425e5311bf19a99877520b3 (diff) |
This should fix long outstanding issues with ami(4). The reported
symptoms that were fixed are:
* Very slow throughput
* ccb timeout (i.e. ami0: timeout ccb 1)
* All IO to ami devices hangs
* Only 1 LD (Logical Drive) can be accessed at the same time
* System hangs/freezes when running IO to ami cards.
Issues it doesn't fix:
* Really old ULTRA-2 controllers still crash whenever more than 1 LD are
accessed at the same time therefore the driver limits the maximum LDs to 1.
Tested by several folks and ok beck@ mickey@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/ami_pci.c | 71 |
1 files changed, 54 insertions, 17 deletions
diff --git a/sys/dev/pci/ami_pci.c b/sys/dev/pci/ami_pci.c index afe418f5d33..28ec9ee9b12 100644 --- a/sys/dev/pci/ami_pci.c +++ b/sys/dev/pci/ami_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ami_pci.c,v 1.20 2004/11/22 21:09:18 deraadt Exp $ */ +/* $OpenBSD: ami_pci.c,v 1.21 2004/12/26 00:11:24 marco Exp $ */ /* * Copyright (c) 2001 Michael Shalayeff @@ -62,6 +62,7 @@ #define AMI_SGL_LHC 0x00000299 #define AMI_SGL_HLC 0x00000199 +int ami_pci_find_device(void *); int ami_pci_match(struct device *, void *, void *); void ami_pci_attach(struct device *, struct device *, void *); @@ -77,12 +78,13 @@ struct ami_pci_device { #define AMI_CHECK_SIGN 0x001 } ami_pci_devices[] = { { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID, 0 }, - { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID428, 0 }, - { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID434, 0 }, + { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID428, AMI_BROKEN }, + { PCI_VENDOR_AMI, PCI_PRODUCT_AMI_MEGARAID434, AMI_BROKEN }, { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_4DI, 0 }, { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_4DI_2, 0 }, { PCI_VENDOR_DELL, PCI_PRODUCT_DELL_PERC_4EDI, 0 }, - { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80960RP_ATU, AMI_CHECK_SIGN }, + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_80960RP_ATU, + AMI_CHECK_SIGN | AMI_BROKEN }, { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_MEGARAID, 0 }, { 0 } }; @@ -117,6 +119,25 @@ struct ami_pci_vendor { { 0 } }; +int ami_pci_find_device(aux) + void *aux; +{ + int i; + struct pci_attach_args *pa = aux; + + for (i = 0; ami_pci_devices[i].vendor; i++) { + if (ami_pci_devices[i].vendor == PCI_VENDOR(pa->pa_id) && + ami_pci_devices[i].product == PCI_PRODUCT(pa->pa_id)) { +#ifdef AMI_DEBUG + printf(" ami_pci_find_device() %i ", i); +#endif /* AMI_DEBUG */ + return (i); + } + } + + return (-1); +} + int ami_pci_match(parent, match, aux) struct device *parent; @@ -124,25 +145,29 @@ ami_pci_match(parent, match, aux) void *aux; { struct pci_attach_args *pa = aux; - const struct ami_pci_device *pami; + int i; pcireg_t sig; if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O) return (0); - for (pami = ami_pci_devices; pami->vendor; pami++) { - if (pami->vendor == PCI_VENDOR(pa->pa_id) && - pami->product == PCI_PRODUCT(pa->pa_id)) { - if (!(pami->flags & AMI_CHECK_SIGN)) - return (1); - /* some cards have 0x11223344, but some only 16bit */ - sig = pci_conf_read(pa->pa_pc, pa->pa_tag, - AMI_PCI_SIG) & 0xffff; - if (sig == AMI_SIGNATURE_1 || - sig == AMI_SIGNATURE_2) - return (1); - } + if ((i = ami_pci_find_device(aux)) != -1) { +#ifdef AMI_DEBUG + printf("\nvendor: %04x product: %04x\n", + ami_pci_devices[i].vendor, + ami_pci_devices[i].product); +#endif /* AMI_DEBUG */ + + if (!(ami_pci_devices[i].flags & AMI_CHECK_SIGN)) + return (1); + /* some cards have 0x11223344, but some only 16bit */ + sig = pci_conf_read(pa->pa_pc, pa->pa_tag, + AMI_PCI_SIG) & 0xffff; + if (sig == AMI_SIGNATURE_1 || + sig == AMI_SIGNATURE_2) + return (1); } + return (0); } @@ -158,6 +183,7 @@ ami_pci_attach(parent, self, aux) const struct ami_pci_subsys *ssp; bus_size_t size; pcireg_t csr; + int i; #if 0 /* reset */ pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_EBCR, @@ -247,6 +273,17 @@ ami_pci_attach(parent, self, aux) default: lhc = "32b"; } + if ((i = ami_pci_find_device(aux)) != -1) { + if (ami_pci_devices[i].flags & AMI_BROKEN) + sc->sc_quirks = AMI_BROKEN; + else + sc->sc_quirks = 0x0000; + } + else { + /* this device existed at _match() should never happen */ + panic("ami device dissapeared between match() and attach()\n"); + } + printf(" %s/%s\n%s", model, lhc, sc->sc_dev.dv_xname); if (ami_attach(sc)) { |