alim15x3: fix handling of command timings
[safe/jmp/linux-2.6] / drivers / ide / qd65xx.c
index bc27c7a..3f0244f 100644 (file)
@@ -16,7 +16,7 @@
 
 /*
  * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
+ * Samuel Thibault <samuel.thibault@ens-lyon.org>
  */
 
 #include <linux/module.h>
@@ -90,13 +90,15 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
  * This routine is invoked to prepare for access to a given drive.
  */
 
-static void qd65xx_select(ide_drive_t *drive)
+static void qd65xx_dev_select(ide_drive_t *drive)
 {
        u8 index = ((   (QD_TIMREG(drive)) & 0x80 ) >> 7) |
                        (QD_TIMREG(drive) & 0x02);
 
        if (timings[index] != QD_TIMING(drive))
                outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+
+       outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
 }
 
 /*
@@ -178,21 +180,22 @@ static int qd_find_disk_type (ide_drive_t *drive,
 
 static void qd_set_timing (ide_drive_t *drive, u8 timing)
 {
-       drive->drive_data &= 0xff00;
-       drive->drive_data |= timing;
+       unsigned long data = (unsigned long)ide_get_drivedata(drive);
+
+       data &= 0xff00;
+       data |= timing;
+       ide_set_drivedata(drive, (void *)data);
 
        printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
 }
 
-static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void qd6500_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
        u16 *id = drive->id;
        int active_time   = 175;
        int recovery_time = 415; /* worst case values from the dos driver */
 
-       /*
-        * FIXME: use "pio" value
-        */
+       /* FIXME: use drive->pio_mode value */
        if (!qd_find_disk_type(drive, &active_time, &recovery_time) &&
            (id[ATA_ID_OLD_PIO_MODES] & 0xff) && (id[ATA_ID_FIELD_VALID] & 2) &&
            id[ATA_ID_EIDE_PIO] >= 240) {
@@ -202,12 +205,13 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
                recovery_time = drive->id[ATA_ID_EIDE_PIO] - 120;
        }
 
-       qd_set_timing(drive, qd6500_compute_timing(HWIF(drive), active_time, recovery_time));
+       qd_set_timing(drive, qd6500_compute_timing(drive->hwif,
+                               active_time, recovery_time));
 }
 
-static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void qd6580_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
 {
-       ide_hwif_t *hwif = drive->hwif;
+       const u8 pio = drive->pio_mode - XFER_PIO_0;
        struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
        unsigned int cycle_time;
        int active_time   = 175;
@@ -245,11 +249,11 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
                printk(KERN_INFO "%s: PIO mode%d\n", drive->name,pio);
        }
 
-       if (!HWIF(drive)->channel && drive->media != ide_disk) {
+       if (!hwif->channel && drive->media != ide_disk) {
                outb(0x5f, QD_CONTROL_PORT);
                printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO "
                        "and post-write buffer on %s.\n",
-                       drive->name, HWIF(drive)->name);
+                       drive->name, hwif->name);
        }
 
        qd_set_timing(drive, qd6580_compute_timing(active_time, recovery_time));
@@ -289,7 +293,7 @@ static void __init qd6500_init_dev(ide_drive_t *drive)
        u8 base = (hwif->config_data & 0xff00) >> 8;
        u8 config = QD_CONFIG(hwif);
 
-       drive->drive_data = QD6500_DEF_DATA;
+       ide_set_drivedata(drive, (void *)QD6500_DEF_DATA);
 }
 
 static void __init qd6580_init_dev(ide_drive_t *drive)
@@ -305,23 +309,36 @@ static void __init qd6580_init_dev(ide_drive_t *drive)
        } else
                t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;
 
-       drive->drive_data = (drive->dn & 1) ? t2 : t1;
+       ide_set_drivedata(drive, (void *)((drive->dn & 1) ? t2 : t1));
 }
 
+static const struct ide_tp_ops qd65xx_tp_ops = {
+       .exec_command           = ide_exec_command,
+       .read_status            = ide_read_status,
+       .read_altstatus         = ide_read_altstatus,
+       .write_devctl           = ide_write_devctl,
+
+       .dev_select             = qd65xx_dev_select,
+       .tf_load                = ide_tf_load,
+       .tf_read                = ide_tf_read,
+
+       .input_data             = ide_input_data,
+       .output_data            = ide_output_data,
+};
+
 static const struct ide_port_ops qd6500_port_ops = {
        .init_dev               = qd6500_init_dev,
        .set_pio_mode           = qd6500_set_pio_mode,
-       .selectproc             = qd65xx_select,
 };
 
 static const struct ide_port_ops qd6580_port_ops = {
        .init_dev               = qd6580_init_dev,
        .set_pio_mode           = qd6580_set_pio_mode,
-       .selectproc             = qd65xx_select,
 };
 
 static const struct ide_port_info qd65xx_port_info __initdata = {
        .name                   = DRV_NAME,
+       .tp_ops                 = &qd65xx_tp_ops,
        .chipset                = ide_qd65xx,
        .host_flags             = IDE_HFLAG_IO_32BIT |
                                  IDE_HFLAG_NO_DMA,