/*
- * linux/drivers/ide/ide-pmac.c
+ * linux/drivers/ide/ppc/pmac.c
*
* Support for IDE interfaces on PowerMacs.
* These IDE interfaces are memory-mapped and have a DBDMA channel
* big table
*
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/adb.h>
#include <linux/pmu.h>
+#include <linux/scatterlist.h>
#include <asm/prom.h>
#include <asm/io.h>
#include "ide-timing.h"
-extern void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq);
-
-#define IDE_PMAC_DEBUG
+#undef IDE_PMAC_DEBUG
#define DMA_WAIT_TIMEOUT 50
int irq;
int kind;
int aapl_bus_id;
- int cable_80 : 1;
- int mediabay : 1;
- int broken_dma : 1;
- int broken_dma_warn : 1;
+ unsigned cable_80 : 1;
+ unsigned mediabay : 1;
+ unsigned broken_dma : 1;
+ unsigned broken_dma_warn : 1;
struct device_node* node;
struct macio_dev *mdev;
u32 timings[4];
+ volatile u32 __iomem * *kauai_fcr;
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* Those fields are duplicating what is in hwif. We currently
* can't use the hwif ones because of some assumptions that are
* beeing done by the generic code about the kind of dma controller
* and format of the dma table. This will have to be fixed though.
*/
- volatile struct dbdma_regs* dma_regs;
+ volatile struct dbdma_regs __iomem * dma_regs;
struct dbdma_cmd* dma_table_cpu;
- dma_addr_t dma_table_dma;
- struct scatterlist* sg_table;
- int sg_nents;
- int sg_dma_direction;
#endif
} pmac_ide_hwif_t;
-static pmac_ide_hwif_t pmac_ide[MAX_HWIFS] __pmacdata;
+static pmac_ide_hwif_t pmac_ide[MAX_HWIFS];
static int pmac_ide_count;
enum {
controller_kl_ata3, /* KeyLargo ATA-3 */
controller_kl_ata4, /* KeyLargo ATA-4 */
controller_un_ata6, /* UniNorth2 ATA-6 */
- controller_k2_ata6 /* K2 ATA-6 */
+ controller_k2_ata6, /* K2 ATA-6 */
+ controller_sh_ata6, /* Shasta ATA-6 */
};
static const char* model_name[] = {
"KeyLargo ATA-4", /* KeyLargo ATA-4 (UDMA/66) */
"UniNorth ATA-6", /* UniNorth2 ATA-6 (UDMA/100) */
"K2 ATA-6", /* K2 ATA-6 (UDMA/100) */
+ "Shasta ATA-6", /* Shasta ATA-6 (UDMA/133) */
};
/*
#define IDE_SYSCLK_NS 30 /* 33Mhz cell */
#define IDE_SYSCLK_66_NS 15 /* 66Mhz cell */
+/* 133Mhz cell, found in shasta.
+ * See comments about 100 Mhz Uninorth 2...
+ * Note that PIO_MASK and MDMA_MASK seem to overlap
+ */
+#define TR_133_PIOREG_PIO_MASK 0xff000fff
+#define TR_133_PIOREG_MDMA_MASK 0x00fff800
+#define TR_133_UDMAREG_UDMA_MASK 0x0003ffff
+#define TR_133_UDMAREG_UDMA_EN 0x00000001
+
/* 100Mhz cell, found in Uninorth 2. I don't have much infos about
* this one yet, it appears as a pci device (106b/0033) on uninorth
* internal PCI bus and it's clock is controlled like gem or fw. It
#define IDE_INTR_DMA 0x80000000
#define IDE_INTR_DEVICE 0x40000000
+/*
+ * FCR Register on Kauai. Not sure what bit 0x4 is ...
+ */
+#define KAUAI_FCR_UATA_MAGIC 0x00000004
+#define KAUAI_FCR_UATA_RESET_N 0x00000002
+#define KAUAI_FCR_UATA_ENABLE 0x00000001
+
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* Rounded Multiword DMA timings
int cycleTime;
};
-struct mdma_timings_t mdma_timings_33[] __pmacdata =
+struct mdma_timings_t mdma_timings_33[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
{ 0, 0, 0 }
};
-struct mdma_timings_t mdma_timings_33k[] __pmacdata =
+struct mdma_timings_t mdma_timings_33k[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
{ 0, 0, 0 }
};
-struct mdma_timings_t mdma_timings_66[] __pmacdata =
+struct mdma_timings_t mdma_timings_66[] =
{
{ 240, 240, 480 },
{ 180, 180, 360 },
int addrSetup; /* ??? */
int rdy2pause;
int wrDataSetup;
-} kl66_udma_timings[] __pmacdata =
+} kl66_udma_timings[] =
{
{ 0, 180, 120 }, /* Mode 0 */
{ 0, 150, 90 }, /* 1 */
u32 timing_reg;
};
-static struct kauai_timing kauai_pio_timings[] __pmacdata =
+static struct kauai_timing kauai_pio_timings[] =
{
{ 930 , 0x08000fff },
{ 600 , 0x08000a92 },
{ 120 , 0x04000148 }
};
-static struct kauai_timing kauai_mdma_timings[] __pmacdata =
+static struct kauai_timing kauai_mdma_timings[] =
{
{ 1260 , 0x00fff000 },
{ 480 , 0x00618000 },
{ 0 , 0 },
};
-static struct kauai_timing kauai_udma_timings[] __pmacdata =
+static struct kauai_timing kauai_udma_timings[] =
{
{ 120 , 0x000070c0 },
{ 90 , 0x00005d80 },
{ 0 , 0 },
};
+static struct kauai_timing shasta_pio_timings[] =
+{
+ { 930 , 0x08000fff },
+ { 600 , 0x0A000c97 },
+ { 383 , 0x07000712 },
+ { 360 , 0x040003cd },
+ { 330 , 0x040003cd },
+ { 300 , 0x040003cd },
+ { 270 , 0x040003cd },
+ { 240 , 0x040003cd },
+ { 239 , 0x040003cd },
+ { 180 , 0x0400028b },
+ { 120 , 0x0400010a }
+};
+
+static struct kauai_timing shasta_mdma_timings[] =
+{
+ { 1260 , 0x00fff000 },
+ { 480 , 0x00820800 },
+ { 360 , 0x00820800 },
+ { 270 , 0x00820800 },
+ { 240 , 0x00820800 },
+ { 210 , 0x00820800 },
+ { 180 , 0x00820800 },
+ { 150 , 0x0028b000 },
+ { 120 , 0x001ca000 },
+ { 0 , 0 },
+};
+
+static struct kauai_timing shasta_udma133_timings[] =
+{
+ { 120 , 0x00035901, },
+ { 90 , 0x000348b1, },
+ { 60 , 0x00033881, },
+ { 45 , 0x00033861, },
+ { 30 , 0x00033841, },
+ { 20 , 0x00033031, },
+ { 15 , 0x00033021, },
+ { 0 , 0 },
+};
+
+
static inline u32
kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
{
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);
-static int pmac_ide_dma_begin (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 = find_devices("device-tree");
- 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)
- return 0;
-
- 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
+void
pmac_ide_init_hwif_ports(hw_regs_t *hw,
unsigned long data_port, unsigned long ctrl_port,
int *irq)
if (irq != NULL)
*irq = pmac_ide[ix].irq;
+
+ hw->dev = &pmac_ide[ix].mdev->ofdev.dev;
}
+#define PMAC_IDE_REG(x) ((void __iomem *)(IDE_DATA_REG+(x)))
+
/*
* Apply the timings of the proper unit (master/slave) to the shared
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
-static void __pmac
+static void
pmac_ide_selectproc(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
return;
if (drive->select.b.unit & 0x01)
- writel(pmif->timings[1],
- (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG));
+ writel(pmif->timings[1], PMAC_IDE_REG(IDE_TIMING_CONFIG));
else
- writel(pmif->timings[0],
- (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG));
- (void)readl((unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG));
+ writel(pmif->timings[0], PMAC_IDE_REG(IDE_TIMING_CONFIG));
+ (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
/*
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
-static void __pmac
+static void
pmac_ide_kauai_selectproc(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
return;
if (drive->select.b.unit & 0x01) {
- writel(pmif->timings[1],
- (unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG));
- writel(pmif->timings[3],
- (unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG));
+ writel(pmif->timings[1], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
+ writel(pmif->timings[3], PMAC_IDE_REG(IDE_KAUAI_ULTRA_CONFIG));
} else {
- writel(pmif->timings[0],
- (unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG));
- writel(pmif->timings[2],
- (unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG));
+ writel(pmif->timings[0], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
+ writel(pmif->timings[2], PMAC_IDE_REG(IDE_KAUAI_ULTRA_CONFIG));
}
- (void)readl((unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG));
+ (void)readl(PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
}
/*
* Force an update of controller timing values for a given drive
*/
-static void __pmac
+static void
pmac_ide_do_update_timings(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
if (pmif == NULL)
return;
- if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6)
+ if (pmif->kind == controller_sh_ata6 ||
+ pmif->kind == controller_un_ata6 ||
+ pmif->kind == controller_k2_ata6)
pmac_ide_kauai_selectproc(drive);
else
pmac_ide_selectproc(drive);
{
u32 tmp;
- writeb(value, port);
- tmp = readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG));
+ writeb(value, (void __iomem *) port);
+ tmp = readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
/*
* 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
+static int
pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
{
ide_hwif_t *hwif = HWIF(drive);
/*
* Old tuning functions (called on hdparm -p), sets up drive PIO timings
*/
-static void __pmac
+static void
pmac_ide_tuneproc(ide_drive_t *drive, u8 pio)
{
ide_pio_data_t d;
pio = ide_get_best_pio_mode(drive, pio, 4, &d);
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;
+ break;
+ }
case controller_un_ata6:
case controller_k2_ata6: {
/* 100Mhz cell */
/*
* Calculate KeyLargo ATA/66 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_ata4(u32 *timings, u8 speed)
{
unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;
/*
* Calculate Kauai ATA/100 UDMA timings
*/
-static int __pmac
+static int
set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, u8 speed)
{
struct ide_timing *t = ide_timing_find_mode(speed);
return 0;
}
+/*
+ * Calculate Shasta ATA/133 UDMA timings
+ */
+static int
+set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed)
+{
+ struct ide_timing *t = ide_timing_find_mode(speed);
+ u32 tr;
+
+ 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;
+
+ return 0;
+}
+
/*
* Calculate MDMA timings for all cells
*/
-static int __pmac
+static int
set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
u8 speed, int drive_cycle_time)
{
- int cycleTime, accessTime, recTime;
+ int cycleTime, accessTime = 0, recTime = 0;
unsigned accessTicks, recTicks;
struct mdma_timings_t* tm = NULL;
int i;
cycleTime = 150;
/* Get the proper timing array for this controller */
switch(intf_type) {
+ case controller_sh_ata6:
case controller_un_ata6:
case controller_k2_ata6:
break;
#endif
}
switch(intf_type) {
+ 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;
+ }
case controller_un_ata6:
case controller_k2_ata6: {
/* 100Mhz cell */
* 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
+static int
pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
{
int unit = (drive->select.b.unit & 0x01);
switch(speed) {
#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_k2_ata6 &&
+ pmif->kind != controller_sh_ata6)
return 1;
case XFER_UDMA_4:
case XFER_UDMA_3:
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;
* Blast some well known "safe" values to the timing registers at init or
* wakeup from sleep time, before we do real calculation
*/
-static void __pmac
+static void
sanitize_timings(pmac_ide_hwif_t *pmif)
{
unsigned int value, value2 = 0;
switch(pmif->kind) {
+ case controller_sh_ata6:
+ value = 0x0a820c97;
+ value2 = 0x00033031;
+ break;
case controller_un_ata6:
case controller_k2_ata6:
value = 0x08618a92;
pmif->timings[2] = pmif->timings[3] = value2;
}
-unsigned long __pmac
+unsigned long
pmac_ide_get_base(int index)
{
return pmac_ide[index].regbase;
}
-int __pmac
+int
pmac_ide_check_base(unsigned long base)
{
int ix;
return -1;
}
-int __pmac
+int
pmac_ide_get_irq(unsigned long base)
{
int ix;
return 0;
}
-static int ide_majors[] __pmacdata = { 3, 22, 33, 34, 56, 57 };
+static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
dev_t __init
pmac_find_ide_boot(char *bootdevice, int n)
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 */
if (pmif->mediabay)
return 0;
- /* Disable the bus */
- ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 0);
+ /* Kauai has bus control FCRs directly here */
+ if (pmif->kauai_fcr) {
+ u32 fcr = readl(pmif->kauai_fcr);
+ fcr &= ~(KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE);
+ writel(fcr, pmif->kauai_fcr);
+ }
+
+ /* Disable the bus on older machines and the cell on kauai */
+ ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id,
+ 0);
return 0;
}
ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
msleep(10);
ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0);
+
+ /* Kauai has it different */
+ if (pmif->kauai_fcr) {
+ u32 fcr = readl(pmif->kauai_fcr);
+ fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE;
+ writel(fcr, pmif->kauai_fcr);
+ }
+
msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));
}
/* Sanitize drive timings */
sanitize_timings(pmif);
+ enable_irq(pmif->irq);
+
return 0;
}
pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
{
struct device_node *np = pmif->node;
- int *bidp, i;
+ const int *bidp;
pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0;
- if (device_is_compatible(np, "kauai-ata"))
+ if (device_is_compatible(np, "shasta-ata"))
+ pmif->kind = controller_sh_ata6;
+ else if (device_is_compatible(np, "kauai-ata"))
pmif->kind = controller_un_ata6;
else if (device_is_compatible(np, "K2-UATA"))
pmif->kind = controller_k2_ata6;
pmif->broken_dma = 1;
}
- bidp = (int *)get_property(np, "AAPL,bus-id", NULL);
+ bidp = 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) {
- char* cable = get_property(np, "cable-type", NULL);
+ || pmif->kind == controller_k2_ata6
+ || pmif->kind == controller_sh_ata6) {
+ const char* cable = get_property(np, "cable-type", NULL);
if (cable && !strncmp(cable, "80-", 3))
pmif->cable_80 = 1;
}
+ /* G5's seem to have incorrect cable type in device-tree. Let's assume
+ * 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"))
+ pmif->cable_80 = 1;
+
+ /* On Kauai-type controllers, we make sure the FCR is correct */
+ if (pmif->kauai_fcr)
+ writel(KAUAI_FCR_UATA_MAGIC |
+ KAUAI_FCR_UATA_RESET_N |
+ KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr);
pmif->mediabay = 0;
/* XXX FIXME: Media bay stuff need re-organizing */
if (np->parent && np->parent->name
&& strcasecmp(np->parent->name, "media-bay") == 0) {
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PMAC_MEDIABAY
media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PMAC_MEDIABAY */
pmif->mediabay = 1;
if (!bidp)
pmif->aapl_bus_id = 1;
hwif->drives[0].unmask = 1;
hwif->drives[1].unmask = 1;
hwif->tuneproc = pmac_ide_tuneproc;
- if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6)
+ 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
-
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,
pmif->mediabay ? " (mediabay)" : "", hwif->irq);
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PMAC_MEDIABAY
if (pmif->mediabay && check_media_bay_by_base(pmif->regbase, MB_CD) == 0)
hwif->noprobe = 0;
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PMAC_MEDIABAY */
+
+ hwif->sg_max_nents = MAX_DCMDS;
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* has a DBDMA controller channel */
/* We probe the hwif now */
probe_hwif_init(hwif);
- /* The code IDE code will have set hwif->present if we have devices attached,
- * if we don't, the discard the interface except if we are on a media bay slot
- */
- if (!hwif->present && !pmif->mediabay) {
- printk(KERN_INFO "ide%d: Bus empty, interface released.\n",
- hwif->index);
- default_hwif_iops(hwif);
- for (i = IDE_DATA_OFFSET; i <= IDE_CONTROL_OFFSET; ++i)
- hwif->io_ports[i] = 0;
- hwif->chipset = ide_unknown;
- hwif->noprobe = 1;
- return -ENODEV;
- }
-
return 0;
}
* Attach to a macio probed interface
*/
static int __devinit
-pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match)
+pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
- unsigned long base, regbase;
+ void __iomem *base;
+ unsigned long regbase;
int irq;
ide_hwif_t *hwif;
pmac_ide_hwif_t *pmif;
pmif = &pmac_ide[i];
hwif = &ide_hwifs[i];
- if (mdev->ofdev.node->n_addrs == 0) {
+ if (macio_resource_count(mdev) == 0) {
printk(KERN_WARNING "ide%d: no address for %s\n",
i, mdev->ofdev.node->full_name);
return -ENXIO;
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 = (unsigned long)ioremap(macio_resource_start(mdev, 0), 0x400);
- regbase = base;
+ base = ioremap(macio_resource_start(mdev, 0), 0x400);
+ regbase = (unsigned long) base;
hwif->pci_dev = mdev->bus->pdev;
hwif->gendev.parent = &mdev->ofdev.dev;
pmif->node = mdev->ofdev.node;
pmif->regbase = regbase;
pmif->irq = irq;
+ pmif->kauai_fcr = NULL;
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
if (macio_resource_count(mdev) >= 2) {
if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))
printk(KERN_WARNING "ide%d: can't request DMA resource !\n", i);
else
- pmif->dma_regs = (volatile struct dbdma_regs*)
- ioremap(macio_resource_start(mdev, 1), 0x1000);
+ pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);
} else
pmif->dma_regs = NULL;
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
if (rc != 0) {
/* The inteface is released to the common IDE layer */
dev_set_drvdata(&mdev->ofdev.dev, NULL);
- iounmap((void *)base);
+ iounmap(base);
if (pmif->dma_regs)
- iounmap((void *)pmif->dma_regs);
+ iounmap(pmif->dma_regs);
memset(pmif, 0, sizeof(*pmif));
macio_release_resource(mdev, 0);
if (pmif->dma_regs)
}
static int
-pmac_ide_macio_suspend(struct macio_dev *mdev, u32 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 != mdev->ofdev.dev.power_state && state >= 2) {
+ if (mesg.event != mdev->ofdev.dev.power.power_state.event
+ && mesg.event == PM_EVENT_SUSPEND) {
rc = pmac_ide_do_suspend(hwif);
if (rc == 0)
- mdev->ofdev.dev.power_state = state;
+ mdev->ofdev.dev.power.power_state = mesg;
}
return rc;
ide_hwif_t *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
int rc = 0;
- if (mdev->ofdev.dev.power_state != 0) {
+ if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
rc = pmac_ide_do_resume(hwif);
if (rc == 0)
- mdev->ofdev.dev.power_state = 0;
+ mdev->ofdev.dev.power.power_state = PMSG_ON;
}
return rc;
ide_hwif_t *hwif;
struct device_node *np;
pmac_ide_hwif_t *pmif;
- unsigned long base;
+ void __iomem *base;
unsigned long rbase, rlen;
int i, rc;
rbase = pci_resource_start(pdev, 0);
rlen = pci_resource_len(pdev, 0);
- base = (unsigned long) ioremap(rbase, rlen);
- pmif->regbase = base + 0x2000;
+ base = ioremap(rbase, rlen);
+ pmif->regbase = (unsigned long) base + 0x2000;
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
- pmif->dma_regs = (volatile struct dbdma_regs*)(base + 0x1000);
-#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
-
- /* We use the OF node irq mapping */
- if (np->n_intrs == 0)
- pmif->irq = pdev->irq;
- else
- pmif->irq = np->intrs[0].line;
+ pmif->dma_regs = base + 0x1000;
+#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
+ pmif->kauai_fcr = base;
+ pmif->irq = pdev->irq;
pci_set_drvdata(pdev, hwif);
if (rc != 0) {
/* The inteface is released to the common IDE layer */
pci_set_drvdata(pdev, NULL);
- iounmap((void *)base);
+ iounmap(base);
memset(pmif, 0, sizeof(*pmif));
pci_release_regions(pdev);
}
}
static int
-pmac_ide_pci_suspend(struct pci_dev *pdev, u32 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 != pdev->dev.power_state && state >= 2) {
+ if (mesg.event != pdev->dev.power.power_state.event
+ && mesg.event == PM_EVENT_SUSPEND) {
rc = pmac_ide_do_suspend(hwif);
if (rc == 0)
- pdev->dev.power_state = state;
+ pdev->dev.power.power_state = mesg;
}
return rc;
ide_hwif_t *hwif = (ide_hwif_t *)pci_get_drvdata(pdev);
int rc = 0;
- if (pdev->dev.power_state != 0) {
+ if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
rc = pmac_ide_do_resume(hwif);
if (rc == 0)
- pdev->dev.power_state = 0;
+ pdev->dev.power.power_state = PMSG_ON;
}
return rc;
}
-static struct of_match pmac_ide_macio_match[] =
+static struct of_device_id pmac_ide_macio_match[] =
{
{
.name = "IDE",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
.name = "ATA",
- .type = OF_ANY_MATCH,
- .compatible = OF_ANY_MATCH
},
{
- .name = OF_ANY_MATCH,
.type = "ide",
- .compatible = OF_ANY_MATCH
},
{
- .name = OF_ANY_MATCH,
.type = "ata",
- .compatible = OF_ANY_MATCH
},
{},
};
};
static struct pci_device_id pmac_ide_pci_match[] = {
- { PCI_VENDOR_ID_APPLE, PCI_DEVIEC_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_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 struct pci_driver pmac_ide_pci_driver = {
.suspend = pmac_ide_pci_suspend,
.resume = pmac_ide_pci_resume,
};
+MODULE_DEVICE_TABLE(pci, pmac_ide_pci_match);
void __init
pmac_ide_probe(void)
{
- if (_machine != _MACH_Pmac)
+ if (!machine_is(powermac))
return;
#ifdef CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST
#else
macio_register_driver(&pmac_ide_macio_driver);
pci_register_driver(&pmac_ide_pci_driver);
-#endif
+#endif
}
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
-/*
- * This is very close to the generic ide-dma version of the function except
- * that we don't use the fields in the hwif but our own copies for sg_table
- * and friends. We build & map the sglist for a given request
- */
-static int __pmac
-pmac_ide_build_sglist(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = HWIF(drive);
- pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
- struct scatterlist *sg = pmif->sg_table;
- int nents;
-
- if (hwif->sg_dma_active)
- BUG();
-
- nents = blk_rq_map_sg(drive->queue, rq, sg);
-
- if (rq_data_dir(rq) == READ)
- pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
- else
- pmif->sg_dma_direction = PCI_DMA_TODEVICE;
-
- return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
-}
-
-/*
- * Same as above but for a "raw" taskfile request
- */
-static int __pmac
-pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = HWIF(drive);
- pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
- struct scatterlist *sg = pmif->sg_table;
- int nents = 0;
- ide_task_t *args = rq->special;
- unsigned char *virt_addr = rq->buffer;
- int sector_count = rq->nr_sectors;
-
- if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
- pmif->sg_dma_direction = PCI_DMA_TODEVICE;
- else
- pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-
- if (sector_count > 128) {
- memset(&sg[nents], 0, sizeof(*sg));
- sg[nents].page = virt_to_page(virt_addr);
- sg[nents].offset = offset_in_page(virt_addr);
- sg[nents].length = 128 * SECTOR_SIZE;
- nents++;
- virt_addr = virt_addr + (128 * SECTOR_SIZE);
- sector_count -= 128;
- }
- memset(&sg[nents], 0, sizeof(*sg));
- sg[nents].page = virt_to_page(virt_addr);
- sg[nents].offset = offset_in_page(virt_addr);
- sg[nents].length = sector_count * SECTOR_SIZE;
- nents++;
-
- return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
-}
-
/*
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
-static int __pmac
+static int
pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
{
struct dbdma_cmd *table;
int i, count = 0;
ide_hwif_t *hwif = HWIF(drive);
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
- volatile struct dbdma_regs *dma = pmif->dma_regs;
+ volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
struct scatterlist *sg;
int wr = (rq_data_dir(rq) == WRITE);
while (readl(&dma->status) & RUN)
udelay(1);
- /* Build sglist */
- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
- pmif->sg_nents = i = pmac_ide_raw_build_sglist(drive, rq);
- else
- pmif->sg_nents = i = pmac_ide_build_sglist(drive, rq);
+ hwif->sg_nents = i = ide_build_sglist(drive, rq);
+
if (!i)
return 0;
/* Build DBDMA commands list */
- sg = pmif->sg_table;
+ sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
u32 cur_addr;
u32 cur_len;
memset(table, 0, sizeof(struct dbdma_cmd));
st_le16(&table->command, DBDMA_STOP);
mb();
- writel(pmif->dma_table_dma, &dma->cmdptr);
+ writel(hwif->dmatable_dma, &dma->cmdptr);
return 1;
}
printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
use_pio_instead:
pci_unmap_sg(hwif->pci_dev,
- pmif->sg_table,
- pmif->sg_nents,
- pmif->sg_dma_direction);
- hwif->sg_dma_active = 0;
+ hwif->sg_table,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
return 0; /* revert to PIO for this request */
}
/* Teardown mappings after DMA has completed. */
-static void __pmac
+static void
pmac_ide_destroy_dmatable (ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = HWIF(drive)->pci_dev;
- pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
- struct scatterlist *sg = pmif->sg_table;
- int nents = pmif->sg_nents;
+ struct scatterlist *sg = hwif->sg_table;
+ int nents = hwif->sg_nents;
if (nents) {
- pci_unmap_sg(dev, sg, nents, pmif->sg_dma_direction);
- pmif->sg_nents = 0;
- HWIF(drive)->sg_dma_active = 0;
+ pci_unmap_sg(dev, sg, nents, hwif->sg_dma_direction);
+ hwif->sg_nents = 0;
}
}
/*
* Pick up best MDMA timing for the drive and apply it
*/
-static int __pmac
+static int
pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
{
ide_hwif_t *hwif = HWIF(drive);
/*
* Pick up best UDMA timing for the drive and apply it
*/
-static int __pmac
+static int
pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
{
ide_hwif_t *hwif = HWIF(drive);
timing_local[1] = *timings2;
/* Calculate timings for interface */
- if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6)
+ 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)
* Check what is the best DMA timing setting for the drive and
* call appropriate functions to apply it.
*/
-static int __pmac
+static int
pmac_ide_dma_check(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
short mode;
map = XFER_MWDMA;
- if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6
- || pmif->kind == controller_k2_ata6) {
+ 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_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);
* 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
*/
-static int __pmac
-pmac_ide_dma_start(ide_drive_t *drive, int reading)
+static int
+pmac_ide_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
return 1;
ata4 = (pmif->kind == controller_kl_ata4);
- if (!pmac_ide_build_dmatable(drive, rq))
+ if (!pmac_ide_build_dmatable(drive, rq)) {
+ ide_map_sg(drive, rq);
return 1;
+ }
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
- writel(pmif->timings[unit] + (reading ? 0x00800000UL : 0),
- (unsigned *)(IDE_DATA_REG+IDE_TIMING_CONFIG));
- (void)readl((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG));
+ writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
+ PMAC_IDE_REG(IDE_TIMING_CONFIG));
+ (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
drive->waiting_for_dma = 1;
return 0;
}
-/*
- * Start a DMA READ command
- */
-static int __pmac
-pmac_ide_dma_read(ide_drive_t *drive)
+static void
+pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
- struct request *rq = HWGROUP(drive)->rq;
- u8 lba48 = (drive->addressing == 1) ? 1 : 0;
- task_ioreg_t command = WIN_NOP;
-
- if (pmac_ide_dma_start(drive, 1))
- return 1;
-
- if (drive->media != ide_disk)
- return 0;
-
- command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
-
- if (drive->vdma)
- command = (lba48) ? WIN_READ_EXT: WIN_READ;
-
- if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *args = rq->special;
- command = args->tfRegister[IDE_COMMAND_OFFSET];
- }
-
/* issue cmd to drive */
ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-
- return pmac_ide_dma_begin(drive);
-}
-
-/*
- * Start a DMA WRITE command
- */
-static int __pmac
-pmac_ide_dma_write (ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
- u8 lba48 = (drive->addressing == 1) ? 1 : 0;
- task_ioreg_t command = WIN_NOP;
-
- if (pmac_ide_dma_start(drive, 0))
- return 1;
-
- if (drive->media != ide_disk)
- return 0;
-
- command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
- if (drive->vdma)
- command = (lba48) ? WIN_WRITE_EXT: WIN_WRITE;
-
- if (rq->flags & REQ_DRIVE_TASKFILE) {
- ide_task_t *args = rq->special;
- command = args->tfRegister[IDE_COMMAND_OFFSET];
- }
-
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-
- return pmac_ide_dma_begin(drive);
}
/*
* Kick the DMA controller into life after the DMA command has been issued
* to the drive.
*/
-static int __pmac
-pmac_ide_dma_begin (ide_drive_t *drive)
+static void
+pmac_ide_dma_start(ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
- volatile struct dbdma_regs *dma;
+ volatile struct dbdma_regs __iomem *dma;
- if (pmif == NULL)
- return 1;
dma = pmif->dma_regs;
writel((RUN << 16) | RUN, &dma->control);
/* Make sure it gets to the controller right now */
(void)readl(&dma->control);
- return 0;
}
/*
* After a DMA transfer, make sure the controller is stopped
*/
-static int __pmac
+static int
pmac_ide_dma_end (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
- volatile struct dbdma_regs *dma;
+ volatile struct dbdma_regs __iomem *dma;
u32 dstat;
if (pmif == NULL)
* that's not implemented yet), on the other hand, we don't have shared interrupts
* so it's not really a problem
*/
-static int __pmac
+static int
pmac_ide_dma_test_irq (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
- volatile struct dbdma_regs *dma;
+ volatile struct dbdma_regs __iomem *dma;
unsigned long status, timeout;
if (pmif == NULL)
return 1;
}
-static int __pmac
+static int
pmac_ide_dma_host_off (ide_drive_t *drive)
{
return 0;
}
-static int __pmac
+static int
pmac_ide_dma_host_on (ide_drive_t *drive)
{
return 0;
}
-static int __pmac
+static int
pmac_ide_dma_lostirq (ide_drive_t *drive)
{
pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
- volatile struct dbdma_regs *dma;
+ volatile struct dbdma_regs __iomem *dma;
unsigned long status;
if (pmif == NULL)
pmif->dma_table_cpu = (struct dbdma_cmd*)pci_alloc_consistent(
hwif->pci_dev,
(MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
- &pmif->dma_table_dma);
+ &hwif->dmatable_dma);
if (pmif->dma_table_cpu == NULL) {
printk(KERN_ERR "%s: unable to allocate DMA command list\n",
hwif->name);
return;
}
- pmif->sg_table = kmalloc(sizeof(struct scatterlist) * MAX_DCMDS,
- GFP_KERNEL);
- if (pmif->sg_table == NULL) {
- pci_free_consistent( hwif->pci_dev,
- (MAX_DCMDS + 2) * sizeof(struct dbdma_cmd),
- pmif->dma_table_cpu, pmif->dma_table_dma);
- return;
- }
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->ide_dma_read = &pmac_ide_dma_read;
- hwif->ide_dma_write = &pmac_ide_dma_write;
- hwif->ide_dma_begin = &pmac_ide_dma_begin;
+ 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_verbose = &__ide_dma_verbose;
hwif->ide_dma_timeout = &__ide_dma_timeout;
hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
-#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO
- if (!noautodma)
- hwif->autodma = 1;
-#endif
- hwif->drives[0].autodma = hwif->autodma;
- hwif->drives[1].autodma = hwif->autodma;
-
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;