ide: add IDE_HFLAG_NO_{DMA,AUTODMA} host flags
[safe/jmp/linux-2.6] / drivers / ide / pci / cs5535.c
index 66a101e..8d8a9f8 100644 (file)
@@ -2,6 +2,7 @@
  * linux/drivers/ide/pci/cs5535.c
  *
  * Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
+ * Copyright (C)      2007 Bartlomiej Zolnierkiewicz
  *
  * History:
  * 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
@@ -74,7 +75,7 @@ static unsigned int cs5535_udma_timings[5] =
  *
  *     cs5535_set_speed() configures the chipset to a new speed.
  */
-static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
+static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
 {
 
        u32 reg = 0, dummy;
@@ -83,14 +84,17 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
 
        /* Set the PIO timings */
        if ((speed & XFER_MODE) == XFER_PIO) {
-               u8 pioa;
-               u8 piob;
-               u8 cmd;
+               ide_drive_t *pair = ide_get_paired_drive(drive);
+               u8 cmd, pioa;
 
-               pioa = speed - XFER_PIO_0;
-               piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
-                                               255, 4, NULL);
-               cmd = pioa < piob ? pioa : piob;
+               cmd = pioa = speed - XFER_PIO_0;
+
+               if (pair->present) {
+                       u8 piob = ide_get_best_pio_mode(pair, 255, 4);
+
+                       if (piob < cmd)
+                               cmd = piob;
+               }
 
                /* Write the speed of the current drive */
                reg = (cs5535_pio_cmd_timings[cmd] << 16) |
@@ -116,7 +120,7 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
 
                reg &= 0x80000000UL;  /* Preserve the PIO format bit */
 
-               if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
+               if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_4)
                        reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
                else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
                        reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
@@ -127,71 +131,30 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
        }
 }
 
-/****
- *     cs5535_set_drive         -     Configure the drive to the new speed
- *     @drive: Drive to set up
- *     @speed: desired speed
+/**
+ *     cs5535_set_dma_mode     -       set host controller for DMA mode
+ *     @drive: drive
+ *     @speed: DMA mode
  *
- *     cs5535_set_drive() configures the drive and the chipset to a
- *     new speed. It also can be called by upper layers.
+ *     Programs the chipset for DMA mode.
  */
-static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
+
+static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
-       speed = ide_rate_filter(drive, speed);
-       ide_config_drive_speed(drive, speed);
        cs5535_set_speed(drive, speed);
-
-       return 0;
 }
 
-/****
- *     cs5535_tuneproc    -       PIO setup
- *     @drive: drive to set up
- *     @pio: mode to use (255 for 'best possible')
+/**
+ *     cs5535_set_pio_mode     -       set host controller for PIO mode
+ *     @drive: drive
+ *     @pio: PIO mode number
  *
  *     A callback from the upper layers for PIO-only tuning.
  */
-static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
-{
-       u8 modes[] = {  XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
-                       XFER_PIO_4 };
-
-       /* cs5535 max pio is pio 4, best_pio will check the blacklist.
-       i think we don't need to rate_filter the incoming xferspeed
-       since we know we're only going to choose pio */
-       xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
-       ide_config_drive_speed(drive, modes[xferspeed]);
-       cs5535_set_speed(drive, xferspeed);
-}
-
-static int cs5535_config_drive_for_dma(ide_drive_t *drive)
-{
-       u8 speed = ide_max_dma_mode(drive);
-
-       /* If no DMA speed was available then let dma_check hit pio */
-       if (!speed) {
-               return 0;
-       }
-
-       cs5535_set_drive(drive, speed);
-       return ide_dma_enable(drive);
-}
 
-static int cs5535_dma_check(ide_drive_t *drive)
+static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       u8 speed;
-
-       drive->init_speed = 0;
-
-       if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
-               return 0;
-
-       if (ide_use_fast_pio(drive)) {
-               speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
-               cs5535_set_drive(drive, speed);
-       }
-
-       return -1;
+       cs5535_set_speed(drive, XFER_PIO_0 + pio);
 }
 
 static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
@@ -200,7 +163,8 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
 
        /* if a 80 wire cable was detected */
        pci_read_config_byte(dev, CS5535_CABLE_DETECT, &bit);
-       return (bit & 1);
+
+       return (bit & 1) ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
 }
 
 /****
@@ -213,37 +177,26 @@ static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
  */
 static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
 {
-       int i;
+       hwif->set_pio_mode = &cs5535_set_pio_mode;
+       hwif->set_dma_mode = &cs5535_set_dma_mode;
 
-       hwif->autodma = 0;
+       hwif->drives[1].autotune = hwif->drives[0].autotune = 1;
 
-       hwif->tuneproc = &cs5535_tuneproc;
-       hwif->speedproc = &cs5535_set_drive;
-       hwif->ide_dma_check = &cs5535_dma_check;
+       if (hwif->dma_base == 0)
+               return;
 
-       hwif->atapi_dma = 1;
        hwif->ultra_mask = 0x1F;
        hwif->mwdma_mask = 0x07;
 
-
-       hwif->udma_four = cs5535_cable_detect(hwif->pci_dev);
-
-       if (!noautodma)
-               hwif->autodma = 1;
-
-       /* just setting autotune and not worrying about bios timings */
-       for (i = 0; i < 2; i++) {
-               hwif->drives[i].autotune = 1;
-               hwif->drives[i].autodma = hwif->autodma;
-       }
+       hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
 }
 
 static ide_pci_device_t cs5535_chipset __devinitdata = {
        .name           = "CS5535",
        .init_hwif      = init_hwif_cs5535,
-       .channels       = 1,
-       .autodma        = AUTODMA,
-       .bootable       = ON_BOARD,
+       .host_flags     = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
+                         IDE_HFLAG_BOOTABLE,
+       .pio_mask       = ATA_PIO4,
 };
 
 static int __devinit cs5535_init_one(struct pci_dev *dev,
@@ -252,10 +205,8 @@ static int __devinit cs5535_init_one(struct pci_dev *dev,
        return ide_setup_pci_device(dev, &cs5535_chipset);
 }
 
-static struct pci_device_id cs5535_pci_tbl[] =
-{
-       { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_IDE, PCI_ANY_ID,
-               PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id cs5535_pci_tbl[] = {
+       { PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_CS5535_IDE), 0 },
        { 0, },
 };