ide: limit legacy VLB host drivers to alpha, x86 and mips
[safe/jmp/linux-2.6] / drivers / ide / ppc / pmac.c
index 5013b12..88619b5 100644 (file)
@@ -1,11 +1,11 @@
 /*
- * linux/drivers/ide/ide-pmac.c
- *
  * Support for IDE interfaces on PowerMacs.
+ *
  * These IDE interfaces are memory-mapped and have a DBDMA channel
  * for doing DMA.
  *
  *  Copyright (C) 1998-2003 Paul Mackerras & Ben. Herrenschmidt
+ *  Copyright (C)      2007 Bartlomiej Zolnierkiewicz
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
  * big table
  * 
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
@@ -50,7 +48,7 @@
 #include <asm/mediabay.h>
 #endif
 
-#include "ide-timing.h"
+#include "../ide-timing.h"
 
 #undef IDE_PMAC_DEBUG
 
@@ -82,7 +80,6 @@ typedef struct pmac_ide_hwif {
 } pmac_ide_hwif_t;
 
 static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
-static int pmac_ide_count;
 
 enum {
        controller_ohare,       /* OHare based */
@@ -313,7 +310,8 @@ static struct kauai_timing  kauai_pio_timings[] =
        { 240   , 0x0800038b },
        { 239   , 0x0800030c },
        { 180   , 0x05000249 },
-       { 120   , 0x04000148 }
+       { 120   , 0x04000148 },
+       { 0     , 0 },
 };
 
 static struct kauai_timing     kauai_mdma_timings[] =
@@ -353,7 +351,8 @@ static struct kauai_timing  shasta_pio_timings[] =
        { 240   , 0x040003cd },
        { 239   , 0x040003cd },
        { 180   , 0x0400028b },
-       { 120   , 0x0400010a }
+       { 120   , 0x0400010a },
+       { 0     , 0 },
 };
 
 static struct kauai_timing     shasta_mdma_timings[] =
@@ -391,6 +390,7 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
        for (i=0; table[i].cycle_time; i++)
                if (cycle_time > table[i+1].cycle_time)
                        return table[i].timing_reg;
+       BUG();
        return 0;
 }
 
@@ -411,151 +411,15 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
  */
 #define IDE_WAKEUP_DELAY       (1*HZ)
 
-static void pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif);
+static int pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif);
 static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
-static int pmac_ide_tune_chipset(ide_drive_t *drive, u8 speed);
-static void pmac_ide_tuneproc(ide_drive_t *drive, u8 pio);
 static void pmac_ide_selectproc(ide_drive_t *drive);
 static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
