summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/pciide.c50
-rw-r--r--sys/dev/pci/pciide_piix_reg.h15
2 files changed, 63 insertions, 2 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)
diff --git a/sys/dev/pci/pciide_piix_reg.h b/sys/dev/pci/pciide_piix_reg.h
index a4476fa6609..37b1438aac2 100644
--- a/sys/dev/pci/pciide_piix_reg.h
+++ b/sys/dev/pci/pciide_piix_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_piix_reg.h,v 1.9 2004/09/24 07:38:38 grange Exp $ */
+/* $OpenBSD: pciide_piix_reg.h,v 1.10 2006/04/02 01:36:07 jsg Exp $ */
/* $NetBSD: pciide_piix_reg.h,v 1.5 2001/01/05 15:29:40 bouyer Exp $ */
/*
@@ -128,6 +128,11 @@ static int8_t piix4_sct_udma[] = {0x00, 0x01, 0x02, 0x01, 0x02, 0x01};
*/
#define ICH5_SATA_MAP 0x90 /* Address Map Register */
#define ICH5_SATA_MAP_MV_MASK 0x07 /* Map Value mask */
+#define ICH5_SATA_MAP_COMBINED 0x04 /* Combined mode */
+
+#define ICH5_SATA_PI 0x09 /* Program Interface register */
+#define ICH5_SATA_PI_PRI_NATIVE 0x01 /* Put Pri IDE channel in native mode */
+#define ICH5_SATA_PI_SEC_NATIVE 0x04 /* Put Sec IDE channel in native mode */
#define ICH_SATA_PCS 0x92 /* Port Control and Status Register */
#define ICH_SATA_PCS_P0E 0x01 /* Port 0 enabled */
@@ -135,4 +140,12 @@ static int8_t piix4_sct_udma[] = {0x00, 0x01, 0x02, 0x01, 0x02, 0x01};
#define ICH_SATA_PCS_P0P 0x10 /* Port 0 present */
#define ICH_SATA_PCS_P1P 0x20 /* Port 1 present */
+/*
+ * ICH6/ICH7 SATA registers definitions
+ */
+#define ICH6_SATA_MAP_CMB_MASK 0x03 /* Combined mode bits */
+#define ICH6_SATA_MAP_CMB_PRI 0x01 /* Combined mode, IDE Primary */
+#define ICH6_SATA_MAP_CMB_SEC 0x02 /* Combined mode, IDE Secondary */
+
+
#endif /* !_DEV_PCI_PCIIDE_PIIX_REG_H_ */