diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2006-04-02 01:36:08 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2006-04-02 01:36:08 +0000 |
commit | d1c6bc7dec956aadafc485cd816fcc3b0cf5d434 (patch) | |
tree | 7a9536a00ab2877ad57f7de9413202152382de29 /sys/dev/pci/pciide.c | |
parent | 043d5f33d97c9b4e660d1179e3ab04c1164e2444 (diff) |
To be able to use the maximum number of IDE/SATA disks on an ICH
system we have to make some channels native as there isn't enough
legacy I/O space/interrupts to go around. Intel calls this
enhanced mode.
An updated and expanded version of a diff from Ulrik Holmén.
"looks sane" grange@
Diffstat (limited to 'sys/dev/pci/pciide.c')
-rw-r--r-- | sys/dev/pci/pciide.c | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c index 90ad2b0ba4d..f8c66bd03e6 100644 --- a/sys/dev/pci/pciide.c +++ b/sys/dev/pci/pciide.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pciide.c,v 1.230 2006/03/28 12:56:44 robert Exp $ */ +/* $OpenBSD: pciide.c,v 1.231 2006/04/02 01:36:07 jsg Exp $ */ /* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */ /* @@ -2159,6 +2159,7 @@ piixsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) pcireg_t interface = PCI_INTERFACE(pa->pa_class); int channel; bus_size_t cmdsize, ctlsize; + u_int8_t reg; if (pciide_chipen(sc, pa) == 0) return; @@ -2189,6 +2190,53 @@ piixsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa) WDC_CAPABILITY_MODE | WDC_CAPABILITY_SATA; sc->sc_wdcdev.set_modes = sata_setup_channel; + /* + * Put the SATA portion of controllers that don't operate in combined + * mode into native PCI modes so the maximum number of devices can be + * used. Intel calls this "enhanced mode" + */ + switch(sc->sc_pp->ide_product) { + /* ICH 5 */ + case PCI_PRODUCT_INTEL_82801EB_SATA: + case PCI_PRODUCT_INTEL_82801ER_SATA: + case PCI_PRODUCT_INTEL_6300ESB_SATA: + case PCI_PRODUCT_INTEL_6300ESB_SATA2: + reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, ICH5_SATA_MAP); + if ((reg & ICH5_SATA_MAP_COMBINED) == 0) { + reg = pciide_pci_read(pa->pa_pc, pa->pa_tag, + ICH5_SATA_PI); + reg |= ICH5_SATA_PI_PRI_NATIVE | + ICH5_SATA_PI_SEC_NATIVE; + pciide_pci_write(pa->pa_pc, pa->pa_tag, + ICH5_SATA_PI, reg); + interface |= PCIIDE_INTERFACE_PCI(0) | + PCIIDE_INTERFACE_PCI(1); + } + break; + /* ICH 6 */ + case PCI_PRODUCT_INTEL_82801FB_SATA: + case PCI_PRODUCT_INTEL_82801FR_SATA: + case PCI_PRODUCT_INTEL_82801FBM_SATA: + /* ICH 7 */ + case PCI_PRODUCT_INTEL_82801GB_SATA_1: + case PCI_PRODUCT_INTEL_82801GB_SATA_3: + case PCI_PRODUCT_INTEL_82801GBM_SATA: + reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, ICH5_SATA_MAP) & + ICH6_SATA_MAP_CMB_MASK; + if (reg != ICH6_SATA_MAP_CMB_PRI && + reg != ICH6_SATA_MAP_CMB_SEC) { + reg = pciide_pci_read(pa->pa_pc, pa->pa_tag, + ICH5_SATA_PI); + reg |= ICH5_SATA_PI_PRI_NATIVE | + ICH5_SATA_PI_SEC_NATIVE; + pciide_pci_write(pa->pa_pc, pa->pa_tag, + ICH5_SATA_PI, reg); + interface |= PCIIDE_INTERFACE_PCI(0) | + PCIIDE_INTERFACE_PCI(1); + } + break; + } + for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) { cp = &sc->pciide_channels[channel]; if (pciide_chansetup(sc, channel, interface) == 0) |