-/*
- * Below is the code for blinking the laptop LED along with hard
- * disk activity.
- */
-
-#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
-
-/* Set to 50ms minimum led-on time (also used to limit frequency
- * of requests sent to the PMU
- */
-#define PMU_HD_BLINK_TIME      (HZ/50)
-
-static struct adb_request pmu_blink_on, pmu_blink_off;
-static spinlock_t pmu_blink_lock;
-static unsigned long pmu_blink_stoptime;
-static int pmu_blink_ledstate;
-static struct timer_list pmu_blink_timer;
-static int pmu_ide_blink_enabled;
-
-
-static void
-pmu_hd_blink_timeout(unsigned long data)
-{
-       unsigned long flags;
-       
-       spin_lock_irqsave(&pmu_blink_lock, flags);
-
-       /* We may have been triggered again in a racy way, check
-        * that we really want to switch it off
-        */
-       if (time_after(pmu_blink_stoptime, jiffies))
-               goto done;
-
-       /* Previous req. not complete, try 100ms more */
-       if (pmu_blink_off.complete == 0)
-               mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME);
-       else if (pmu_blink_ledstate) {
-               pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0);
-               pmu_blink_ledstate = 0;
-       }
-done:
-       spin_unlock_irqrestore(&pmu_blink_lock, flags);
-}
-
-static void
-pmu_hd_kick_blink(void *data, int rw)
-{
-       unsigned long flags;
-       
-       pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME;
-       wmb();
-       mod_timer(&pmu_blink_timer, pmu_blink_stoptime);
-       /* Fast path when LED is already ON */
-       if (pmu_blink_ledstate == 1)
-               return;
-       spin_lock_irqsave(&pmu_blink_lock, flags);
-       if (pmu_blink_on.complete && !pmu_blink_ledstate) {
-               pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1);
-               pmu_blink_ledstate = 1;
-       }
-       spin_unlock_irqrestore(&pmu_blink_lock, flags);
-}
-
-static int
-pmu_hd_blink_init(void)
-{
-       struct device_node *dt;
-       const char *model;
-
-       /* Currently, I only enable this feature on KeyLargo based laptops,
-        * older laptops may support it (at least heathrow/paddington) but
-        * I don't feel like loading those venerable old machines with so
-        * much additional interrupt & PMU activity...
-        */
-       if (pmu_get_model() != PMU_KEYLARGO_BASED)
-               return 0;
-       
-       dt = of_find_node_by_path("/");
-       if (dt == NULL)
-               return 0;
-       model = (const char *)get_property(dt, "model", NULL);
-       if (model == NULL)
-               return 0;
-       if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 &&
-           strncmp(model, "iBook", strlen("iBook")) != 0) {
-               of_node_put(dt);
-               return 0;
-       }
-       of_node_put(dt);
-
-       pmu_blink_on.complete = 1;
-       pmu_blink_off.complete = 1;
-       spin_lock_init(&pmu_blink_lock);
-       init_timer(&pmu_blink_timer);
-       pmu_blink_timer.function = pmu_hd_blink_timeout;
-
-       return 1;
-}
-
-#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
-
-/*
- * N.B. this can't be an initfunc, because the media-bay task can
- * call ide_[un]register at any time.
- */
-void
-pmac_ide_init_hwif_ports(hw_regs_t *hw,
-                             unsigned long data_port, unsigned long ctrl_port,
-                             int *irq)
-{
-       int i, ix;
-
-       if (data_port == 0)
-               return;
-
-       for (ix = 0; ix < MAX_HWIFS; ++ix)
-               if (data_port == pmac_ide[ix].regbase)
-                       break;
-
-       if (ix >= MAX_HWIFS) {
-               /* Probably a PCI interface... */
-               for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i)
-                       hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET;
-               hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
-               return;
-       }
-
-       for (i = 0; i < 8; ++i)
-               hw->io_ports[i] = data_port + i * 0x10;
-       hw->io_ports[8] = data_port + 0x160;
-
-       if (irq != NULL)
-               *irq = pmac_ide[ix].irq;
-}
-
-#define PMAC_IDE_REG(x) ((void __iomem *)(IDE_DATA_REG+(x)))
+#define PMAC_IDE_REG(x) \
+       ((void __iomem *)((drive)->hwif->io_ports[IDE_DATA_OFFSET] + (x)))
 
 /*
  * Apply the timings of the proper unit (master/slave) to the shared
@@ -629,128 +493,43 @@ pmac_outbsync(ide_drive_t *drive, u8 value, unsigned long port)
 }
 
 /*
- * Send the SET_FEATURE IDE command to the drive and update drive->id with
- * the new state. We currently don't use the generic routine as it used to
- * cause various trouble, especially with older mediabays.
- * This code is sometimes triggering a spurrious interrupt though, I need
- * to sort that out sooner or later and see if I can finally get the
- * common version to work properly in all cases
- */
-static int
-pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
-{
-       ide_hwif_t *hwif = HWIF(drive);
-       int result = 1;
-       
-       disable_irq_nosync(hwif->irq);
-       udelay(1);
-       SELECT_DRIVE(drive);
-       SELECT_MASK(drive, 0);
-       udelay(1);
-       /* Get rid of pending error state */
-       (void) hwif->INB(IDE_STATUS_REG);
-       /* Timeout bumped for some powerbooks */
-       if (wait_for_ready(drive, 2000)) {
-               /* Timeout bumped for some powerbooks */
-               printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready "
-                       "before SET_FEATURE!\n", drive->name);
-               goto out;
-       }
-       udelay(10);
-       hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG);
-       hwif->OUTB(command, IDE_NSECTOR_REG);
-       hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG);
-       hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
-       udelay(1);
-       /* Timeout bumped for some powerbooks */
-       result = wait_for_ready(drive, 2000);
-       hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
-       if (result)
-               printk(KERN_ERR "%s: pmac_ide_do_setfeature disk not ready "
-                       "after SET_FEATURE !\n", drive->name);
-out:
-       SELECT_MASK(drive, 0);
-       if (result == 0) {
-               drive->id->dma_ultra &= ~0xFF00;
-               drive->id->dma_mword &= ~0x0F00;
-               drive->id->dma_1word &= ~0x0F00;
-               switch(command) {
-                       case XFER_UDMA_7:
-                               drive->id->dma_ultra |= 0x8080; break;
-                       case XFER_UDMA_6:
-                               drive->id->dma_ultra |= 0x4040; break;
-                       case XFER_UDMA_5:
-                               drive->id->dma_ultra |= 0x2020; break;
-                       case XFER_UDMA_4:
-                               drive->id->dma_ultra |= 0x1010; break;
-                       case XFER_UDMA_3:
-                               drive->id->dma_ultra |= 0x0808; break;
-                       case XFER_UDMA_2:
-                               drive->id->dma_ultra |= 0x0404; break;
-                       case XFER_UDMA_1:
-                               drive->id->dma_ultra |= 0x0202; break;
-                       case XFER_UDMA_0:
-                               drive->id->dma_ultra |= 0x0101; break;
-                       case XFER_MW_DMA_2:
-                               drive->id->dma_mword |= 0x0404; break;
-                       case XFER_MW_DMA_1:
-                               drive->id->dma_mword |= 0x0202; break;
-                       case XFER_MW_DMA_0:
-                               drive->id->dma_mword |= 0x0101; break;
-                       case XFER_SW_DMA_2:
-                               drive->id->dma_1word |= 0x0404; break;
-                       case XFER_SW_DMA_1:
-                               drive->id->dma_1word |= 0x0202; break;
-                       case XFER_SW_DMA_0:
-                               drive->id->dma_1word |= 0x0101; break;
-                       default: break;
-               }
-       }
-       enable_irq(hwif->irq);
-       return result;
-}
-
-/*
  * Old tuning functions (called on hdparm -p), sets up drive PIO timings
  */
 static void
-pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
+pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
 {
-       ide_pio_data_t d;
-       u32 *timings;
+       u32 *timings, t;
        unsigned accessTicks, recTicks;
        unsigned accessTime, recTime;
        pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
-       
+       unsigned int cycle_time;
+
        if (pmif == NULL)
                return;
                
        /* which drive is it ? */
        timings = &pmif->timings[drive->select.b.unit & 0x01];
+       t = *timings;
 
-       pio = ide_get_best_pio_mode(drive, pio, 4, &d);
+       cycle_time = ide_pio_cycle_time(drive, pio);
 
        switch (pmif->kind) {
        case controller_sh_ata6: {
                /* 133Mhz cell */
-               u32 tr = kauai_lookup_timing(shasta_pio_timings, d.cycle_time);
-               if (tr == 0)
-                       return;
-               *timings = ((*timings) & ~TR_133_PIOREG_PIO_MASK) | tr;
+               u32 tr = kauai_lookup_timing(shasta_pio_timings, cycle_time);
+               t = (t & ~TR_133_PIOREG_PIO_MASK) | tr;
                break;
                }
        case controller_un_ata6:
        case controller_k2_ata6: {
                /* 100Mhz cell */
-               u32 tr = kauai_lookup_timing(kauai_pio_timings, d.cycle_time);
-               if (tr == 0)
-                       return;
-               *timings = ((*timings) & ~TR_100_PIOREG_PIO_MASK) | tr;
+               u32 tr = kauai_lookup_timing(kauai_pio_timings, cycle_time);
+               t = (t & ~TR_100_PIOREG_PIO_MASK) | tr;
                break;
                }
        case controller_kl_ata4:
                /* 66Mhz cell */
-               recTime = d.cycle_time - ide_pio_timings[pio].active_time
+               recTime = cycle_time - ide_pio_timings[pio].active_time
                                - ide_pio_timings[pio].setup_time;
                recTime = max(recTime, 150U);
                accessTime = ide_pio_timings[pio].active_time;
@@ -759,14 +538,14 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
                accessTicks = min(accessTicks, 0x1fU);
                recTicks = SYSCLK_TICKS_66(recTime);
                recTicks = min(recTicks, 0x1fU);
-               *timings = ((*timings) & ~TR_66_PIO_MASK) |
-                               (accessTicks << TR_66_PIO_ACCESS_SHIFT) |
-                               (recTicks << TR_66_PIO_RECOVERY_SHIFT);
+               t = (t & ~TR_66_PIO_MASK) |
+                       (accessTicks << TR_66_PIO_ACCESS_SHIFT) |
+                       (recTicks << TR_66_PIO_RECOVERY_SHIFT);
                break;
        default: {
                /* 33Mhz cell */
                int ebit = 0;
-               recTime = d.cycle_time - ide_pio_timings[pio].active_time
+               recTime = cycle_time - ide_pio_timings[pio].active_time
                                - ide_pio_timings[pio].setup_time;
                recTime = max(recTime, 150U);
                accessTime = ide_pio_timings[pio].active_time;
@@ -781,11 +560,11 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
                        recTicks--; /* guess, but it's only for PIO0, so... */
                        ebit = 1;
                }
-               *timings = ((*timings) & ~TR_33_PIO_MASK) |
+               t = (t & ~TR_33_PIO_MASK) |
                                (accessTicks << TR_33_PIO_ACCESS_SHIFT) |
                                (recTicks << TR_33_PIO_RECOVERY_SHIFT);
                if (ebit)
-                       *timings |= TR_33_PIO_E;
+                       t |= TR_33_PIO_E;
                break;
                }
        }
@@ -795,8 +574,8 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
                drive->name, pio,  *timings);
 #endif 
 
-       if (drive->select.all == HWIF(drive)->INB(IDE_SELECT_REG))
-               pmac_ide_do_update_timings(drive);
+       *timings = t;
+       pmac_ide_do_update_timings(drive);
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
@@ -841,8 +620,6 @@ set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
        if (speed > XFER_UDMA_5 || t == NULL)
                return 1;
        tr = kauai_lookup_timing(kauai_udma_timings, (int)t->udma);
-       if (tr == 0)
-               return 1;
        *ultra_timings = ((*ultra_timings) & ~TR_100_UDMAREG_UDMA_MASK) | tr;
        *ultra_timings = (*ultra_timings) | TR_100_UDMAREG_UDMA_EN;
 
@@ -861,8 +638,6 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
        if (speed > XFER_UDMA_6 || t == NULL)
                return 1;
        tr = kauai_lookup_timing(shasta_udma133_timings, (int)t->udma);
-       if (tr == 0)
-               return 1;
        *ultra_timings = ((*ultra_timings) & ~TR_133_UDMAREG_UDMA_MASK) | tr;
        *ultra_timings = (*ultra_timings) | TR_133_UDMAREG_UDMA_EN;
 
@@ -872,12 +647,13 @@ set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
 /*
  * Calculate MDMA timings for all cells
  */
-static int
+static void
 set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
-                       u8 speed, int drive_cycle_time)
+                       u8 speed)
 {
        int cycleTime, accessTime = 0, recTime = 0;
        unsigned accessTicks, recTicks;
+       struct hd_driveid *id = drive->id;
        struct mdma_timings_t* tm = NULL;
        int i;
 
@@ -887,11 +663,14 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
                case 1: cycleTime = 150; break;
                case 2: cycleTime = 120; break;
                default:
-                       return 1;
+                       BUG();
+                       break;
        }
-       /* Adjust for drive */
-       if (drive_cycle_time && drive_cycle_time > cycleTime)
-               cycleTime = drive_cycle_time;
+
+       /* Check if drive provides explicit DMA cycle time */
+       if ((id->field_valid & 2) && id->eide_dma_time)
+               cycleTime = max_t(int, id->eide_dma_time, cycleTime);
+
        /* OHare limits according to some old Apple sources */  
        if ((intf_type == controller_ohare) && (cycleTime < 150))
                cycleTime = 150;
@@ -919,8 +698,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
                                break;
                        i++;
                }
-               if (i < 0)
-                       return 1;
                cycleTime = tm[i].cycleTime;
                accessTime = tm[i].accessTime;
                recTime = tm[i].recoveryTime;
@@ -934,8 +711,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
        case controller_sh_ata6: {
                /* 133Mhz cell */
                u32 tr = kauai_lookup_timing(shasta_mdma_timings, cycleTime);
-               if (tr == 0)
-                       return 1;
                *timings = ((*timings) & ~TR_133_PIOREG_MDMA_MASK) | tr;
                *timings2 = (*timings2) & ~TR_133_UDMAREG_UDMA_EN;
                }
@@ -943,8 +718,6 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
        case controller_k2_ata6: {
                /* 100Mhz cell */
                u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime);
-               if (tr == 0)
-                       return 1;
                *timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr;
                *timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN;
                }
@@ -1006,89 +779,45 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
        printk(KERN_ERR "%s: Set MDMA timing for mode %d, reg: 0x%08x\n",
                drive->name, speed & 0xf,  *timings);
 #endif 
-       return 0;
 }
 #endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC */
 
