aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/Kconfig10
-rw-r--r--drivers/ide/ide-cd.c7
-rw-r--r--drivers/ide/ide-cd.h1
-rw-r--r--drivers/ide/ide-disk.c4
-rw-r--r--drivers/ide/ide-dma.c15
-rw-r--r--drivers/ide/mips/Makefile3
-rw-r--r--drivers/ide/mips/au1xxx-ide.c1498
-rw-r--r--drivers/ide/pci/sgiioc4.c8
-rw-r--r--drivers/ide/pci/via82cxxx.c1
-rw-r--r--include/asm-mips/mach-au1x00/au1xxx_ide.h22
-rw-r--r--include/linux/ide.h131
-rw-r--r--include/linux/pci_ids.h1
12 files changed, 567 insertions, 1134 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 31e649a9ff7..1c81174595b 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -807,14 +807,6 @@ config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
endchoice
-config BLK_DEV_IDE_AU1XXX_BURSTABLE_ON
- bool "Enable burstable Mode on DbDMA"
- default false
- depends BLK_DEV_IDE_AU1XXX
- help
- This option enable the burstable Flag on DbDMA controller
- (cf. "AMD Alchemy 'Au1200' Processor Data Book - PRELIMINARY").
-
config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ
int "Maximum transfer size (KB) per request (up to 128)"
default "128"
@@ -940,7 +932,7 @@ config BLK_DEV_Q40IDE
config BLK_DEV_MPC8xx_IDE
bool "MPC8xx IDE support"
- depends on 8xx
+ depends on 8xx && IDE=y && BLK_DEV_IDE=y
help
This option provides support for IDE on Motorola MPC8xx Systems.
Please see 'Type of MPC8xx IDE interface' for details.
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 9455e42abb2..b4d7a3efb90 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -1292,7 +1292,6 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- info->cmd = 0;
info->start_seek = jiffies;
return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
}
@@ -1344,8 +1343,6 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
(rq->nr_sectors & (sectors_per_frame - 1)))
info->dma = 0;
- info->cmd = READ;
-
/* Start sending the read request to the drive. */
return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
}
@@ -1484,7 +1481,6 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
struct cdrom_info *info = drive->driver_data;
info->dma = 0;
- info->cmd = 0;
rq->flags &= ~REQ_FAILED;
len = rq->data_len;
@@ -1891,7 +1887,6 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
/* use dma, if possible. we don't need to check more, since we
* know that the transfer is always (at least!) frame aligned */
info->dma = drive->using_dma ? 1 : 0;
- info->cmd = WRITE;
info->devinfo.media_written = 1;
@@ -1916,7 +1911,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
rq->flags |= REQ_QUIET;
info->dma = 0;
- info->cmd = 0;
/*
* sg request
@@ -1925,7 +1919,6 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
int mask = drive->queue->dma_alignment;
unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
- info->cmd = rq_data_dir(rq);
info->dma = drive->using_dma;
/*
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 7ca3e5afc66..ad1f2ed14a3 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -480,7 +480,6 @@ struct cdrom_info {
struct request request_sense_request;
int dma;
- int cmd;
unsigned long last_block;
unsigned long start_seek;
/* Buffer to hold mechanism status and changer slot table. */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index f4e3d3527b0..449522f0540 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -1034,12 +1034,12 @@ static int ide_disk_remove(struct device *dev)
struct ide_disk_obj *idkp = drive->driver_data;
struct gendisk *g = idkp->disk;
- ide_cacheflush_p(drive);
-
ide_unregister_subdriver(drive, idkp->driver);
del_gendisk(g);
+ ide_cacheflush_p(drive);
+
ide_disk_put(idkp);
return 0;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 1e1531334c2..0523da77425 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -90,11 +90,6 @@
#include <asm/io.h>
#include <asm/irq.h>
-struct drive_list_entry {
- const char *id_model;
- const char *id_firmware;
-};
-
static const struct drive_list_entry drive_whitelist [] = {
{ "Micropolis 2112A" , "ALL" },
@@ -139,7 +134,7 @@ static const struct drive_list_entry drive_blacklist [] = {
};
/**
- * in_drive_list - look for drive in black/white list
+ * ide_in_drive_list - look for drive in black/white list
* @id: drive identifier
* @drive_table: list to inspect
*
@@ -147,7 +142,7 @@ static const struct drive_list_entry drive_blacklist [] = {
* Returns 1 if the drive is found in the table.
*/
-static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
+int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
{
for ( ; drive_table->id_model ; drive_table++)
if ((!strcmp(drive_table->id_model, id->model)) &&
@@ -157,6 +152,8 @@ static int in_drive_list(struct hd_driveid *id, const struct drive_list_entry *d
return 0;
}
+EXPORT_SYMBOL_GPL(ide_in_drive_list);
+
/**
* ide_dma_intr - IDE DMA interrupt handler
* @drive: the drive the interrupt is for
@@ -663,7 +660,7 @@ int __ide_dma_bad_drive (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- int blacklist = in_drive_list(id, drive_blacklist);
+ int blacklist = ide_in_drive_list(id, drive_blacklist);
if (blacklist) {
printk(KERN_WARNING "%s: Disabling (U)DMA for %s (blacklisted)\n",
drive->name, id->model);
@@ -677,7 +674,7 @@ EXPORT_SYMBOL(__ide_dma_bad_drive);
int __ide_dma_good_drive (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
- return in_drive_list(id, drive_whitelist);
+ return ide_in_drive_list(id, drive_whitelist);
}
EXPORT_SYMBOL(__ide_dma_good_drive);
diff --git a/drivers/ide/mips/Makefile b/drivers/ide/mips/Makefile
index 578e52a5958..677c7b2bac9 100644
--- a/drivers/ide/mips/Makefile
+++ b/drivers/ide/mips/Makefile
@@ -1 +1,4 @@
obj-$(CONFIG_BLK_DEV_IDE_SWARM) += swarm.o
+obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
+
+EXTRA_CFLAGS := -Idrivers/ide
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 2b6327c576b..32431dcf5d8 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -31,865 +31,638 @@
*/
#undef REALLY_SLOW_IO /* most systems can safely undef this */
-#include <linux/config.h> /* for CONFIG_BLK_DEV_IDEPCI */
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/hdreg.h>
+#include <linux/platform_device.h>
+
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/sysdev.h>
#include <linux/dma-mapping.h>
+#include "ide-timing.h"
+
#include <asm/io.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#if CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
#include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide"
#define DRV_VERSION "1.0"
-#define DRV_AUTHOR "AMD PCS / Pete Popov <ppopov@embeddedalley.com>"
-#define DRV_DESC "Au1200 IDE"
-
-static _auide_hwif auide_hwif;
-static spinlock_t ide_tune_drive_spin_lock = SPIN_LOCK_UNLOCKED;
-static spinlock_t ide_tune_chipset_spin_lock = SPIN_LOCK_UNLOCKED;
-static int dbdma_init_done = 0;
-
-/*
- * local I/O functions
- */
-u8 auide_inb(unsigned long port)
-{
- return (au_readb(port));
-}
+#define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
-u16 auide_inw(unsigned long port)
-{
- return (au_readw(port));
-}
+/* enable the burstmode in the dbdma */
+#define IDE_AU1XXX_BURSTMODE 1
-u32 auide_inl(unsigned long port)
-{
- return (au_readl(port));
-}
+static _auide_hwif auide_hwif;
+static int dbdma_init_done;
-void auide_insw(unsigned long port, void *addr, u32 count)
-{
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- _auide_hwif *ahwif = &auide_hwif;
- chan_tab_t *ctp;
- au1x_ddma_desc_t *dp;
-
- if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
- DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
- return;
- }
- ctp = *((chan_tab_t **)ahwif->rx_chan);
- dp = ctp->cur_ptr;
- while (dp->dscr_cmd0 & DSCR_CMD0_V)
- ;
- ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
- while (count--)
- {
- *(u16 *)addr = au_readw(port);
- addr +=2 ;
- }
-#endif
-}
-
-void auide_insl(unsigned long port, void *addr, u32 count)
-{
- while (count--)
- {
- *(u32 *)addr = au_readl(port);
- /* NOTE: For IDE interfaces over PCMCIA,
- * 32-bit access does not work
- */
- addr += 4;
- }
-}
-
-void auide_outb(u8 addr, unsigned long port)
+void auide_insw(unsigned long port, void *addr, u32 count)
{
- return (au_writeb(addr, port));
-}
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
-void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port)
-{
- return (au_writeb(addr, port));
+ if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
+ DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->rx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outw(u16 addr, unsigned long port)
+void auide_outsw(unsigned long port, void *addr, u32 count)
{
- return (au_writew(addr, port));
-}
+ _auide_hwif *ahwif = &auide_hwif;
+ chan_tab_t *ctp;
+ au1x_ddma_desc_t *dp;
-void auide_outl(u32 addr, unsigned long port)
-{
- return (au_writel(addr, port));
+ if(!put_source_flags(ahwif->tx_chan, (void*)addr,
+ count << 1, DDMA_FLAGS_NOIE)) {
+ printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+ ctp = *((chan_tab_t **)ahwif->tx_chan);
+ dp = ctp->cur_ptr;
+ while (dp->dscr_cmd0 & DSCR_CMD0_V)
+ ;
+ ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outsw(unsigned long port, void *addr, u32 count)
-{
-#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
- _auide_hwif *ahwif = &auide_hwif;
- chan_tab_t *ctp;
- au1x_ddma_desc_t *dp;
-
- if(!put_source_flags(ahwif->tx_chan, (void*)addr,
- count << 1, DDMA_FLAGS_NOIE)) {
- printk(KERN_ERR "%s failed %d\n", __FUNCTION__, __LINE__);
- return;
- }
- ctp = *((chan_tab_t **)ahwif->tx_chan);
- dp = ctp->cur_ptr;
- while (dp->dscr_cmd0 & DSCR_CMD0_V)
- ;
- ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
-#else
- while (count--)
- {
- au_writew(*(u16 *)addr, port);
- addr += 2;
- }
#endif
-}
-
-void auide_outsl(unsigned long port, void *addr, u32 count)
-{
- while (count--)
- {
- au_writel(*(u32 *)addr, port);
- /* NOTE: For IDE interfaces over PCMCIA,
- * 32-bit access does not work
- */
- addr += 4;
- }
-}
static void auide_tune_drive(ide_drive_t *drive, byte pio)
{
- int mem_sttime;
- int mem_stcfg;
- unsigned long flags;
- u8 speed;
-
- /* get the best pio mode for the drive */
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-
- printk("%s: setting Au1XXX IDE to PIO mode%d\n",
- drive->name, pio);
-
- spin_lock_irqsave(&ide_tune_drive_spin_lock, flags);
-
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
-
- /* set pio mode! */
- switch(pio) {
- case 0:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO0_TWCS
- | SBC_IDE_PIO0_TCSH
- | SBC_IDE_PIO0_TCSOFF
- | SBC_IDE_PIO0_TWP
- | SBC_IDE_PIO0_TCSW
- | SBC_IDE_PIO0_TPM
- | SBC_IDE_PIO0_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
- break;
-
- case 1:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO1_TWCS
- | SBC_IDE_PIO1_TCSH
- | SBC_IDE_PIO1_TCSOFF
- | SBC_IDE_PIO1_TWP
- | SBC_IDE_PIO1_TCSW
- | SBC_IDE_PIO1_TPM
- | SBC_IDE_PIO1_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
- break;
-
- case 2:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO2_TWCS
- | SBC_IDE_PIO2_TCSH
- | SBC_IDE_PIO2_TCSOFF
- | SBC_IDE_PIO2_TWP
- | SBC_IDE_PIO2_TCSW
- | SBC_IDE_PIO2_TPM
- | SBC_IDE_PIO2_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
- break;
-
- case 3:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO3_TWCS
- | SBC_IDE_PIO3_TCSH
- | SBC_IDE_PIO3_TCSOFF
- | SBC_IDE_PIO3_TWP
- | SBC_IDE_PIO3_TCSW
- | SBC_IDE_PIO3_TPM
- | SBC_IDE_PIO3_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
-
- break;
-
- case 4:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_PIO4_TWCS
- | SBC_IDE_PIO4_TCSH
- | SBC_IDE_PIO4_TCSOFF
- | SBC_IDE_PIO4_TWP
- | SBC_IDE_PIO4_TCSW
- | SBC_IDE_PIO4_TPM
- | SBC_IDE_PIO4_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
- break;
- }
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
-
- spin_unlock_irqrestore(&ide_tune_drive_spin_lock, flags);
-
- speed = pio + XFER_PIO_0;
- ide_config_drive_speed(drive, speed);
+ int mem_sttime;
+ int mem_stcfg;
+ u8 speed;
+
+ /* get the best pio mode for the drive */
+ pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
+
+ printk(KERN_INFO "%s: setting Au1XXX IDE to PIO mode%d\n",
+ drive->name, pio);
+
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
+
+ /* set pio mode! */
+ switch(pio) {
+ case 0:
+ mem_sttime = SBC_IDE_TIMING(PIO0);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO0_TCSOE | SBC_IDE_PIO0_TOECS;
+ break;
+
+ case 1:
+ mem_sttime = SBC_IDE_TIMING(PIO1);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO1_TCSOE | SBC_IDE_PIO1_TOECS;
+ break;
+
+ case 2:
+ mem_sttime = SBC_IDE_TIMING(PIO2);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO2_TCSOE | SBC_IDE_PIO2_TOECS;
+ break;
+
+ case 3:
+ mem_sttime = SBC_IDE_TIMING(PIO3);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO3_TCSOE | SBC_IDE_PIO3_TOECS;
+
+ break;
+
+ case 4:
+ mem_sttime = SBC_IDE_TIMING(PIO4);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_PIO4_TCSOE | SBC_IDE_PIO4_TOECS;
+ break;
+ }
+
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
+
+ speed = pio + XFER_PIO_0;
+ ide_config_drive_speed(drive, speed);
}
static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
{
- u8 mode = 0;
- int mem_sttime;
- int mem_stcfg;
- unsigned long flags;
+ int mem_sttime;
+ int mem_stcfg;
+ unsigned long mode;
+
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- struct hd_driveid *id = drive->id;
-
- /*
- * Now see what the current drive is capable of,
- * selecting UDMA only if the mate said it was ok.
- */
- if (id && (id->capability & 1) && drive->autodma &&
- !__ide_dma_bad_drive(drive)) {
- if (!mode && (id->field_valid & 2) && (id->dma_mword & 7)) {
- if (id->dma_mword & 4)
- mode = XFER_MW_DMA_2;
- else if (id->dma_mword & 2)
- mode = XFER_MW_DMA_1;
- else if (id->dma_mword & 1)
- mode = XFER_MW_DMA_0;
- }
- }
+ if (ide_use_dma(drive))
+ mode = ide_dma_speed(drive, 0);
#endif
- spin_lock_irqsave(&ide_tune_chipset_spin_lock, flags);
+ mem_sttime = 0;
+ mem_stcfg = au_readl(MEM_STCFG2);
- mem_sttime = 0;
- mem_stcfg = au_readl(MEM_STCFG2);
-
- switch(speed) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- auide_tune_drive(drive, (speed - XFER_PIO_0));
- break;
+ if (speed >= XFER_PIO_0 && speed <= XFER_PIO_4) {
+ auide_tune_drive(drive, speed - XFER_PIO_0);
+ return 0;
+ }
+
+ switch(speed) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
- case XFER_MW_DMA_2:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA2_TWCS
- | SBC_IDE_MDMA2_TCSH
- | SBC_IDE_MDMA2_TCSOFF
- | SBC_IDE_MDMA2_TWP
- | SBC_IDE_MDMA2_TCSW
- | SBC_IDE_MDMA2_TPM
- | SBC_IDE_MDMA2_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
-
- mode = XFER_MW_DMA_2;
- break;
- case XFER_MW_DMA_1:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA1_TWCS
- | SBC_IDE_MDMA1_TCSH
- | SBC_IDE_MDMA1_TCSOFF
- | SBC_IDE_MDMA1_TWP
- | SBC_IDE_MDMA1_TCSW
- | SBC_IDE_MDMA1_TPM
- | SBC_IDE_MDMA1_TA;
- /* set configuration for RCS2# */
- mem_stcfg &= ~TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
-
- mode = XFER_MW_DMA_1;
- break;
- case XFER_MW_DMA_0:
- /* set timing parameters for RCS2# */
- mem_sttime = SBC_IDE_MDMA0_TWCS
- | SBC_IDE_MDMA0_TCSH
- | SBC_IDE_MDMA0_TCSOFF
- | SBC_IDE_MDMA0_TWP
- | SBC_IDE_MDMA0_TCSW
- | SBC_IDE_MDMA0_TPM
- | SBC_IDE_MDMA0_TA;
- /* set configuration for RCS2# */
- mem_stcfg |= TS_MASK;
- mem_stcfg &= ~TCSOE_MASK;
- mem_stcfg &= ~TOECS_MASK;
- mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
-
- mode = XFER_MW_DMA_0;
- break;
+ case XFER_MW_DMA_2:
+ mem_sttime = SBC_IDE_TIMING(MDMA2);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
+
+ mode = XFER_MW_DMA_2;
+ break;
+ case XFER_MW_DMA_1:
+ mem_sttime = SBC_IDE_TIMING(MDMA1);
+
+ /* set configuration for RCS2# */
+ mem_stcfg &= ~TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
+
+ mode = XFER_MW_DMA_1;
+ break;
+ case XFER_MW_DMA_0:
+ mem_sttime = SBC_IDE_TIMING(MDMA0);
+
+ /* set configuration for RCS2# */
+ mem_stcfg |= TS_MASK;
+ mem_stcfg &= ~TCSOE_MASK;
+ mem_stcfg &= ~TOECS_MASK;
+ mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
+
+ mode = XFER_MW_DMA_0;
+ break;
#endif
- default:
- return 1;
- }
-
- /*
- * Tell the drive to switch to the new mode; abort on failure.
- */
- if (!mode || ide_config_drive_speed(drive, mode))
- {
- return 1; /* failure */
- }
-
-
- au_writel(mem_sttime,MEM_STTIME2);
- au_writel(mem_stcfg,MEM_STCFG2);
+ default:
+ return 1;
+ }
+
+ if (ide_config_drive_speed(drive, mode))
+ return 1;
- spin_unlock_irqrestore(&ide_tune_chipset_spin_lock, flags);
+ au_writel(mem_sttime,MEM_STTIME2);
+ au_writel(mem_stcfg,MEM_STCFG2);
- return 0;
+ return 0;
}
/*
* Multi-Word DMA + DbDMA functions
*/
-#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int in_drive_list(struct hd_driveid *id,
- const struct drive_list_entry *drive_table)
-{
- for ( ; drive_table->id_model ; drive_table++){
- if ((!strcmp(drive_table->id_model, id->model)) &&
- ((strstr(drive_table->id_firmware, id->fw_rev)) ||
- (!strcmp(drive_table->id_firmware, "ALL")))
- )
- return 1;
- }
- return 0;
-}
+#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
static int auide_build_sglist(ide_drive_t *drive, struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- struct scatterlist *sg = hwif->sg_table;
+ ide_hwif_t *hwif = drive->hwif;
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg = hwif->sg_table;
- ide_map_sg(drive, rq);
+ ide_map_sg(drive, rq);
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
- else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
+ if (rq_data_dir(rq) == READ)
+ hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ else
+ hwif->sg_dma_direction = DMA_TO_DEVICE;
- return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
- hwif->sg_dma_direction);
+ return dma_map_sg(ahwif->dev, sg, hwif->sg_nents,
+ hwif->sg_dma_direction);
}
static int auide_build_dmatable(ide_drive_t *drive)
{
- int i, iswrite, count = 0;
- ide_hwif_t *hwif = HWIF(drive);
-
- struct request *rq = HWGROUP(drive)->rq;
-
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- struct scatterlist *sg;
-
- iswrite = (rq_data_dir(rq) == WRITE);
- /* Save for interrupt context */
- ahwif->drive = drive;
-
- /* Build sglist */
- hwif->sg_nents = i = auide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
- /* fill the descriptors */
- sg = hwif->sg_table;
- while (i && sg_dma_len(sg)) {
- u32 cur_addr;
- u32 cur_len;
-
- cur_addr = sg_dma_address(sg);
- cur_len = sg_dma_len(sg);
-
- while (cur_len) {
- u32 flags = DDMA_FLAGS_NOIE;
- unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
-
- if (++count >= PRD_ENTRIES) {
- printk(KERN_WARNING "%s: DMA table too small\n",
- drive->name);
- goto use_pio_instead;
- }
-
- /* Lets enable intr for the last descriptor only */
- if (1==i)
- flags = DDMA_FLAGS_IE;
- else
- flags = DDMA_FLAGS_NOIE;
-
- if (iswrite) {
- if(!put_source_flags(ahwif->tx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
- tc, flags)) {
- printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ int i, iswrite, count = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+
+ struct request *rq = HWGROUP(drive)->rq;
+
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ struct scatterlist *sg;
+
+ iswrite = (rq_data_dir(rq) == WRITE);
+ /* Save for interrupt context */
+ ahwif->drive = drive;
+
+ /* Build sglist */
+ hwif->sg_nents = i = auide_build_sglist(drive, rq);
+
+ if (!i)
+ return 0;
+
+ /* fill the descriptors */
+ sg = hwif->sg_table;
+ while (i && sg_dma_len(sg)) {
+ u32 cur_addr;
+ u32 cur_len;
+
+ cur_addr = sg_dma_address(sg);
+ cur_len = sg_dma_len(sg);
+
+ while (cur_len) {
+ u32 flags = DDMA_FLAGS_NOIE;
+ unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
+
+ if (++count >= PRD_ENTRIES) {
+ printk(KERN_WARNING "%s: DMA table too small\n",
+ drive->name);
+ goto use_pio_instead;
+ }
+
+ /* Lets enable intr for the last descriptor only */
+ if (1==i)
+ flags = DDMA_FLAGS_IE;
+ else
+ flags = DDMA_FLAGS_NOIE;
+
+ if (iswrite) {
+ if(!put_source_flags(ahwif->tx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
}
- } else
+ } else
{
- if(!put_dest_flags(ahwif->rx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
- tc, flags)) {
- printk(KERN_ERR "%s failed %d\n",
- __FUNCTION__, __LINE__);
+ if(!put_dest_flags(ahwif->rx_chan,
+ (void*)(page_address(sg->page)
+ + sg->offset),
+ tc, flags)) {
+ printk(KERN_ERR "%s failed %d\n",
+ __FUNCTION__, __LINE__);
}
- }
+ }
- cur_addr += tc;
- cur_len -= tc;
- }
- sg++;
- i--;
- }
+ cur_addr += tc;
+ cur_len -= tc;
+ }
+ sg++;
+ i--;
+ }
- if (count)
- return 1;
+ if (count)
+ return 1;
-use_pio_instead:
- dma_unmap_sg(ahwif->dev,
- hwif->sg_table,
- hwif->sg_nents,
- hwif->sg_dma_direction);
+ use_pio_instead:
+ dma_unmap_sg(ahwif->dev,
+ hwif->sg_table,
+ hwif->sg_nents,
+ hwif->sg_dma_direction);
- return 0; /* revert to PIO for this request */
+ return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
+ ide_hwif_t *hwif = HWIF(drive);
+ _auide_hwif *ahwif = (_auide_hwif*)hwif->hwif_data;
- if (hwif->sg_nents) {
- dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
- hwif->sg_dma_direction);
- hwif->sg_nents = 0;
- }
+ if (hwif->sg_nents) {
+ dma_unmap_sg(ahwif->dev, hwif->sg_table, hwif->sg_nents,
+ hwif->sg_dma_direction);
+ hwif->sg_nents = 0;
+ }
- return 0;
+ return 0;
}
static void auide_dma_start(ide_drive_t *drive )
{
-// printk("%s\n", __FUNCTION__);
}
-ide_startstop_t auide_dma_intr(ide_drive_t *drive)
-{
- //printk("%s\n", __FUNCTION__);
-
- u8 stat = 0, dma_stat = 0;
-
- dma_stat = HWIF(drive)->ide_dma_end(drive);
- stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */
- if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
- if (!dma_stat) {
- struct request *rq = HWGROUP(drive)->rq;
-
- ide_end_request(drive, 1, rq->nr_sectors);
- return ide_stopped;
- }
- printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n",
- drive->name, dma_stat);
- }
- return ide_error(drive, "dma_intr", stat);
-}
static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
{
- //printk("%s\n", __FUNCTION__);
-
- /* issue cmd to drive */
- ide_execute_command(drive, command, &auide_dma_intr,
- (2*WAIT_CMD), NULL);
+ /* issue cmd to drive */
+ ide_execute_command(drive, command, &ide_dma_intr,
+ (2*WAIT_CMD), NULL);
}
static int auide_dma_setup(ide_drive_t *drive)
-{
-// printk("%s\n", __FUNCTION__);
-
- if (drive->media != ide_disk)
- return 1;
-
- if (!auide_build_dmatable(drive))
- /* try PIO instead of DMA */
- return 1;
+{
+ struct request *rq = HWGROUP(drive)->rq;
- drive->waiting_for_dma = 1;
+ if (!auide_build_dmatable(drive)) {
+ ide_map_sg(drive, rq);
+ return 1;