fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / ide / pci / cmd64x.c
index c04122f..aee947e 100644 (file)
@@ -14,7 +14,6 @@
  * Copyright (C) 1999-2002     Andre Hedrick <andre@linux-ide.org>
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 
 #include <asm/io.h>
 
-#include "cmd64x.h"
+#define DISPLAY_CMD64X_TIMINGS
+
+#define CMD_DEBUG 0
+
+#if CMD_DEBUG
+#define cmdprintk(x...)        printk(x)
+#else
+#define cmdprintk(x...)
+#endif
+
+/*
+ * CMD64x specific registers definition.
+ */
+#define CFR            0x50
+#define   CFR_INTR_CH0         0x02
+#define CNTRL          0x51
+#define          CNTRL_DIS_RA0         0x40
+#define   CNTRL_DIS_RA1                0x80
+#define          CNTRL_ENA_2ND         0x08
+
+#define        CMDTIM          0x52
+#define        ARTTIM0         0x53
+#define        DRWTIM0         0x54
+#define ARTTIM1        0x55
+#define DRWTIM1                0x56
+#define ARTTIM23       0x57
+#define   ARTTIM23_DIS_RA2     0x04
+#define   ARTTIM23_DIS_RA3     0x08
+#define   ARTTIM23_INTR_CH1    0x10
+#define ARTTIM2                0x57
+#define ARTTIM3                0x57
+#define DRWTIM23       0x58
+#define DRWTIM2                0x58
+#define BRST           0x59
+#define DRWTIM3                0x5b
+
+#define BMIDECR0       0x70
+#define MRDMODE                0x71
+#define   MRDMODE_INTR_CH0     0x04
+#define   MRDMODE_INTR_CH1     0x08
+#define   MRDMODE_BLK_CH0      0x10
+#define   MRDMODE_BLK_CH1      0x20
+#define BMIDESR0       0x72
+#define UDIDETCR0      0x73
+#define DTPR0          0x74
+#define BMIDECR1       0x78
+#define BMIDECSR       0x79
+#define BMIDESR1       0x7A
+#define UDIDETCR1      0x7B
+#define DTPR1          0x7C
 
 #if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -38,8 +86,6 @@ static u8 cmd64x_proc = 0;
 static struct pci_dev *cmd_devs[CMD_MAX_DEVS];
 static int n_cmd_devs;
 
-#undef DEBUG_CMD_REGS
-
 static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
 {
        char *p = buf;
@@ -49,9 +95,6 @@ static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
        u8 reg72 = 0, reg73 = 0;                        /* primary */
        u8 reg7a = 0, reg7b = 0;                        /* secondary */
        u8 reg50 = 0, reg71 = 0;                        /* extra */
-#ifdef DEBUG_CMD_REGS
-       u8 hi_byte = 0, lo_byte = 0;
-#endif /* DEBUG_CMD_REGS */
 
        p += sprintf(p, "\nController: %d\n", index);
        p += sprintf(p, "CMD%x Chipset.\n", dev->device);
@@ -127,18 +170,6 @@ static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
                (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled",
                (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled");
 
-#ifdef DEBUG_CMD_REGS
-       SPLIT_BYTE(reg50, hi_byte, lo_byte);
-       p += sprintf(p, "CFR       = 0x%02x, HI = 0x%02x, "
-                       "LOW = 0x%02x\n", reg50, hi_byte, lo_byte);
-       SPLIT_BYTE(reg57, hi_byte, lo_byte);
-       p += sprintf(p, "ARTTIM23  = 0x%02x, HI = 0x%02x, "
-                       "LOW = 0x%02x\n", reg57, hi_byte, lo_byte);
-       SPLIT_BYTE(reg71, hi_byte, lo_byte);
-       p += sprintf(p, "MRDMODE   = 0x%02x, HI = 0x%02x, "
-                       "LOW = 0x%02x\n", reg71, hi_byte, lo_byte);
-#endif /* DEBUG_CMD_REGS */
-
        return (char *)p;
 }
 
@@ -157,14 +188,6 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
 
 #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
 
-/*
- * Registers and masks for easy access by drive index:
- */
-#if 0
-static u8 prefetch_regs[4]  = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};
-static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};
-#endif
-
 /*
  * This routine writes the prepared setup/active/recovery counts
  * for a drive into the cmd646 chipset registers to active them.
@@ -458,36 +481,16 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
        struct hd_driveid *id   = drive->id;
 
        if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) {
-               /* Consult the list of known "bad" drives */
-               if (__ide_dma_bad_drive(drive))
-                       goto fast_ata_pio;
-               if ((id->field_valid & 4) && cmd64x_ratemask(drive)) {
-                       if (id->dma_ultra & hwif->ultra_mask) {
-                               /* Force if Capable UltraDMA */
-                               int dma = config_chipset_for_dma(drive);
-                               if ((id->field_valid & 2) && !dma)
-                                       goto try_dma_modes;
-                       }
-               } else if (id->field_valid & 2) {
-try_dma_modes:
-                       if ((id->dma_mword & hwif->mwdma_mask) ||
-                           (id->dma_1word & hwif->swdma_mask)) {
-                               /* Force if Capable regular DMA modes */
-                               if (!config_chipset_for_dma(drive))
-                                       goto no_dma_set;
-                       }
-               } else if (__ide_dma_good_drive(drive) &&
-                          (id->eide_dma_time < 150)) {
-                       /* Consult the list of known "good" drives */
-                       if (!config_chipset_for_dma(drive))
-                               goto no_dma_set;
-               } else {
-                       goto fast_ata_pio;
+
+               if (ide_use_dma(drive)) {
+                       if (config_chipset_for_dma(drive))
+                               return hwif->ide_dma_on(drive);
                }
-               return hwif->ide_dma_on(drive);
+
+               goto fast_ata_pio;
+
        } else if ((id->capability & 8) || (id->field_valid & 2)) {
 fast_ata_pio:
-no_dma_set:
                config_chipset_for_pio(drive, 1);
                return hwif->ide_dma_off_quietly(drive);
        }