-/* 
- * Speedproc. This function is called by the core to set any of the standard
- * timing (PIO, MDMA or UDMA) to both the drive and the controller.
- * You may notice we don't use this function on normal "dma check" operation,
- * our dedicated function is more precise as it uses the drive provided
- * cycle time value. We should probably fix this one to deal with that too...
- */
-static int
-pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
+static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
 {
        int unit = (drive->select.b.unit & 0x01);
        int ret = 0;
        pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
-       u32 *timings, *timings2;
+       u32 *timings, *timings2, tl[2];
 
-       if (pmif == NULL)
-               return 1;
-               
        timings = &pmif->timings[unit];
        timings2 = &pmif->timings[unit+2];
-       
-       switch(speed) {
+
+       /* Copy timings to local image */
+       tl[0] = *timings;
+       tl[1] = *timings2;
+
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
-               case XFER_UDMA_6:
-                       if (pmif->kind != controller_sh_ata6)
-                               return 1;
-               case XFER_UDMA_5:
-                       if (pmif->kind != controller_un_ata6 &&
-                           pmif->kind != controller_k2_ata6 &&
-                           pmif->kind != controller_sh_ata6)
-                               return 1;
-               case XFER_UDMA_4:
-               case XFER_UDMA_3:
-                       if (HWIF(drive)->udma_four == 0)
-                               return 1;               
-               case XFER_UDMA_2:
-               case XFER_UDMA_1:
-               case XFER_UDMA_0:
-                       if (pmif->kind == controller_kl_ata4)
-                               ret = set_timings_udma_ata4(timings, speed);
-                       else if (pmif->kind == controller_un_ata6
-                                || pmif->kind == controller_k2_ata6)
-                               ret = set_timings_udma_ata6(timings, timings2, speed);
-                       else if (pmif->kind == controller_sh_ata6)
-                               ret = set_timings_udma_shasta(timings, timings2, speed);
-                       else
-                               ret = 1;                
-                       break;
-               case XFER_MW_DMA_2:
-               case XFER_MW_DMA_1:
-               case XFER_MW_DMA_0:
-                       ret = set_timings_mdma(drive, pmif->kind, timings, timings2, speed, 0);
-                       break;
-               case XFER_SW_DMA_2:
-               case XFER_SW_DMA_1:
-               case XFER_SW_DMA_0:
-                       return 1;
+       if (speed >= XFER_UDMA_0) {
+               if (pmif->kind == controller_kl_ata4)
+                       ret = set_timings_udma_ata4(&tl[0], speed);
+               else if (pmif->kind == controller_un_ata6
+                        || pmif->kind == controller_k2_ata6)
+                       ret = set_timings_udma_ata6(&tl[0], &tl[1], speed);
+               else if (pmif->kind == controller_sh_ata6)
+                       ret = set_timings_udma_shasta(&tl[0], &tl[1], speed);
+               else
+                       ret = -1;
+       } else
+               set_timings_mdma(drive, pmif->kind, &tl[0], &tl[1], speed);
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
-               case XFER_PIO_4:
-               case XFER_PIO_3:
-               case XFER_PIO_2:
-               case XFER_PIO_1:
-               case XFER_PIO_0:
-                       pmac_ide_tuneproc(drive, speed & 0x07);
-                       break;
-               default:
-                       ret = 1;
-       }
        if (ret)
-               return ret;
+               return;
 
-       ret = pmac_ide_do_setfeature(drive, speed);
-       if (ret)
-               return ret;
-               
-       pmac_ide_do_update_timings(drive);      
-       drive->current_speed = speed;
+       /* Apply timings to controller */
+       *timings = tl[0];
+       *timings2 = tl[1];
 
-       return 0;
+       pmac_ide_do_update_timings(drive);      
 }
 
 /*
@@ -1126,58 +855,6 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
        pmif->timings[2] = pmif->timings[3] = value2;
 }
 
-unsigned long
-pmac_ide_get_base(int index)
-{
-       return pmac_ide[index].regbase;
-}
-
-int
-pmac_ide_check_base(unsigned long base)
-{
-       int ix;
-       
-       for (ix = 0; ix < MAX_HWIFS; ++ix)
-               if (base == pmac_ide[ix].regbase)
-                       return ix;
-       return -1;
-}
-
-int
-pmac_ide_get_irq(unsigned long base)
-{
-       int ix;
-
-       for (ix = 0; ix < MAX_HWIFS; ++ix)
-               if (base == pmac_ide[ix].regbase)
-                       return pmac_ide[ix].irq;
-       return 0;
-}
-
-static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
-
-dev_t __init
-pmac_find_ide_boot(char *bootdevice, int n)
-{
-       int i;
-       
-       /*
-        * Look through the list of IDE interfaces for this one.
-        */
-       for (i = 0; i < pmac_ide_count; ++i) {
-               char *name;
-               if (!pmac_ide[i].node || !pmac_ide[i].node->full_name)
-                       continue;
-               name = pmac_ide[i].node->full_name;
-               if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {
-                       /* XXX should cope with the 2nd drive as well... */
-                       return MKDEV(ide_majors[i], 0);
-               }
-       }
-
-       return 0;
-}
-
 /* Suspend call back, should be called after the child devices
  * have actually been suspended
  */
@@ -1190,23 +867,6 @@ pmac_ide_do_suspend(ide_hwif_t *hwif)
        pmif->timings[0] = 0;
        pmif->timings[1] = 0;
        
-#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
-       /* Note: This code will be called for every hwif, thus we'll
-        * try several time to stop the LED blinker timer,  but that
-        * should be harmless
-        */
-       if (pmu_ide_blink_enabled) {
-               unsigned long flags;
-
-               /* Make sure we don't hit the PMU blink */
-               spin_lock_irqsave(&pmu_blink_lock, flags);
-               if (pmu_blink_ledstate)
-                       del_timer(&pmu_blink_timer);
-               pmu_blink_ledstate = 0;
-               spin_unlock_irqrestore(&pmu_blink_lock, flags);
-       }
-#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */
-
        disable_irq(pmif->irq);
 
        /* The media bay will handle itself just fine */
@@ -1260,6 +920,17 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
        return 0;
 }
 
