fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / ide / pci / cy82c693.c
index 83bfe92..9eafcbf 100644 (file)
@@ -44,7 +44,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 
 #include <asm/io.h>
 
-#include "cy82c693.h"
+/* the current version */
+#define CY82_VERSION   "CY82C693U driver v0.34 99-13-12 Andreas S. Krebs (akrebs@altavista.net)"
+
+/*
+ *     The following are used to debug the driver.
+ */
+#define CY82C693_DEBUG_LOGS    0
+#define CY82C693_DEBUG_INFO    0
+
+/* define CY82C693_SETDMA_CLOCK to set DMA Controller Clock Speed to ATCLK */
+#undef CY82C693_SETDMA_CLOCK
+
+/*
+ *     NOTE: the value for busmaster timeout is tricky and I got it by
+ *     trial and error!  By using a to low value will cause DMA timeouts
+ *     and drop IDE performance, and by using a to high value will cause
+ *     audio playback to scatter.
+ *     If you know a better value or how to calc it, please let me know.
+ */
+
+/* twice the value written in cy82c693ub datasheet */
+#define BUSMASTER_TIMEOUT      0x50
+/*
+ * the value above was tested on my machine and it seems to work okay
+ */
+
+/* here are the offset definitions for the registers */
+#define CY82_IDE_CMDREG                0x04
+#define CY82_IDE_ADDRSETUP     0x48
+#define CY82_IDE_MASTER_IOR    0x4C
+#define CY82_IDE_MASTER_IOW    0x4D
+#define CY82_IDE_SLAVE_IOR     0x4E
+#define CY82_IDE_SLAVE_IOW     0x4F
+#define CY82_IDE_MASTER_8BIT   0x50
+#define CY82_IDE_SLAVE_8BIT    0x51
+
+#define CY82_INDEX_PORT                0x22
+#define CY82_DATA_PORT         0x23
+
+#define CY82_INDEX_CTRLREG1    0x01
+#define CY82_INDEX_CHANNEL0    0x30
+#define CY82_INDEX_CHANNEL1    0x31
+#define CY82_INDEX_TIMEOUT     0x32
+
+/* the max PIO mode - from datasheet */
+#define CY82C693_MAX_PIO       4
+
+/* the min and max PCI bus speed in MHz - from datasheet */
+#define CY82C963_MIN_BUS_SPEED 25
+#define CY82C963_MAX_BUS_SPEED 33
+
+/* the struct for the PIO mode timings */
+typedef struct pio_clocks_s {
+       u8      address_time;   /* Address setup (clocks) */
+       u8      time_16r;       /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
+       u8      time_16w;       /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
+       u8      time_8;         /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
+} pio_clocks_t;
 
 /*
  * calc clocks using bus_speed
@@ -183,7 +239,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
 /* 
  * used to set DMA mode for CY82C693 (single and multi modes)
  */
-int cy82c693_ide_dma_on (ide_drive_t *drive)
+static int cy82c693_ide_dma_on (ide_drive_t *drive)
 {
        struct hd_driveid *id = drive->id;
 
@@ -225,7 +281,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
 
        /* select primary or secondary channel */
        if (hwif->index > 0) {  /* drive is on the secondary channel */
-               dev = pci_find_slot(dev->bus->number, dev->devfn+1);
+               dev = pci_get_slot(dev->bus, dev->devfn+1);
                if (!dev) {
                        printk(KERN_ERR "%s: tune_drive: "
                                "Cannot find secondary interface!\n",
@@ -334,7 +390,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
 /*
  * this function is called during init and is used to setup the cy82c693 chip
  */
-static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name)
+static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name)
 {
        if (PCI_FUNC(dev->devfn) != 1)
                return 0;
@@ -386,7 +442,7 @@ static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char
 /*
  * the init function - called for each ide channel once
  */
-static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
+static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
 {
        hwif->autodma = 0;
 
@@ -410,9 +466,9 @@ static void __init init_hwif_cy82c693(ide_hwif_t *hwif)
        hwif->drives[1].autodma = hwif->autodma;
 }
 
-static __initdata ide_hwif_t *primary;
+static __devinitdata ide_hwif_t *primary;
 
-void __init init_iops_cy82c693(ide_hwif_t *hwif)
+static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
 {
        if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
                primary = hwif;
@@ -422,19 +478,33 @@ void __init init_iops_cy82c693(ide_hwif_t *hwif)
        }
 }
 
+static ide_pci_device_t cy82c693_chipsets[] __devinitdata = {
+       {       /* 0 */
+               .name           = "CY82C693",
+               .init_chipset   = init_chipset_cy82c693,
+               .init_iops      = init_iops_cy82c693,
+               .init_hwif      = init_hwif_cy82c693,
+               .channels       = 1,
+               .autodma        = AUTODMA,
+               .bootable       = ON_BOARD,
+       }
+};
+
 static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
        struct pci_dev *dev2;
+       int ret = -ENODEV;
 
        /* CY82C693 is more than only a IDE controller.
           Function 1 is primary IDE channel, function 2 - secondary. */
         if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
            PCI_FUNC(dev->devfn) == 1) {
-               dev2 = pci_find_slot(dev->bus->number, dev->devfn + 1);
-               ide_setup_pci_devices(dev, dev2, d);
+               dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
+               ret = ide_setup_pci_devices(dev, dev2, d);
+               /* We leak pci refs here but thats ok - we can't be unloaded */
        }
-       return 0;
+       return ret;
 }
 
 static struct pci_device_id cy82c693_pci_tbl[] = {
@@ -449,7 +519,7 @@ static struct pci_driver driver = {
        .probe          = cy82c693_init_one,
 };
 
-static int cy82c693_ide_init(void)
+static int __init cy82c693_ide_init(void)
 {
        return ide_pci_register_driver(&driver);
 }