diff options
author | mav <mav@FreeBSD.org> | 2009-12-22 19:48:06 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2009-12-22 19:48:06 +0000 |
commit | 4822b84df379c1e8a850868c8bfdb42e70249f76 (patch) | |
tree | 4013041d66ebacfa9018b3b12787864294dbe19d /sys/dev | |
parent | 804c7f3ed4a20417ea23315595ea4e9bb3ebe99e (diff) | |
download | FreeBSD-src-4822b84df379c1e8a850868c8bfdb42e70249f76.zip FreeBSD-src-4822b84df379c1e8a850868c8bfdb42e70249f76.tar.gz |
Add support for Intel SCH PATA controller.
PR: kern/140251
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ata/ata-pci.h | 1 | ||||
-rw-r--r-- | sys/dev/ata/chipsets/ata-intel.c | 41 |
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); |