+static const struct ide_port_info pmac_port_info = {
+       .chipset                = ide_pmac,
+       .host_flags             = IDE_HFLAG_SET_PIO_MODE_KEEP_DMA |
+                                 IDE_HFLAG_PIO_NO_DOWNGRADE |
+                                 IDE_HFLAG_POST_SET_MODE |
+                                 IDE_HFLAG_NO_DMA | /* no SFF-style DMA */
+                                 IDE_HFLAG_UNMASK_IRQS,
+       .pio_mask               = ATA_PIO4,
+       .mwdma_mask             = ATA_MWDMA2,
+};
+
 /*
  * Setup, register & probe an IDE channel driven by this driver, this is
  * called by one of the 2 probe functions (macio or PCI). Note that a channel
@@ -1267,40 +938,46 @@ pmac_ide_do_resume(ide_hwif_t *hwif)
  * (it is kept in 2.4). This introduce an interface numbering change on some
  * rare machines unfortunately, but it's better this way.
  */
-static int
-pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+static int __devinit
+pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif, hw_regs_t *hw)
 {
        struct device_node *np = pmif->node;
-       int *bidp;
+       const int *bidp;
+       u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+       struct ide_port_info d = pmac_port_info;
 
        pmif->cable_80 = 0;
        pmif->broken_dma = pmif->broken_dma_warn = 0;
-       if (device_is_compatible(np, "shasta-ata"))
+       if (of_device_is_compatible(np, "shasta-ata")) {
                pmif->kind = controller_sh_ata6;
-       else if (device_is_compatible(np, "kauai-ata"))
+               d.udma_mask = ATA_UDMA6;
+       } else if (of_device_is_compatible(np, "kauai-ata")) {
                pmif->kind = controller_un_ata6;
-       else if (device_is_compatible(np, "K2-UATA"))
+               d.udma_mask = ATA_UDMA5;
+       } else if (of_device_is_compatible(np, "K2-UATA")) {
                pmif->kind = controller_k2_ata6;
-       else if (device_is_compatible(np, "keylargo-ata")) {
-               if (strcmp(np->name, "ata-4") == 0)
+               d.udma_mask = ATA_UDMA5;
+       } else if (of_device_is_compatible(np, "keylargo-ata")) {
+               if (strcmp(np->name, "ata-4") == 0) {
                        pmif->kind = controller_kl_ata4;
-               else
+                       d.udma_mask = ATA_UDMA4;
+               } else
                        pmif->kind = controller_kl_ata3;
-       } else if (device_is_compatible(np, "heathrow-ata"))
+       } else if (of_device_is_compatible(np, "heathrow-ata")) {
                pmif->kind = controller_heathrow;
-       else {
+       else {
                pmif->kind = controller_ohare;
                pmif->broken_dma = 1;
        }
 
-       bidp = (int *)get_property(np, "AAPL,bus-id", NULL);
+       bidp = of_get_property(np, "AAPL,bus-id", NULL);
        pmif->aapl_bus_id =  bidp ? *bidp : 0;
 
        /* Get cable type from device-tree */
        if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6
            || pmif->kind == controller_k2_ata6
            || pmif->kind == controller_sh_ata6) {
-               char* cable = get_property(np, "cable-type", NULL);
+               const char* cable = of_get_property(np, "cable-type", NULL);
                if (cable && !strncmp(cable, "80-", 3))
                        pmif->cable_80 = 1;
        }
@@ -1308,8 +985,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
         * they have a 80 conductor cable, this seem to be always the case unless
         * the user mucked around
         */
-       if (device_is_compatible(np, "K2-UATA") ||
-           device_is_compatible(np, "shasta-ata"))
+       if (of_device_is_compatible(np, "K2-UATA") ||
+           of_device_is_compatible(np, "shasta-ata"))
                pmif->cable_80 = 1;
 
        /* On Kauai-type controllers, we make sure the FCR is correct */
@@ -1328,7 +1005,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
        if (np->parent && np->parent->name
            && strcasecmp(np->parent->name, "media-bay") == 0) {
 #ifdef CONFIG_PMAC_MEDIABAY
-               media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index);
+               media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq,
+                                       hwif);
 #endif /* CONFIG_PMAC_MEDIABAY */
                pmif->mediabay = 1;
                if (!bidp)
@@ -1355,31 +1033,19 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
                hwif->OUTBSYNC = pmac_outbsync;
 
        /* Tell common code _not_ to mess with resources */
-       hwif->mmio = 2;
+       hwif->mmio = 1;
        hwif->hwif_data = pmif;
-       pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
-       memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
-       hwif->chipset = ide_pmac;
-       hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
-       hwif->hold = pmif->mediabay;
-       hwif->udma_four = pmif->cable_80;
-       hwif->drives[0].unmask = 1;
-       hwif->drives[1].unmask = 1;
-       hwif->tuneproc = pmac_ide_tuneproc;
+       ide_init_port_hw(hwif, hw);
+       hwif->noprobe = pmif->mediabay;
+       hwif->cbl = pmif->cable_80 ? ATA_CBL_PATA80 : ATA_CBL_PATA40;
+       hwif->set_pio_mode = pmac_ide_set_pio_mode;
        if (pmif->kind == controller_un_ata6
            || pmif->kind == controller_k2_ata6
            || pmif->kind == controller_sh_ata6)
                hwif->selectproc = pmac_ide_kauai_selectproc;
        else
                hwif->selectproc = pmac_ide_selectproc;
-       hwif->speedproc = pmac_ide_tune_chipset;
-
-#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK
-       pmu_ide_blink_enabled = pmu_hd_blink_init();
-
-       if (pmu_ide_blink_enabled)
-               hwif->led_act = pmu_hd_kick_blink;
-#endif
+       hwif->set_dma_mode = pmac_ide_set_dma_mode;
 
        printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",
               hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,
@@ -1390,20 +1056,30 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
                hwif->noprobe = 0;
 #endif /* CONFIG_PMAC_MEDIABAY */
 
-       hwif->sg_max_nents = MAX_DCMDS;
-
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+       if (pmif->cable_80 == 0)
+               d.udma_mask &= ATA_UDMA2;
        /* has a DBDMA controller channel */
-       if (pmif->dma_regs)
-               pmac_ide_setup_dma(pmif, hwif);
-#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+       if (pmif->dma_regs == 0 || pmac_ide_setup_dma(pmif, hwif) < 0)
+#endif
+               d.udma_mask = d.mwdma_mask = 0;
+
+       idx[0] = hwif->index;
 
-       /* We probe the hwif now */
-       probe_hwif_init(hwif);
+       ide_device_add(idx, &d);
 
        return 0;
 }
 
