summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-12-22 19:48:06 +0000
committermav <mav@FreeBSD.org>2009-12-22 19:48:06 +0000
commit4822b84df379c1e8a850868c8bfdb42e70249f76 (patch)
tree4013041d66ebacfa9018b3b12787864294dbe19d
parent804c7f3ed4a20417ea23315595ea4e9bb3ebe99e (diff)
downloadFreeBSD-src-4822b84df379c1e8a850868c8bfdb42e70249f76.zip
FreeBSD-src-4822b84df379c1e8a850868c8bfdb42e70249f76.tar.gz
Add support for Intel SCH PATA controller.
PR: kern/140251
-rw-r--r--sys/dev/ata/ata-pci.h1
-rw-r--r--sys/dev/ata/chipsets/ata-intel.c41
2 files changed, 40 insertions, 2 deletions
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index 25e0588..6f696a6 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -204,6 +204,7 @@ struct ata_pci_controller {
#define ATA_I82801JI_R1 0x3a258086
#define ATA_I82801JI_S2 0x3a268086
#define ATA_I31244 0x32008086
+#define ATA_ISCH 0x811a8086
#define ATA_ITE_ID 0x1283
#define ATA_IT8211F 0x82111283
diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index 95e40c1..ec05f30 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -57,6 +57,7 @@ static int ata_intel_ch_attach(device_t dev);
static void ata_intel_reset(device_t dev);
static int ata_intel_old_setmode(device_t dev, int target, int mode);
static int ata_intel_new_setmode(device_t dev, int target, int mode);
+static int ata_intel_sch_setmode(device_t dev, int target, int mode);
static int ata_intel_sata_getrev(device_t dev, int target);
static int ata_intel_31244_ch_attach(device_t dev);
static int ata_intel_31244_ch_detach(device_t dev);
@@ -140,6 +141,7 @@ ata_intel_probe(device_t dev)
{ ATA_I82801JI_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JI_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
{ ATA_I31244, 0, 0, 2, ATA_SA150, "31244" },
+ { ATA_ISCH, 0, 0, 1, ATA_UDMA5, "SCH" },
{ 0, 0, 0, 0, 0, 0}};
if (pci_get_vendor(dev) != ATA_INTEL_ID)
@@ -183,7 +185,13 @@ ata_intel_chipinit(device_t dev)
ctlr->setmode = ata_sata_setmode;
ctlr->getrev = ata_sata_getrev;
}
-
+ /* SCH */
+ else if (ctlr->chip->chipid == ATA_ISCH) {
+ ctlr->channels = 1;
+ ctlr->ch_attach = ata_intel_ch_attach;
+ ctlr->ch_detach = ata_pci_ch_detach;
+ ctlr->setmode = ata_intel_sch_setmode;
+ }
/* non SATA intel chips goes here */
else if (ctlr->chip->max_dma < ATA_SA150) {
ctlr->channels = ctlr->chip->cfg2;
@@ -245,7 +253,7 @@ ata_intel_ch_attach(device_t dev)
(pci_read_config(device_get_parent(dev), 0x90, 1) & 0x04) == 0)
ch->flags |= ATA_NO_SLAVE;
ch->flags |= ATA_SATA;
- } else
+ } else if (ctlr->chip->chipid != ATA_ISCH)
ch->flags |= ATA_CHECKS_CABLE;
return 0;
}
@@ -360,6 +368,35 @@ ata_intel_new_setmode(device_t dev, int target, int mode)
}
static int
+ata_intel_sch_setmode(device_t dev, int target, int mode)
+{
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ u_int8_t dtim = 0x80 + (target << 2);
+ u_int32_t tim = pci_read_config(parent, dtim, 4);
+ int piomode;
+
+ mode = min(mode, ctlr->chip->max_dma);
+ if (mode >= ATA_UDMA0) {
+ tim |= (0x1 << 31);
+ tim &= ~(0x7 << 16);
+ tim |= ((mode & ATA_MODE_MASK) << 16);
+ piomode = ATA_PIO4;
+ } else if (mode >= ATA_WDMA0) {
+ tim &= ~(0x1 << 31);
+ tim &= ~(0x3 << 8);
+ tim |= ((mode & ATA_MODE_MASK) << 8);
+ piomode = (mode == ATA_WDMA0) ? ATA_PIO0 :
+ (mode == ATA_WDMA1) ? ATA_PIO3 : ATA_PIO4;
+ } else
+ piomode = mode;
+ tim &= ~(0x7);
+ tim |= (piomode & 0x7);
+ pci_write_config(parent, dtim, tim, 4);
+ return (mode);
+}
+
+static int
ata_intel_sata_getrev(device_t dev, int target)
{
struct ata_channel *ch = device_get_softc(dev);
OpenPOWER on IntegriCloud