vserver 1.9.5.x5
[linux-2.6.git] / drivers / ide / pci / pdc202xx_new.c
index 8f63592..211641a 100644 (file)
 #include <asm/pci-bridge.h>
 #endif
 
-#include "pdc202xx_new.h"
-
 #define PDC202_DEBUG_CABLE     0
 
-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 pdcnew_proc = 0;
-#define PDC202_MAX_DEVS                5
-static struct pci_dev *pdc202_devs[PDC202_MAX_DEVS];
-static int n_pdc202_devs;
-
-static char * pdcnew_info(char *buf, struct pci_dev *dev)
-{
-       char *p = buf;
-
-       p += sprintf(p, "\n                                ");
-       switch(dev->device) {
-               case PCI_DEVICE_ID_PROMISE_20277:
-                       p += sprintf(p, "SBFastTrak 133 Lite"); break;
-               case PCI_DEVICE_ID_PROMISE_20276:
-                       p += sprintf(p, "MBFastTrak 133 Lite"); break;
-               case PCI_DEVICE_ID_PROMISE_20275:
-                       p += sprintf(p, "MBUltra133"); break;
-               case PCI_DEVICE_ID_PROMISE_20271:
-                       p += sprintf(p, "FastTrak TX2000"); break;
-               case PCI_DEVICE_ID_PROMISE_20270:
-                       p += sprintf(p, "FastTrak LP/TX2/TX4"); break;
-               case PCI_DEVICE_ID_PROMISE_20269:
-                       p += sprintf(p, "Ultra133 TX2"); break;
-               case PCI_DEVICE_ID_PROMISE_20268:
-                       p += sprintf(p, "Ultra100 TX2"); break;
-               default:
-                       p += sprintf(p, "Ultra series"); break;
-                       break;
-       }
-       p += sprintf(p, " Chipset.\n");
-       return (char *)p;
-}
-
-static int pdcnew_get_info (char *buffer, char **addr, off_t offset, int count)
-{
-       char *p = buffer;
-       int i, len;
-
-       for (i = 0; i < n_pdc202_devs; i++) {
-               struct pci_dev *dev     = pdc202_devs[i];
-               p = pdcnew_info(buffer, dev);
-       }
-       /* p - buffer must be less than 4k! */
-       len = (p - buffer) - offset;
-       *addr = buffer + offset;
-       
-       return len > count ? count : len;
-}
-#endif  /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
+const static char *pdc_quirk_drives[] = {
+       "QUANTUM FIREBALLlct08 08",
+       "QUANTUM FIREBALLP KA6.4",
+       "QUANTUM FIREBALLP KA9.1",
+       "QUANTUM FIREBALLP LM20.4",
+       "QUANTUM FIREBALLP KX13.6",
+       "QUANTUM FIREBALLP KX20.5",
+       "QUANTUM FIREBALLP KX27.3",
+       "QUANTUM FIREBALLP LM20.5",
+       NULL
+};
 
+#define set_2regs(a, b)                                        \
+       do {                                            \
+               hwif->OUTB((a + adj), indexreg);        \
+               hwif->OUTB(b, datareg);                 \
+       } while(0)
+
+#define set_ultra(a, b, c)                             \
+       do {                                            \
+               set_2regs(0x10,(a));                    \
+               set_2regs(0x11,(b));                    \
+               set_2regs(0x12,(c));                    \
+       } while(0)
+
+#define set_ata2(a, b)                                 \
+       do {                                            \
+               set_2regs(0x0e,(a));                    \
+               set_2regs(0x0f,(b));                    \
+       } while(0)
+
+#define set_pio(a, b, c)                               \
+       do {                                            \
+               set_2regs(0x0c,(a));                    \
+               set_2regs(0x0d,(b));                    \
+               set_2regs(0x13,(c));                    \
+       } while(0)
 
 static u8 pdcnew_ratemask (ide_drive_t *drive)
 {
@@ -244,37 +225,16 @@ static int pdcnew_config_drive_xfer_rate (ide_drive_t *drive)
        drive->init_speed = 0;
 
        if (id && (id->capability & 1) && drive->autodma) {
-               /* Consult the list of known "bad" drives */
-               if (__ide_dma_bad_drive(drive))
-                       goto fast_ata_pio;
-               if (id->field_valid & 4) {
-                       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)) {
-                               goto no_dma_set;
-                       /* 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:
                hwif->tuneproc(drive, 5);
                return hwif->ide_dma_off_quietly(drive);
        }
@@ -310,68 +270,12 @@ static void pdcnew_new_reset (ide_drive_t *drive)
                HWIF(drive)->channel ? "Secondary" : "Primary");
 }
 
-static void pdcnew_reset_host (ide_hwif_t *hwif)
-{
-//     unsigned long high_16   = hwif->dma_base - (8*(hwif->channel));
-       unsigned long high_16   = hwif->dma_master;
-       u8 udma_speed_flag      = hwif->INB(high_16|0x001f);
-
-       hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f));
-       mdelay(100);
-       hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f));
-       mdelay(2000);   /* 2 seconds ?! */
-
-       printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
-               hwif->channel ? "Secondary" : "Primary");
-}
-
-void pdcnew_reset (ide_drive_t *drive)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       ide_hwif_t *mate        = hwif->mate;
-       
-       pdcnew_reset_host(hwif);
-       pdcnew_reset_host(mate);
-#if 0
-       /*
-        * FIXME: Have to kick all the drives again :-/
-        * What a pain in the ACE!
-        */
-       if (hwif->present) {
-               u16 hunit = 0;
-               for (hunit = 0; hunit < MAX_DRIVES; ++hunit) {
-                       ide_drive_t *hdrive = &hwif->drives[hunit];
-                       if (hdrive->present) {
-                               if (hwif->ide_dma_check)
-                                       hwif->ide_dma_check(hdrive);
-                               else
-                                       hwif->tuneproc(hdrive, 5);
-                       }
-               }
-       }
-       if (mate->present) {
-               u16 munit = 0;
-               for (munit = 0; munit < MAX_DRIVES; ++munit) {
-                       ide_drive_t *mdrive = &mate->drives[munit];
-                       if (mdrive->present) {
-                               if (mate->ide_dma_check) 
-                                       mate->ide_dma_check(mdrive);
-                               else
-                                       mate->tuneproc(mdrive, 5);
-                       }
-               }
-       }
-#else
-       hwif->tuneproc(drive, 5);
-#endif
-}
-
 #ifdef CONFIG_PPC_PMAC
 static void __devinit apple_kiwi_init(struct pci_dev *pdev)
 {
        struct device_node *np = pci_device_to_OF_node(pdev);
        unsigned int class_rev = 0;
-       unsigned long mmio;
+       void __iomem *mmio;
        u8 conf;
 
        if (np == NULL || !device_is_compatible(np, "kiwi-root"))
@@ -385,7 +289,7 @@ static void __devinit apple_kiwi_init(struct pci_dev *pdev)
                pci_read_config_byte(pdev, 0x40, &conf);
                pci_write_config_byte(pdev, 0x40, conf | 0x01);
        }