+static void __devinit pmac_ide_init_ports(hw_regs_t *hw, unsigned long base)
+{
+       int i;
+
+       for (i = 0; i < 8; ++i)
+               hw->io_ports[i] = base + i * 0x10;
+       hw->io_ports[8] = base + 0x160;
+}
+
 /*
  * Attach to a macio probed interface
  */
@@ -1416,6 +1092,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
        ide_hwif_t *hwif;
        pmac_ide_hwif_t *pmif;
        int i, rc;
+       hw_regs_t hw;
 
        i = 0;
        while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0
@@ -1450,15 +1127,14 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
        if (macio_irq_count(mdev) == 0) {
                printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
                        i, mdev->ofdev.node->full_name);
-               irq = 13;
+               irq = irq_create_mapping(NULL, 13);
        } else
                irq = macio_irq(mdev, 0);
 
        base = ioremap(macio_resource_start(mdev, 0), 0x400);
        regbase = (unsigned long) base;
 
-       hwif->pci_dev = mdev->bus->pdev;
-       hwif->gendev.parent = &mdev->ofdev.dev;
+       hwif->dev = &mdev->bus->pdev->dev;
 
        pmif->mdev = mdev;
        pmif->node = mdev->ofdev.node;
@@ -1476,32 +1152,38 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
        dev_set_drvdata(&mdev->ofdev.dev, hwif);
 
-       rc = pmac_ide_setup_device(pmif, hwif);
+       memset(&hw, 0, sizeof(hw));
+       pmac_ide_init_ports(&hw, pmif->regbase);
+       hw.irq = irq;
+       hw.dev = &mdev->ofdev.dev;
+
+       rc = pmac_ide_setup_device(pmif, hwif, &hw);
        if (rc != 0) {
                /* The inteface is released to the common IDE layer */
                dev_set_drvdata(&mdev->ofdev.dev, NULL);
                iounmap(base);
-               if (pmif->dma_regs)
+               if (pmif->dma_regs) {
                        iounmap(pmif->dma_regs);
+                       macio_release_resource(mdev, 1);
+               }
                memset(pmif, 0, sizeof(*pmif));
                macio_release_resource(mdev, 0);
-               if (pmif->dma_regs)
-                       macio_release_resource(mdev, 1);
        }
 
        return rc;
 }
 
 static int
-pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t state)
+pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
 {
        ide_hwif_t      *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
        int             rc = 0;
 
-       if (state.event != mdev->ofdev.dev.power.power_state.event && state.event >= PM_EVENT_SUSPEND) {
+       if (mesg.event != mdev->ofdev.dev.power.power_state.event
+                       && (mesg.event & PM_EVENT_SLEEP)) {
                rc = pmac_ide_do_suspend(hwif);
                if (rc == 0)
-                       mdev->ofdev.dev.power.power_state = state;
+                       mdev->ofdev.dev.power.power_state = mesg;
        }
 
        return rc;
@@ -1534,6 +1216,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        void __iomem *base;
        unsigned long rbase, rlen;
        int i, rc;
+       hw_regs_t hw;
 
        np = pci_device_to_OF_node(pdev);
        if (np == NULL) {
@@ -1566,8 +1249,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
                return -ENXIO;
        }
 
-       hwif->pci_dev = pdev;
-       hwif->gendev.parent = &pdev->dev;
+       hwif->dev = &pdev->dev;
        pmif->mdev = NULL;
        pmif->node = np;
 
@@ -1584,7 +1266,12 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 
        pci_set_drvdata(pdev, hwif);
 
-       rc = pmac_ide_setup_device(pmif, hwif);
+       memset(&hw, 0, sizeof(hw));
+       pmac_ide_init_ports(&hw, pmif->regbase);
+       hw.irq = pdev->irq;
+       hw.dev = &pdev->dev;
+
+       rc = pmac_ide_setup_device(pmif, hwif, &hw);
        if (rc != 0) {
                /* The inteface is released to the common IDE layer */
                pci_set_drvdata(pdev, NULL);
@@ -1597,15 +1284,16 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 }
 
 static int
-pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
        ide_hwif_t      *hwif = (ide_hwif_t *)pci_get_drvdata(pdev);
        int             rc = 0;
        
-       if (state.event != pdev->dev.power.power_state.event && state.event >= 2) {
+       if (mesg.event != pdev->dev.power.power_state.event
+                       && (mesg.event & PM_EVENT_SLEEP)) {
                rc = pmac_ide_do_suspend(hwif);
                if (rc == 0)
-                       pdev->dev.power.power_state = state;
+                       pdev->dev.power.power_state = mesg;
        }
 
        return rc;
@@ -1652,17 +1340,13 @@ static struct macio_driver pmac_ide_macio_driver =
        .resume         = pmac_ide_macio_resume,
 };
 
-static struct pci_device_id pmac_ide_pci_match[] = {
-       { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-       { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA,
-         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+static const struct pci_device_id pmac_ide_pci_match[] = {
+       { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA),    0 },
+       { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100),  0 },
+       { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100),    0 },
+       { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_SH_ATA),       0 },
+       { PCI_VDEVICE(APPLE, PCI_DEVICE_ID_APPLE_IPID2_ATA),    0 },
+       {},
 };
 
 static struct pci_driver pmac_ide_pci_driver = {
@@ -1674,19 +1358,34 @@ static struct pci_driver pmac_ide_pci_driver = {
 };
 MODULE_DEVICE_TABLE(pci, pmac_ide_pci_match);
 
-void __init
-pmac_ide_probe(void)
+int __init pmac_ide_probe(void)
 {
-       if (_machine != _MACH_Pmac)
-               return;
+       int error;
+
+       if (!machine_is(powermac))
+               return -ENODEV;
 
 #ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
-       pci_register_driver(&pmac_ide_pci_driver);
-       macio_register_driver(&pmac_ide_macio_driver);
+       error = pci_register_driver(&pmac_ide_pci_driver);
+       if (error)
+               goto out;
+       error = macio_register_driver(&pmac_ide_macio_driver);
+       if (error) {
+               pci_unregister_driver(&pmac_ide_pci_driver);
+               goto out;
+       }
 #else
-       macio_register_driver(&pmac_ide_macio_driver);
-       pci_register_driver(&pmac_ide_pci_driver);
+       error = macio_register_driver(&pmac_ide_macio_driver);
+       if (error)
+               goto out;
+       error = pci_register_driver(&pmac_ide_pci_driver);
+       if (error) {
+               macio_unregister_driver(&pmac_ide_macio_driver);
+               goto out;
+       }
 #endif
+out:
+       return error;
 }
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
@@ -1730,7 +1429,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
 
                if (pmif->broken_dma && cur_addr & (L1_CACHE_BYTES - 1)) {
                        if (pmif->broken_dma_warn == 0) {
-                               printk(KERN_WARNING "%s: DMA on non aligned address,"
+                               printk(KERN_WARNING "%s: DMA on non aligned address, "
                                       "switching to PIO on Ohare chipset\n", drive->name);
                                pmif->broken_dma_warn = 1;
                        }
@@ -1754,7 +1453,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
                        cur_len -= tc;
                        ++table;
                }
-               sg++;
+               sg = sg_next(sg);
                i--;
        }
 
@@ -1770,11 +1469,10 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
        }
 
        printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
- use_pio_instead:
-       pci_unmap_sg(hwif->pci_dev,
-                    hwif->sg_table,
-                    hwif->sg_nents,
-                    hwif->sg_dma_direction);
+
+use_pio_instead:
+       ide_destroy_dmatable(drive);
+
        return 0; /* revert to PIO for this request */
 }
 