@@ -586,7 +589,7 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
        return (dma_stat & 7) != 4;
 }
 
-static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const char *name)
 {
        u32 class_rev = 0;
        u8 mrdmode = 0;
@@ -594,13 +597,6 @@ static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char
        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
        class_rev &= 0xff;
 
-#ifdef __i386__
-       if (dev->resource[PCI_ROM_RESOURCE].start) {
-               pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
-               printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
-       }
-#endif
-
        switch(dev->device) {
                case PCI_DEVICE_ID_CMD_643:
                        break;
@@ -674,7 +670,7 @@ static unsigned int __init init_chipset_cmd64x (struct pci_dev *dev, const char
        return 0;
 }
 
-static unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
+static unsigned int __devinit ata66_cmd64x(ide_hwif_t *hwif)
 {
        u8 ata66 = 0, mask = (hwif->channel) ? 0x02 : 0x01;
 
@@ -689,7 +685,7 @@ static unsigned int __init ata66_cmd64x (ide_hwif_t *hwif)
        return (ata66 & mask) ? 1 : 0;
 }
 
-static void __init init_hwif_cmd64x (ide_hwif_t *hwif)
+static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = hwif->pci_dev;
        unsigned int class_rev;
@@ -744,13 +740,42 @@ static void __init init_hwif_cmd64x (ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
+static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
+       {       /* 0 */
+               .name           = "CMD643",
+               .init_chipset   = init_chipset_cmd64x,
+               .init_hwif      = init_hwif_cmd64x,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = ON_BOARD,
+       },{     /* 1 */
+               .name           = "CMD646",
+               .init_chipset   = init_chipset_cmd64x,
+               .init_hwif      = init_hwif_cmd64x,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .enablebits     = {{0x00,0x00,0x00}, {0x51,0x80,0x80}},
+               .bootable       = ON_BOARD,
+       },{     /* 2 */
+               .name           = "CMD648",
+               .init_chipset   = init_chipset_cmd64x,
+               .init_hwif      = init_hwif_cmd64x,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = ON_BOARD,
+       },{     /* 3 */
+               .name           = "CMD649",
+               .init_chipset   = init_chipset_cmd64x,
+               .init_hwif      = init_hwif_cmd64x,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = ON_BOARD,
+       }
+};
+
 static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       ide_pci_device_t *d = &cmd64x_chipsets[id->driver_data];
-       if (dev->device != d->device)
-               BUG();
-       ide_setup_pci_device(dev, d);
-       return 0;
+       return ide_setup_pci_device(dev, &cmd64x_chipsets[id->driver_data]);
 }
 
 static struct pci_device_id cmd64x_pci_tbl[] = {
@@ -763,12 +788,12 @@ static struct pci_device_id cmd64x_pci_tbl[] = {
 MODULE_DEVICE_TABLE(pci, cmd64x_pci_tbl);
 
 static struct pci_driver driver = {
-       .name           = "CMD64x IDE",
+       .name           = "CMD64x_IDE",
        .id_table       = cmd64x_pci_tbl,
        .probe          = cmd64x_init_one,
 };
 
-static int cmd64x_ide_init(void)
+static int __init cmd64x_ide_init(void)
 {
        return ide_pci_register_driver(&driver);
 }