summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-12-08 11:17:38 +0000
committersos <sos@FreeBSD.org>2004-12-08 11:17:38 +0000
commit0138ea081fa27f66eec707a0fd8d308f6d34298e (patch)
treec44e23d84d7b1319967bc6f5c136ad8f95072b4c /sys/dev/ata
parentdb3855bde986efb23c3361ac7bfb0f35eeb0780f (diff)
downloadFreeBSD-src-0138ea081fa27f66eec707a0fd8d308f6d34298e.zip
FreeBSD-src-0138ea081fa27f66eec707a0fd8d308f6d34298e.tar.gz
Add support for the ITE IT8212F controller.
HW donated by: Yahoo!
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-chipset.c96
-rw-r--r--sys/dev/ata/ata-pci.c15
-rw-r--r--sys/dev/ata/ata-pci.h11
3 files changed, 117 insertions, 5 deletions
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c
index 6cc76b7..4d8446b 100644
--- a/sys/dev/ata/ata-chipset.c
+++ b/sys/dev/ata/ata-chipset.c
@@ -83,6 +83,8 @@ static void ata_intel_intr(void *);
static void ata_intel_reset(struct ata_channel *);
static void ata_intel_old_setmode(struct ata_device *, int);
static void ata_intel_new_setmode(struct ata_device *, int);
+static int ata_ite_chipinit(device_t);
+static void ata_ite_setmode(struct ata_device *, int);
static int ata_national_chipinit(device_t);
static void ata_national_setmode(struct ata_device *, int);
static int ata_nvidia_chipinit(device_t);
@@ -1015,6 +1017,100 @@ ata_intel_new_setmode(struct ata_device *atadev, int mode)
}
/*
+ * Integrated Technology Express Inc. (ITE) chipset support functions
+ */
+int
+ata_ite_ident(device_t dev)
+{
+ struct ata_pci_controller *ctlr = device_get_softc(dev);
+
+ if (pci_get_devid(dev) == ATA_IT8212F) {
+ device_set_desc(dev, "ITE IT8212F ATA133 controller");
+ ctlr->chipinit = ata_ite_chipinit;
+ return 0;
+ }
+ return ENXIO;
+}
+
+static int
+ata_ite_chipinit(device_t dev)
+{
+ struct ata_pci_controller *ctlr = device_get_softc(dev);
+
+ if (ata_setup_interrupt(dev))
+ return ENXIO;
+
+ ctlr->setmode = ata_ite_setmode;
+
+ /* set PCI mode and 66Mhz reference clock */
+ pci_write_config(dev, 0x50, pci_read_config(dev, 0x50, 1) & ~0x83, 1);
+
+ /* set default active & recover timings */
+ pci_write_config(dev, 0x54, 0x31, 1);
+ pci_write_config(dev, 0x56, 0x31, 1);
+ return 0;
+}
+
+static void
+ata_ite_setmode(struct ata_device *atadev, int mode)
+{
+ device_t parent = device_get_parent(atadev->channel->dev);
+ struct ata_channel *ch = atadev->channel;
+ int devno = (ch->unit << 1) + ATA_DEV(atadev->unit);
+ int error;
+
+ /* correct the mode for what the HW supports */
+ mode = ata_limit_mode(atadev, mode, ATA_UDMA6);
+
+ /* check the CBLID bits for 80 conductor cable detection */
+ if (mode > ATA_UDMA2 && (pci_read_config(parent, 0x40, 2) &
+ (ch->unit ? (1<<3) : (1<<2)))) {
+ ata_prtdev(atadev,"DMA limited to UDMA33, non-ATA66 cable or device\n");
+ mode = ATA_UDMA2;
+ }
+
+ /* set the wanted mode on the device */
+ error = ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
+
+ if (bootverbose)
+ ata_prtdev(atadev, "%s setting %s on ITE8212F chip\n",
+ (error) ? "failed" : "success", ata_mode2str(mode));
+
+ /* if the device accepted the mode change, setup the HW accordingly */
+ if (!error) {
+ if (mode >= ATA_UDMA0) {
+ u_int8_t udmatiming[] =
+ { 0x44, 0x42, 0x31, 0x21, 0x11, 0xa2, 0x91 };
+
+ /* enable UDMA mode */
+ pci_write_config(parent, 0x50,
+ pci_read_config(parent, 0x50, 1) &
+ ~(1 << (devno + 3)), 1);
+
+ /* set UDMA timing */
+ pci_write_config(parent,
+ 0x56 + (ch->unit << 2) + ATA_DEV(atadev->unit),
+ udmatiming[mode & ATA_MODE_MASK], 1);
+ }
+ else {
+ u_int8_t chtiming[] =
+ { 0xaa, 0xa3, 0xa1, 0x33, 0x31, 0x88, 0x32, 0x31 };
+
+ /* disable UDMA mode */
+ pci_write_config(parent, 0x50,
+ pci_read_config(parent, 0x50, 1) |
+ (1 << (devno + 3)), 1);
+
+ /* set active and recover timing (shared between master & slave) */
+ if (pci_read_config(parent, 0x54 + (ch->unit << 2), 1) <
+ chtiming[ata_mode2idx(mode)])
+ pci_write_config(parent, 0x54 + (ch->unit << 2),
+ chtiming[ata_mode2idx(mode)], 1);
+ }
+ atadev->mode = mode;
+ }
+}
+/*
* National chipset support functions
*/
int
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index b5d7388..747ba41 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -106,6 +106,10 @@ ata_pci_probe(device_t dev)
if (!ata_intel_ident(dev))
return 0;
break;
+ case ATA_ITE_ID:
+ if (!ata_ite_ident(dev))
+ return 0;
+ break;
case ATA_NATIONAL_ID:
if (!ata_national_ident(dev))
return 0;
@@ -134,18 +138,19 @@ ata_pci_probe(device_t dev)
if (!ata_via_ident(dev))
return 0;
break;
- case 0x16ca:
- if (pci_get_devid(dev) == 0x000116ca) {
+ case ATA_CENATEK_ID:
+ if (pci_get_devid(dev) == ATA_CENATEK_ROCKET) {
ata_generic_ident(dev);
device_set_desc(dev, "Cenatek Rocket Drive controller");
return 0;
}
break;
- case 0x1042:
- if (pci_get_devid(dev)==0x10001042 || pci_get_devid(dev)==0x10011042) {
+ case ATA_MICRON_ID:
+ if (pci_get_devid(dev) == ATA_MICRON_RZ1000 ||
+ pci_get_devid(dev) == ATA_MICRON_RZ1001) {
ata_generic_ident(dev);
device_set_desc(dev,
- "RZ 100? ATA controller !WARNING! buggy HW data loss possible");
+ "RZ 100? ATA controller !WARNING! data loss/corruption risk");
return 0;
}
break;
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index e054bcb..5189e70 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -83,6 +83,9 @@ struct ata_pci_controller {
#define ATA_ACER_LABS_ID 0x10b9
#define ATA_ALI_5229 0x522910b9
+#define ATA_CENATEK_ID 0x16ca
+#define ATA_CENATEK_ROCKET 0x000116ca
+
#define ATA_CYRIX_ID 0x1078
#define ATA_CYRIX_5530 0x01021078
@@ -125,6 +128,13 @@ struct ata_pci_controller {
#define ATA_I82801FB_S1 0x26518086
#define ATA_I82801FB_R1 0x26528086
+#define ATA_ITE_ID 0x1283
+#define ATA_IT8212F 0x82121283
+
+#define ATA_MICRON_ID 0x1042
+#define ATA_MICRON_RZ1000 0x10001042
+#define ATA_MICRON_RZ1001 0x10011042
+
#define ATA_NATIONAL_ID 0x100b
#define ATA_SC1100 0x0502100b
@@ -328,6 +338,7 @@ int ata_cyrix_ident(device_t);
int ata_cypress_ident(device_t);
int ata_highpoint_ident(device_t);
int ata_intel_ident(device_t);
+int ata_ite_ident(device_t);
int ata_national_ident(device_t);
int ata_nvidia_ident(device_t);
int ata_promise_ident(device_t);
OpenPOWER on IntegriCloud