@@ -1783,181 +1481,14 @@ static void
 pmac_ide_destroy_dmatable (ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
-       struct pci_dev *dev = HWIF(drive)->pci_dev;
-       struct scatterlist *sg = hwif->sg_table;
-       int nents = hwif->sg_nents;
 
-       if (nents) {
-               pci_unmap_sg(dev, sg, nents, hwif->sg_dma_direction);
+       if (hwif->sg_nents) {
+               ide_destroy_dmatable(drive);
                hwif->sg_nents = 0;
        }
 }
 
 /*
- * Pick up best MDMA timing for the drive and apply it
- */
-static int
-pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
-{
-       ide_hwif_t *hwif = HWIF(drive);
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-       int drive_cycle_time;
-       struct hd_driveid *id = drive->id;
-       u32 *timings, *timings2;
-       u32 timing_local[2];
-       int ret;
-
-       /* which drive is it ? */
-       timings = &pmif->timings[drive->select.b.unit & 0x01];
-       timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2];
-
-       /* Check if drive provide explicit cycle time */
-       if ((id->field_valid & 2) && (id->eide_dma_time))
-               drive_cycle_time = id->eide_dma_time;
-       else
-               drive_cycle_time = 0;
-
-       /* Copy timings to local image */
-       timing_local[0] = *timings;
-       timing_local[1] = *timings2;
-
-       /* Calculate controller timings */
-       ret = set_timings_mdma( drive, pmif->kind,
-                               &timing_local[0],
-                               &timing_local[1],
-                               mode,
-                               drive_cycle_time);
-       if (ret)
-               return 0;
-
-       /* Set feature on drive */
-       printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, mode & 0xf);
-       ret = pmac_ide_do_setfeature(drive, mode);
-       if (ret) {
-               printk(KERN_WARNING "%s: Failed !\n", drive->name);
-               return 0;
-       }
-
-       /* Apply timings to controller */
-       *timings = timing_local[0];
-       *timings2 = timing_local[1];
-       
-       /* Set speed info in drive */
-       drive->current_speed = mode;    
-       if (!drive->init_speed)
-               drive->init_speed = mode;
-
-       return 1;
-}
-
-/*
- * Pick up best UDMA timing for the drive and apply it
- */
-static int
-pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
-{
-       ide_hwif_t *hwif = HWIF(drive);
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-       u32 *timings, *timings2;
-       u32 timing_local[2];
-       int ret;
-               
-       /* which drive is it ? */
-       timings = &pmif->timings[drive->select.b.unit & 0x01];
-       timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2];
-
-       /* Copy timings to local image */
-       timing_local[0] = *timings;
-       timing_local[1] = *timings2;
-       
-       /* Calculate timings for interface */
-       if (pmif->kind == controller_un_ata6
-           || pmif->kind == controller_k2_ata6)
-               ret = set_timings_udma_ata6(    &timing_local[0],
-                                               &timing_local[1],
-                                               mode);
-       else if (pmif->kind == controller_sh_ata6)
-               ret = set_timings_udma_shasta(  &timing_local[0],
-                                               &timing_local[1],
-                                               mode);
-       else
-               ret = set_timings_udma_ata4(&timing_local[0], mode);
-       if (ret)
-               return 0;
-               
-       /* Set feature on drive */
-       printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, mode & 0x0f);
-       ret = pmac_ide_do_setfeature(drive, mode);
-       if (ret) {
-               printk(KERN_WARNING "%s: Failed !\n", drive->name);
-               return 0;
-       }
-
-       /* Apply timings to controller */
-       *timings = timing_local[0];
-       *timings2 = timing_local[1];
-
-       /* Set speed info in drive */
-       drive->current_speed = mode;    
-       if (!drive->init_speed)
-               drive->init_speed = mode;
-
-       return 1;
-}
-
-/*
- * Check what is the best DMA timing setting for the drive and
- * call appropriate functions to apply it.
- */
-static int
-pmac_ide_dma_check(ide_drive_t *drive)
-{
-       struct hd_driveid *id = drive->id;
-       ide_hwif_t *hwif = HWIF(drive);
-       pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-       int enable = 1;
-       int map;
-       drive->using_dma = 0;
-       
-       if (drive->media == ide_floppy)
-               enable = 0;
-       if (((id->capability & 1) == 0) && !__ide_dma_good_drive(drive))
-               enable = 0;
-       if (__ide_dma_bad_drive(drive))
-               enable = 0;
-
-       if (enable) {
-               short mode;
-               
-               map = XFER_MWDMA;
-               if (pmif->kind == controller_kl_ata4
-                   || pmif->kind == controller_un_ata6
-                   || pmif->kind == controller_k2_ata6
-                   || pmif->kind == controller_sh_ata6) {
-                       map |= XFER_UDMA;
-                       if (pmif->cable_80) {
-                               map |= XFER_UDMA_66;
-                               if (pmif->kind == controller_un_ata6 ||
-                                   pmif->kind == controller_k2_ata6 ||
-                                   pmif->kind == controller_sh_ata6)
-                                       map |= XFER_UDMA_100;
-                               if (pmif->kind == controller_sh_ata6)
-                                       map |= XFER_UDMA_133;
-                       }
-               }
-               mode = ide_find_best_mode(drive, map);
-               if (mode & XFER_UDMA)
-                       drive->using_dma = pmac_ide_udma_enable(drive, mode);
-               else if (mode & XFER_MWDMA)
-                       drive->using_dma = pmac_ide_mdma_enable(drive, mode);
-               hwif->OUTB(0, IDE_CONTROL_REG);
-               /* Apply settings to controller */
-               pmac_ide_do_update_timings(drive);
-       }
-       return 0;
-}
-
-/*
  * Prepare a DMA transfer. We build the DMA table, adjust the timings for
  * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
  */