-       mmio = (unsigned long)ioremap(pci_resource_start(pdev, 5),
+       mmio = ioremap(pci_resource_start(pdev, 5),
                                      pci_resource_len(pdev, 5));
 
        /* Setup some PLL stuffs */
@@ -400,7 +304,7 @@ static void __devinit apple_kiwi_init(struct pci_dev *pdev)
                break;
        }
 
-       iounmap((void *)mmio);
+       iounmap(mmio);
 }
 #endif /* CONFIG_PPC_PMAC */
 
@@ -417,15 +321,6 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
        apple_kiwi_init(dev);
 #endif
 
-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
-       pdc202_devs[n_pdc202_devs++] = dev;
-
-       if (!pdcnew_proc) {
-               pdcnew_proc = 1;
-               ide_pci_create_host_proc("pdcnew", pdcnew_get_info);
-       }
-#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
-
        return dev->irq;
 }
 
@@ -457,21 +352,21 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
 #endif /* PDC202_DEBUG_CABLE */
 }
 
-static void __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
 {
-       ide_setup_pci_device(dev, d);
+       return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc20270(struct pci_dev *dev,
+                                        ide_pci_device_t *d)
 {
        struct pci_dev *findev = NULL;
 
        if ((dev->bus->self &&
             dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
            (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) {
-               if (PCI_SLOT(dev->devfn) & 2) {
-                       return;
-               }
+               if (PCI_SLOT(dev->devfn) & 2)
+                       return -ENODEV;
                d->extra = 0;
                while ((findev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
                        if ((findev->vendor == dev->vendor) &&
@@ -480,15 +375,15 @@ static void __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t
                                if (findev->irq != dev->irq) {
                                        findev->irq = dev->irq;
                                }
-                               ide_setup_pci_devices(dev, findev, d);
-                               return;
+                               return ide_setup_pci_devices(dev, findev, d);
                        }
                }
        }
-       ide_setup_pci_device(dev, d);
+       return ide_setup_pci_device(dev, d);
 }
 
-static void __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_pdc20276(struct pci_dev *dev,
+                                        ide_pci_device_t *d)
 {
        if ((dev->bus->self) &&
            (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
@@ -496,11 +391,77 @@ static void __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t
             (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
                printk(KERN_INFO "ide: Skipping Promise PDC20276 "
                        "attached to I2O RAID controller.\n");
-               return;
+               return -ENODEV;
        }
-       ide_setup_pci_device(dev, d);
+       return ide_setup_pci_device(dev, d);
 }
 
+static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
+       {       /* 0 */
+               .name           = "PDC20268",
+               .init_setup     = init_setup_pdcnew,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = OFF_BOARD,
+       },{     /* 1 */
+               .name           = "PDC20269",
+               .init_setup     = init_setup_pdcnew,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = OFF_BOARD,
+       },{     /* 2 */
+               .name           = "PDC20270",
+               .init_setup     = init_setup_pdc20270,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+               .bootable       = OFF_BOARD,
+       },{     /* 3 */
+               .name           = "PDC20271",
+               .init_setup     = init_setup_pdcnew,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = OFF_BOARD,
+       },{     /* 4 */
+               .name           = "PDC20275",
+               .init_setup     = init_setup_pdcnew,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = OFF_BOARD,
+       },{     /* 5 */
+               .name           = "PDC20276",
+               .init_setup     = init_setup_pdc20276,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+#ifndef CONFIG_PDC202XX_FORCE
+               .enablebits     = {{0x50,0x02,0x02}, {0x50,0x04,0x04}},
+#endif
+               .bootable       = OFF_BOARD,
+       },{     /* 6 */
+               .name           = "PDC20277",
+               .init_setup     = init_setup_pdcnew,
+               .init_chipset   = init_chipset_pdcnew,
+               .init_hwif      = init_hwif_pdc202new,
+               .channels       = 2,
+               .autodma        = AUTODMA,
+               .bootable       = OFF_BOARD,
+       }
+};
+
 /**
  *     pdc202new_init_one      -       called when a pdc202xx is found
  *     @dev: the pdc202new device
@@ -514,8 +475,7 @@ static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_de
 {
        ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data];
 
-       d->init_setup(dev, d);
-       return 0;
+       return d->init_setup(dev, d);
 }
 
 static struct pci_device_id pdc202new_pci_tbl[] = {