@@ -2102,98 +1633,69 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
        return 1;
 }
 
-static int
-pmac_ide_dma_host_off (ide_drive_t *drive)
+static void pmac_ide_dma_host_set(ide_drive_t *drive, int on)
 {
-       return 0;
 }
 
-static int
-pmac_ide_dma_host_on (ide_drive_t *drive)
-{
-       return 0;
-}
-
-static int
-pmac_ide_dma_lostirq (ide_drive_t *drive)
+static void
+pmac_ide_dma_lost_irq (ide_drive_t *drive)
 {
        pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
        volatile struct dbdma_regs __iomem *dma;
        unsigned long status;
 
        if (pmif == NULL)
-               return 0;
+               return;
        dma = pmif->dma_regs;
 
        status = readl(&dma->status);
        printk(KERN_ERR "ide-pmac lost interrupt, dma status: %lx\n", status);
-       return 0;
 }
 
 /*
  * Allocate the data structures needed for using DMA with an interface
  * and fill the proper list of functions pointers
  */
-static void __init 
-pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
+static int __devinit pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
 {
+       struct pci_dev *dev = to_pci_dev(hwif->dev);
+
        /* We won't need pci_dev if we switch to generic consistent
         * DMA routines ...
         */
-       if (hwif->pci_dev == NULL)
-               return;
+       if (dev == NULL)
+               return -ENODEV;
        /*
         * Allocate space for the DBDMA commands.
         * The +2 is +1 for the stop command and +1 to allow for
         * aligning the start address to a multiple of 16 bytes.
         */
        pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
-               hwif->pci_dev,
+               dev,
                (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
                &hwif->dmatable_dma);
        if (pmif->dma_table_cpu == NULL) {
                printk(KERN_ERR "%s: unable to allocate DMA command list\n",
                       hwif->name);
-               return;
+               return -ENOMEM;
        }
 
-       hwif->ide_dma_off_quietly = &__ide_dma_off_quietly;
-       hwif->ide_dma_on = &__ide_dma_on;
-       hwif->ide_dma_check = &pmac_ide_dma_check;
+       hwif->sg_max_nents = MAX_DCMDS;
+
+       hwif->dma_host_set = &pmac_ide_dma_host_set;
        hwif->dma_setup = &pmac_ide_dma_setup;
        hwif->dma_exec_cmd = &pmac_ide_dma_exec_cmd;
        hwif->dma_start = &pmac_ide_dma_start;
        hwif->ide_dma_end = &pmac_ide_dma_end;
        hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
-       hwif->ide_dma_host_off = &pmac_ide_dma_host_off;
-       hwif->ide_dma_host_on = &pmac_ide_dma_host_on;
-       hwif->ide_dma_timeout = &__ide_dma_timeout;
-       hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
+       hwif->dma_timeout = &ide_dma_timeout;
+       hwif->dma_lost_irq = &pmac_ide_dma_lost_irq;
 
-       hwif->atapi_dma = 1;
-       switch(pmif->kind) {
-               case controller_sh_ata6:
-                       hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07;
-                       hwif->mwdma_mask = 0x07;
-                       hwif->swdma_mask = 0x00;
-                       break;
-               case controller_un_ata6:
-               case controller_k2_ata6:
-                       hwif->ultra_mask = pmif->cable_80 ? 0x3f : 0x07;
-                       hwif->mwdma_mask = 0x07;
-                       hwif->swdma_mask = 0x00;
-                       break;
-               case controller_kl_ata4:
-                       hwif->ultra_mask = pmif->cable_80 ? 0x1f : 0x07;
-                       hwif->mwdma_mask = 0x07;
-                       hwif->swdma_mask = 0x00;
-                       break;
-               default:
-                       hwif->ultra_mask = 0x00;
-                       hwif->mwdma_mask = 0x07;
-                       hwif->swdma_mask = 0x00;
-                       break;
-       }       
+       return 0;
 }
 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+
+module_init(pmac_ide_probe);
+
+MODULE_LICENSE("GPL");