summaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r--drivers/ide/pci/Makefile4
-rw-r--r--drivers/ide/pci/aec62xx.c13
-rw-r--r--drivers/ide/pci/alim15x3.c3
-rw-r--r--drivers/ide/pci/amd74xx.c1
-rw-r--r--drivers/ide/pci/atiixp.c74
-rw-r--r--drivers/ide/pci/cmd640.c16
-rw-r--r--drivers/ide/pci/cmd64x.c124
-rw-r--r--drivers/ide/pci/cs5520.c20
-rw-r--r--drivers/ide/pci/cs5530.c2
-rw-r--r--drivers/ide/pci/cs5535.c2
-rw-r--r--drivers/ide/pci/cy82c693.c64
-rw-r--r--drivers/ide/pci/delkin_cb.c2
-rw-r--r--drivers/ide/pci/hpt34x.c12
-rw-r--r--drivers/ide/pci/hpt366.c203
-rw-r--r--drivers/ide/pci/it8213.c21
-rw-r--r--drivers/ide/pci/it821x.c37
-rw-r--r--drivers/ide/pci/pdc202xx_new.c75
-rw-r--r--drivers/ide/pci/pdc202xx_old.c35
-rw-r--r--drivers/ide/pci/piix.c17
-rw-r--r--drivers/ide/pci/sc1200.c178
-rw-r--r--drivers/ide/pci/scc_pata.c14
-rw-r--r--drivers/ide/pci/serverworks.c42
-rw-r--r--drivers/ide/pci/sgiioc4.c50
-rw-r--r--drivers/ide/pci/siimage.c44
-rw-r--r--drivers/ide/pci/sis5513.c99
-rw-r--r--drivers/ide/pci/sl82c105.c111
-rw-r--r--drivers/ide/pci/slc90e66.c14
-rw-r--r--drivers/ide/pci/tc86c001.c3
-rw-r--r--drivers/ide/pci/triflex.c2
-rw-r--r--drivers/ide/pci/trm290.c9
-rw-r--r--drivers/ide/pci/via82cxxx.c1
31 files changed, 420 insertions, 872 deletions
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index 95d1ea8f1f1..94803253e8a 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -36,4 +36,8 @@ obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
# Must appear at the end of the block
obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o
+ifeq ($(CONFIG_BLK_DEV_CMD640), m)
+ obj-m += cmd640.o
+endif
+
EXTRA_CFLAGS := -Idrivers/ide
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index 44268504ae4..7f4d1857d55 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -202,6 +202,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -211,6 +212,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -220,7 +222,8 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
@@ -228,7 +231,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
.name = "AEC6280",
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE |
+ IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -237,7 +242,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE |
+ IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index ce293936af4..49aa82e412b 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -402,9 +402,6 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
u8 tmpbyte = 0x00;
int m5229_udma = (hwif->channel) ? 0x57 : 0x56;
- if (speed < XFER_PIO_0)
- return;
-
if (speed == XFER_UDMA_6)
speed1 = 0x47;
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 8d4125ec252..cee51fdafcf 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -266,6 +266,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
#define IDE_HFLAGS_AMD \
(IDE_HFLAG_PIO_NO_BLACKLIST | \
IDE_HFLAG_PIO_NO_DOWNGRADE | \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE | \
IDE_HFLAG_POST_SET_MODE | \
IDE_HFLAG_IO_32BIT | \
IDE_HFLAG_UNMASK_IRQS | \
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index ef8e0164ef7..491871984aa 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/atiixp.c Version 0.03 Aug 3 2007
+ * linux/drivers/ide/pci/atiixp.c Version 0.05 Nov 9 2007
*
* Copyright (C) 2003 ATI Inc. <hyu@ati.com>
* Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
@@ -43,47 +43,8 @@ static atiixp_ide_timing mdma_timing[] = {
{ 0x02, 0x00 },
};
-static int save_mdma_mode[4];
-
static DEFINE_SPINLOCK(atiixp_lock);
-static void atiixp_dma_host_on(ide_drive_t *drive)
-{
- struct pci_dev *dev = drive->hwif->pci_dev;
- unsigned long flags;
- u16 tmp16;
-
- spin_lock_irqsave(&atiixp_lock, flags);
-
- pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
- if (save_mdma_mode[drive->dn])
- tmp16 &= ~(1 << drive->dn);
- else
- tmp16 |= (1 << drive->dn);
- pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
-
- spin_unlock_irqrestore(&atiixp_lock, flags);
-
- ide_dma_host_on(drive);
-}
-
-static void atiixp_dma_host_off(ide_drive_t *drive)
-{
- struct pci_dev *dev = drive->hwif->pci_dev;
- unsigned long flags;
- u16 tmp16;
-
- spin_lock_irqsave(&atiixp_lock, flags);
-
- pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
- tmp16 &= ~(1 << drive->dn);
- pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
-
- spin_unlock_irqrestore(&atiixp_lock, flags);
-
- ide_dma_host_off(drive);
-}
-
/**
* atiixp_set_pio_mode - set host controller for PIO mode
* @drive: drive
@@ -132,29 +93,33 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
u32 tmp32;
u16 tmp16;
-
- if (speed < XFER_MW_DMA_0)
- return;
+ u16 udma_ctl = 0;
spin_lock_irqsave(&atiixp_lock, flags);
- save_mdma_mode[drive->dn] = 0;
+ pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_ctl);
+
if (speed >= XFER_UDMA_0) {
pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16);
tmp16 &= ~(0x07 << (drive->dn * 4));
tmp16 |= ((speed & 0x07) << (drive->dn * 4));
pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16);
- } else {
- if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) {
- save_mdma_mode[drive->dn] = speed;
- pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
- tmp32 &= ~(0xff << timing_shift);
- tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) |
- (mdma_timing[speed & 0x03].command_width << (timing_shift + 4));
- pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
- }
+
+ udma_ctl |= (1 << drive->dn);
+ } else if (speed >= XFER_MW_DMA_0) {
+ u8 i = speed & 0x03;
+
+ pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
+ tmp32 &= ~(0xff << timing_shift);
+ tmp32 |= (mdma_timing[i].recover_width << timing_shift) |
+ (mdma_timing[i].command_width << (timing_shift + 4));
+ pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
+
+ udma_ctl &= ~(1 << drive->dn);
}
+ pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, udma_ctl);
+
spin_unlock_irqrestore(&atiixp_lock, flags);
}
@@ -184,9 +149,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->cbl = ATA_CBL_PATA80;
else
hwif->cbl = ATA_CBL_PATA40;
-
- hwif->dma_host_on = &atiixp_dma_host_on;
- hwif->dma_host_off = &atiixp_dma_host_off;
}
static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index 4aa48104e0c..da3565e0071 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -706,9 +706,9 @@ static int pci_conf2(void)
}
/*
- * Probe for a cmd640 chipset, and initialize it if found. Called from ide.c
+ * Probe for a cmd640 chipset, and initialize it if found.
*/
-int __init ide_probe_for_cmd640x (void)
+static int __init cmd640x_init(void)
{
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
int second_port_toggled = 0;
@@ -717,6 +717,7 @@ int __init ide_probe_for_cmd640x (void)
const char *bus_type, *port2;
unsigned int index;
u8 b, cfr;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (cmd640_vlb && probe_for_cmd640_vlb()) {
bus_type = "VLB";
@@ -769,6 +770,8 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+ idx[0] = cmd_hwif0->index;
+
/*
* Ensure compatibility by always using the slowest timings
* for access to the drive's command register block,
@@ -826,6 +829,8 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif1->pio_mask = ATA_PIO5;
cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+
+ idx[1] = cmd_hwif1->index;
}
printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
cmd_hwif0->serialized ? "" : "not ", port2);
@@ -872,6 +877,13 @@ int __init ide_probe_for_cmd640x (void)
#ifdef CMD640_DUMP_REGS
cmd640_dump_regs();
#endif
+
+ ide_device_add(idx);
+
return 1;
}
+module_param_named(probe_vlb, cmd640_vlb, bool, 0);
+MODULE_PARM_DESC(probe_vlb, "probe for VLB version of CMD640 chipset");
+
+module_init(cmd640x_init);
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index bc553337b1b..cd4eb9def15 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/cmd64x.c Version 1.52 Dec 24, 2007
+ * linux/drivers/ide/pci/cmd64x.c Version 1.53 Dec 24, 2007
*
* cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines.
* Due to massive hardware bugs, UltraDMA is only supported
@@ -22,8 +22,6 @@
#include <asm/io.h>
-#define DISPLAY_CMD64X_TIMINGS
-
#define CMD_DEBUG 0
#if CMD_DEBUG
@@ -37,11 +35,6 @@
*/
#define CFR 0x50
#define CFR_INTR_CH0 0x04
-#define CNTRL 0x51
-#define CNTRL_ENA_1ST 0x04
-#define CNTRL_ENA_2ND 0x08
-#define CNTRL_DIS_RA0 0x40
-#define CNTRL_DIS_RA1 0x80
#define CMDTIM 0x52
#define ARTTIM0 0x53
@@ -60,108 +53,13 @@
#define MRDMODE 0x71
#define MRDMODE_INTR_CH0 0x04
#define MRDMODE_INTR_CH1 0x08
-#define MRDMODE_BLK_CH0 0x10
-#define MRDMODE_BLK_CH1 0x20
-#define BMIDESR0 0x72
#define UDIDETCR0 0x73
#define DTPR0 0x74
#define BMIDECR1 0x78
#define BMIDECSR 0x79
-#define BMIDESR1 0x7A
#define UDIDETCR1 0x7B
#define DTPR1 0x7C
-#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static u8 cmd64x_proc = 0;
-
-#define CMD_MAX_DEVS 5
-
-static struct pci_dev *cmd_devs[CMD_MAX_DEVS];
-static int n_cmd_devs;
-
-static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
-{
- char *p = buf;
- u8 reg72 = 0, reg73 = 0; /* primary */
- u8 reg7a = 0, reg7b = 0; /* secondary */
- u8 reg50 = 1, reg51 = 1, reg57 = 0, reg71 = 0; /* extra */
-
- p += sprintf(p, "\nController: %d\n", index);
- p += sprintf(p, "PCI-%x Chipset.\n", dev->device);
-
- (void) pci_read_config_byte(dev, CFR, &reg50);
- (void) pci_read_config_byte(dev, CNTRL, &reg51);
- (void) pci_read_config_byte(dev, ARTTIM23, &reg57);
- (void) pci_read_config_byte(dev, MRDMODE, &reg71);
- (void) pci_read_config_byte(dev, BMIDESR0, &reg72);
- (void) pci_read_config_byte(dev, UDIDETCR0, &reg73);
- (void) pci_read_config_byte(dev, BMIDESR1, &reg7a);
- (void) pci_read_config_byte(dev, UDIDETCR1, &reg7b);
-
- /* PCI0643/6 originally didn't have the primary channel enable bit */
- if ((dev->device == PCI_DEVICE_ID_CMD_643) ||
- (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 3))
- reg51 |= CNTRL_ENA_1ST;
-
- p += sprintf(p, "---------------- Primary Channel "
- "---------------- Secondary Channel ------------\n");
- p += sprintf(p, " %s %s\n",
- (reg51 & CNTRL_ENA_1ST) ? "enabled " : "disabled",
- (reg51 & CNTRL_ENA_2ND) ? "enabled " : "disabled");
- p += sprintf(p, "---------------- drive0 --------- drive1 "
- "-------- drive0 --------- drive1 ------\n");
- p += sprintf(p, "DMA enabled: %s %s"
- " %s %s\n",
- (reg72 & 0x20) ? "yes" : "no ", (reg72 & 0x40) ? "yes" : "no ",
- (reg7a & 0x20) ? "yes" : "no ", (reg7a & 0x40) ? "yes" : "no ");
- p += sprintf(p, "UltraDMA mode: %s (%c) %s (%c)",
- ( reg73 & 0x01) ? " on" : "off",
- ((reg73 & 0x30) == 0x30) ? ((reg73 & 0x04) ? '3' : '0') :
- ((reg73 & 0x30) == 0x20) ? ((reg73 & 0x04) ? '3' : '1') :
- ((reg73 & 0x30) == 0x10) ? ((reg73 & 0x04) ? '4' : '2') :
- ((reg73 & 0x30) == 0x00) ? ((reg73 & 0x04) ? '5' : '2') : '?',
- ( reg73 & 0x02) ? " on" : "off",
- ((reg73 & 0xC0) == 0xC0) ? ((reg73 & 0x08) ? '3' : '0') :
- ((reg73 & 0xC0) == 0x80) ? ((reg73 & 0x08) ? '3' : '1') :
- ((reg73 & 0xC0) == 0x40) ? ((reg73 & 0x08) ? '4' : '2') :
- ((reg73 & 0xC0) == 0x00) ? ((reg73 & 0x08) ? '5' : '2') : '?');
- p += sprintf(p, " %s (%c) %s (%c)\n",
- ( reg7b & 0x01) ? " on" : "off",
- ((reg7b & 0x30) == 0x30) ? ((reg7b & 0x04) ? '3' : '0') :
- ((reg7b & 0x30) == 0x20) ? ((reg7b & 0x04) ? '3' : '1') :
- ((reg7b & 0x30) == 0x10) ? ((reg7b & 0x04) ? '4' : '2') :
- ((reg7b & 0x30) == 0x00) ? ((reg7b & 0x04) ? '5' : '2') : '?',
- ( reg7b & 0x02) ? " on" : "off",
- ((reg7b & 0xC0) == 0xC0) ? ((reg7b & 0x08) ? '3' : '0') :
- ((reg7b & 0xC0) == 0x80) ? ((reg7b & 0x08) ? '3' : '1') :
- ((reg7b & 0xC0) == 0x40) ? ((reg7b & 0x08) ? '4' : '2') :
- ((reg7b & 0xC0) == 0x00) ? ((reg7b & 0x08) ? '5' : '2') : '?');
- p += sprintf(p, "Interrupt: %s, %s %s, %s\n",
- (reg71 & MRDMODE_BLK_CH0 ) ? "blocked" : "enabled",
- (reg50 & CFR_INTR_CH0 ) ? "pending" : "clear ",
- (reg71 & MRDMODE_BLK_CH1 ) ? "blocked" : "enabled",
- (reg57 & ARTTIM23_INTR_CH1) ? "pending" : "clear ");
-
- return (char *)p;
-}
-
-static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
-{
- char *p = buffer;
- int i;
-
- for (i = 0; i < n_cmd_devs; i++) {
- struct pci_dev *dev = cmd_devs[i];
- p = print_cmd64x_get_info(p, dev, i);
- }
- return p-buffer; /* => must be less than 4k! */
-}
-
-#endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
-
static u8 quantize_timing(int timing, int quant)
{
return (timing + quant - 1) / quant;
@@ -322,8 +220,6 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
case XFER_MW_DMA_0:
program_cycle_times(drive, 480, 215);
break;
- default:
- return;
}
if (speed >= XFER_SW_DMA_0)
@@ -333,14 +229,15 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
static int cmd648_ide_dma_end (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
+ unsigned long base = hwif->dma_base - (hwif->channel * 8);
int err = __ide_dma_end(drive);
u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0;
- u8 mrdmode = inb(hwif->dma_master + 0x01);
+ u8 mrdmode = inb(base + 1);
/* clear the interrupt bit */
outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask,
- hwif->dma_master + 0x01);
+ base + 1);
return err;
}
@@ -365,10 +262,11 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive)
static int cmd648_ide_dma_test_irq (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
+ unsigned long base = hwif->dma_base - (hwif->channel * 8);
u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0;
u8 dma_stat = inb(hwif->dma_status);
- u8 mrdmode = inb(hwif->dma_master + 0x01);
+ u8 mrdmode = inb(base + 1);
#ifdef DEBUG
printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n",
@@ -472,16 +370,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
mrdmode &= ~0x30;
(void) pci_write_config_byte(dev, MRDMODE, (mrdmode | 0x02));
-#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_IDE_PROC_FS)
-
- cmd_devs[n_cmd_devs++] = dev;
-
- if (!cmd64x_proc) {
- cmd64x_proc = 1;
- ide_pci_create_host_proc("cmd64x", cmd64x_get_info);
- }
-#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_IDE_PROC_FS */
-
return 0;
}
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 0466462fd21..6ec00b8d7ec 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -71,7 +71,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *pdev = hwif->pci_dev;
int controller = drive->dn > 1 ? 1 : 0;
- u8 reg;
/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
@@ -91,11 +90,6 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
-
- /* Set the DMA enable/disable flag */
- reg = inb(hwif->dma_base + 0x02 + 8*controller);
- reg |= 1<<((drive->dn&1)+5);
- outb(reg, hwif->dma_base + 0x02 + 8*controller);
}
static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -109,13 +103,14 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
* We wrap the DMA activate to set the vdma flag. This is needed
* so that the IDE DMA layer issues PIO not DMA commands over the
* DMA channel
+ *
+ * ATAPI is harder so disable it for now using IDE_HFLAG_NO_ATAPI_DMA
*/
-
-static int cs5520_dma_on(ide_drive_t *drive)
+
+static void cs5520_dma_host_set(ide_drive_t *drive, int on)
{
- /* ATAPI is harder so leave it for now */
- drive->vdma = 1;
- return 0;
+ drive->vdma = on;
+ ide_dma_host_set(drive, on);
}
static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
@@ -126,7 +121,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
if (hwif->dma_base == 0)
return;
- hwif->ide_dma_on = &cs5520_dma_on;
+ hwif->dma_host_set = &cs5520_dma_host_set;
}
#define DECLARE_CS_DEV(name_str) \
@@ -137,6 +132,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
IDE_HFLAG_CS5520 | \
IDE_HFLAG_VDMA | \
IDE_HFLAG_NO_ATAPI_DMA | \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE |\
IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
}
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 547690395ee..df5966b3346 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -116,8 +116,6 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
case XFER_MW_DMA_0: timings = 0x00077771; break;
case XFER_MW_DMA_1: timings = 0x00012121; break;
case XFER_MW_DMA_2: timings = 0x00002020; break;
- default:
- return;
}
basereg = CS5530_BASEREG(drive->hwif);
reg = inl(basereg + 4); /* get drive0 config register */
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index ddcbeba671e..50b3d7791f5 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -190,7 +190,7 @@ static const struct ide_port_info cs5535_chipset __devinitdata = {
.name = "CS5535",
.init_hwif = init_hwif_cs5535,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
- IDE_HFLAG_BOOTABLE,
+ IDE_HFLAG_ABUSE_SET_DMA_MODE | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 1cd4e9cb052..3ec4c659a37 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/cy82c693.c Version 0.42 Oct 23, 2007
+ * linux/drivers/ide/pci/cy82c693.c Version 0.44 Nov 8, 2007
*
* Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
@@ -176,17 +176,12 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
* set DMA mode a specific channel for CY82C693
*/
-static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
+static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
- u8 index = 0, data = 0;
+ ide_hwif_t *hwif = drive->hwif;
+ u8 single = (mode & 0x10) >> 4, index = 0, data = 0;
- if (mode>2) /* make sure we set a valid mode */
- mode = 2;
-
- if (mode > drive->id->tDMA) /* to be absolutly sure we have a valid mode */
- mode = drive->id->tDMA;
-
- index = (HWIF(drive)->channel==0) ? CY82_INDEX_CHANNEL0 : CY82_INDEX_CHANNEL1;
+ index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0;
#if CY82C693_DEBUG_LOGS
/* for debug let's show the previous values */
@@ -199,7 +194,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
(data&0x3), ((data>>2)&1));
#endif /* CY82C693_DEBUG_LOGS */
- data = (u8)mode|(u8)(single<<2);
+ data = (mode & 3) | (single << 2);
outb(index, CY82_INDEX_PORT);
outb(data, CY82_DATA_PORT);
@@ -207,7 +202,7 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
#if CY82C693_DEBUG_INFO
printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
drive->name, HWIF(drive)->channel, drive->select.b.unit,
- mode, single);
+ mode & 3, single);
#endif /* CY82C693_DEBUG_INFO */
/*
@@ -230,39 +225,6 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
#endif /* CY82C693_DEBUG_INFO */
}
-/*
- * used to set DMA mode for CY82C693 (single and multi modes)
- */
-static int cy82c693_ide_dma_on (ide_drive_t *drive)
-{
- struct hd_driveid *id = drive->id;
-
-#if CY82C693_DEBUG_INFO
- printk (KERN_INFO "dma_on: %s\n", drive->name);
-#endif /* CY82C693_DEBUG_INFO */
-
- if (id != NULL) {
- /* Enable DMA on any drive that has DMA
- * (multi or single) enabled
- */
- if (id->field_valid & 2) { /* regular DMA */
- int mmode, smode;
-
- mmode = id->dma_mword & (id->dma_mword >> 8);
- smode = id->dma_1word & (id->dma_1word >> 8);
-
- if (mmode != 0) {
- /* enable multi */
- cy82c693_dma_enable(drive, (mmode >> 1), 0);
- } else if (smode != 0) {
- /* enable single */
- cy82c693_dma_enable(drive, (smode >> 1), 1);
- }
- }
- }
- return __ide_dma_on(drive);
-}
-
static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -429,11 +391,7 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
{
hwif->set_pio_mode = &cy82c693_set_pio_mode;
-
- if (hwif->dma_base == 0)
- return;
-
- hwif->ide_dma_on = &cy82c693_ide_dma_on;
+ hwif->set_dma_mode = &cy82c693_set_dma_mode;
}
static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
@@ -454,11 +412,11 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
.init_iops = init_iops_cy82c693,
.init_hwif = init_hwif_cy82c693,
.chipset = ide_cy82c693,
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_CY82C693 |
IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
- .swdma_mask = ATA_SWDMA2_ONLY,
- .mwdma_mask = ATA_MWDMA2_ONLY,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
};
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 83829081640..26aa492071b 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
hw.irq = dev->irq;
hw.chipset = ide_pci; /* this enables IRQ sharing */
- rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif);
+ rc = ide_register_hw(&hw, &ide_undecoded_slave, &hwif);
if (rc < 0) {
printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
pci_disable_device(dev);
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index ae6307fae4f..dfba0d13fcd 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -129,14 +129,18 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
hwif->set_dma_mode = &hpt34x_set_mode;
}
+#define IDE_HFLAGS_HPT34X \
+ (IDE_HFLAG_NO_ATAPI_DMA | \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE | \
+ IDE_HFLAG_NO_AUTODMA)
+
static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
{ /* 0 */
.name = "HPT343",
.init_chipset = init_chipset_hpt34x,
.init_hwif = init_hwif_hpt34x,
.extra = 16,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
- IDE_HFLAG_NO_AUTODMA,
+ .host_flags = IDE_HFLAGS_HPT34X,
.pio_mask = ATA_PIO5,
},
{ /* 1 */
@@ -144,9 +148,7 @@ static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
.init_chipset = init_chipset_hpt34x,
.init_hwif = init_hwif_hpt34x,
.extra = 16,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA |
- IDE_HFLAG_NO_AUTODMA |
- IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO5,
#ifdef CONFIG_HPT34X_AUTODMA
.swdma_mask = ATA_SWDMA2,
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 9fce25bdec8..12685939a81 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/hpt366.c Version 1.22 Dec 4, 2007
+ * linux/drivers/ide/pci/hpt366.c Version 1.30 Dec 12, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -88,7 +88,7 @@
* - rename all the register related variables consistently
* - move all the interrupt twiddling code from the speedproc handlers into
* init_hwif_hpt366(), also grouping all the DMA related code together there
- * - merge two HPT37x speedproc handlers, fix the PIO timing register mask and
+ * - merge HPT36x/HPT37x speedproc handlers, fix PIO timing register mask and
* separate the UltraDMA and MWDMA masks there to avoid changing PIO timings
* when setting an UltraDMA mode
* - fix hpt3xx_tune_drive() to set the PIO mode requested, not always select
@@ -458,6 +458,13 @@ enum ata_clock {
NUM_ATA_CLOCKS
};
+struct hpt_timings {
+ u32 pio_mask;
+ u32 dma_mask;
+ u32 ultra_mask;
+ u32 *clock_table[NUM_ATA_CLOCKS];
+};
+
/*
* Hold all the HighPoint chip information in one place.
*/
@@ -468,7 +475,8 @@ struct hpt_info {
u8 udma_mask; /* Allowed UltraDMA modes mask. */
u8 dpll_clk; /* DPLL clock in MHz */
u8 pci_clk; /* PCI clock in MHz */
- u32 **settings; /* Chipset settings table */
+ struct hpt_timings *timings; /* Chipset timing data */
+ u8 clock; /* ATA clock selected */
};
/* Supported HighPoint chips */
@@ -486,20 +494,30 @@ enum {
HPT371N
};
-static u32 *hpt36x_settings[NUM_ATA_CLOCKS] = {
- twenty_five_base_hpt36x,
- thirty_three_base_hpt36x,
- forty_base_hpt36x,
- NULL,
- NULL
+static struct hpt_timings hpt36x_timings = {
+ .pio_mask = 0xc1f8ffff,
+ .dma_mask = 0x303800ff,
+ .ultra_mask = 0x30070000,
+ .clock_table = {
+ [ATA_CLOCK_25MHZ] = twenty_five_base_hpt36x,
+ [ATA_CLOCK_33MHZ] = thirty_three_base_hpt36x,
+ [ATA_CLOCK_40MHZ] = forty_base_hpt36x,
+ [ATA_CLOCK_50MHZ] = NULL,
+ [ATA_CLOCK_66MHZ] = NULL
+ }
};
-static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
- NULL,
- thirty_three_base_hpt37x,
- NULL,
- fifty_base_hpt37x,
- sixty_six_base_hpt37x
+static struct hpt_timings hpt37x_timings = {
+ .pio_mask = 0xcfc3ffff,
+ .dma_mask = 0x31c001ff,
+ .ultra_mask = 0x303c0000,
+ .clock_table = {
+ [ATA_CLOCK_25MHZ] = NULL,
+ [ATA_CLOCK_33MHZ] = thirty_three_base_hpt37x,
+ [ATA_CLOCK_40MHZ] = NULL,
+ [ATA_CLOCK_50MHZ] = fifty_base_hpt37x,
+ [ATA_CLOCK_66MHZ] = sixty_six_base_hpt37x
+ }
};
static const struct hpt_info hpt36x __devinitdata = {
@@ -507,7 +525,7 @@ static const struct hpt_info hpt36x __devinitdata = {
.chip_type = HPT36x,
.udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
.dpll_clk = 0, /* no DPLL */
- .settings = hpt36x_settings
+ .timings = &hpt36x_timings
};
static const struct hpt_info hpt370 __devinitdata = {
@@ -515,7 +533,7 @@ static const struct hpt_info hpt370 __devinitdata = {
.chip_type = HPT370,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
.dpll_clk = 48,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt370a __devinitdata = {
@@ -523,7 +541,7 @@ static const struct hpt_info hpt370a __devinitdata = {
.chip_type = HPT370A,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
.dpll_clk = 48,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt374 __devinitdata = {
@@ -531,7 +549,7 @@ static const struct hpt_info hpt374 __devinitdata = {
.chip_type = HPT374,
.udma_mask = ATA_UDMA5,
.dpll_clk = 48,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt372 __devinitdata = {
@@ -539,7 +557,7 @@ static const struct hpt_info hpt372 __devinitdata = {
.chip_type = HPT372,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 55,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt372a __devinitdata = {
@@ -547,7 +565,7 @@ static const struct hpt_info hpt372a __devinitdata = {
.chip_type = HPT372A,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 66,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt302 __devinitdata = {
@@ -555,7 +573,7 @@ static const struct hpt_info hpt302 __devinitdata = {
.chip_type = HPT302,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 66,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt371 __devinitdata = {
@@ -563,7 +581,7 @@ static const struct hpt_info hpt371 __devinitdata = {
.chip_type = HPT371,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 66,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt372n __devinitdata = {
@@ -571,7 +589,7 @@ static const struct hpt_info hpt372n __devinitdata = {
.chip_type = HPT372N,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 77,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt302n __devinitdata = {
@@ -579,7 +597,7 @@ static const struct hpt_info hpt302n __devinitdata = {
.chip_type = HPT302N,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 77,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static const struct hpt_info hpt371n __devinitdata = {
@@ -587,7 +605,7 @@ static const struct hpt_info hpt371n __devinitdata = {
.chip_type = HPT371N,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.dpll_clk = 77,
- .settings = hpt37x_settings
+ .timings = &hpt37x_timings
};
static int check_in_drive_list(ide_drive_t *drive, const char **list)
@@ -675,94 +693,50 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
for (i = 0; i < ARRAY_SIZE(xfer_speeds) - 1; i++)
if (xfer_speeds[i] == speed)
break;
- /*
- * NOTE: info->settings only points to the pointer
- * to the list of the actual register values
- */
- return (*info->settings)[i];
+
+ return info->timings->clock_table[info->clock][i];
}
-static void hpt36x_set_mode(ide_drive_t *drive, const u8 speed)
+static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
+ struct pci_dev *dev = HWIF(drive)->pci_dev;
struct hpt_info *info = pci_get_drvdata(dev);
- u8 itr_addr = drive->dn ? 0x44 : 0x40;
+ struct hpt_timings *t = info->timings;
+ u8 itr_addr = 0x40 + (drive->dn * 4);
u32 old_itr = 0;
- u32 itr_mask, new_itr;
-
- itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
- (speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff);
-
- new_itr = get_speed_setting(speed, info);
+ u32 new_itr = get_speed_setting(speed, info);
+ u32 itr_mask = speed < XFER_MW_DMA_0 ? t->pio_mask :
+ (speed < XFER_UDMA_0 ? t->dma_mask :
+ t->ultra_mask);
+ pci_read_config_dword(dev, itr_addr, &old_itr);
+ new_itr = (old_itr & ~itr_mask) | (new_itr & itr_mask);
/*
* Disable on-chip PIO FIFO/buffer (and PIO MST mode as well)
* to avoid problems handling I/O errors later
*/
- pci_read_config_dword(dev, itr_addr, &old_itr);
- new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask);
new_itr &= ~0xc0000000;
pci_write_config_dword(dev, itr_addr, new_itr);
}
-static void hpt37x_set_mode(ide_drive_t *drive, const u8 speed)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
- struct hpt_info *info = pci_get_drvdata(dev);
- u8 itr_addr = 0x40 + (drive->dn * 4);
- u32 old_itr = 0;
- u32 itr_mask, new_itr;
-
- itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
- (speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff);
-
- new_itr = get_speed_setting(speed, info);
-
- pci_read_config_dword(dev, itr_addr, &old_itr);
- new_itr = (new_itr & ~itr_mask) | (old_itr & itr_mask);
-
- if (speed < XFER_MW_DMA_0)
- new_itr &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
- pci_write_config_dword(dev, itr_addr, new_itr);
-}
-
-static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
-
- if (info->chip_type >= HPT370)
- hpt37x_set_mode(drive, speed);
- else /* hpt368: hpt_minimum_revision(dev, 2) */
- hpt36x_set_mode(drive, speed);
-}
-
static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
}
-static int hpt3xx_quirkproc(ide_drive_t *drive)
+static void hpt3xx_quirkproc(ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
const char **list = quirk_drives;
while (*list)
- if (strstr(id->model, *list++))
- return 1;
- return 0;
-}
-
-static void hpt3xx_intrproc(ide_drive_t *drive)
-{
- if (drive->quirk_list)
- return;
+ if (strstr(id->model, *list++)) {
+ drive->quirk_list = 1;
+ return;
+ }
- /* drives in the quirk_list may not like intr setups/cleanups */
- outb(drive->ctl | 2, IDE_CONTROL_REG);
+ drive->quirk_list = 0;
}
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
@@ -914,32 +888,33 @@ static int hpt374_ide_dma_end(ide_drive_t *drive)
static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
{
- u8 scr2 = inb(hwif->dma_master + 0x7b);
+ unsigned long base = hwif->extra_base;
+ u8 scr2 = inb(base + 0x6b);
if ((scr2 & 0x7f) == mode)
return;
/* Tristate the bus */
- outb(0x80, hwif->dma_master + 0x73);
- outb(0x80, hwif->dma_master + 0x77);
+ outb(0x80, base + 0x63);
+ outb(0x80, base + 0x67);
/* Switch clock and reset channels */
- outb(mode, hwif->dma_master + 0x7b);
- outb(0xc0, hwif->dma_master + 0x79);
+ outb(mode, base + 0x6b);
+ outb(0xc0, base + 0x69);
/*
* Reset the state machines.
* NOTE: avoid accidentally enabling the disabled channels.
*/
- outb(inb(hwif->dma_master + 0x70) | 0x32, hwif->dma_master + 0x70);
- outb(inb(hwif->dma_master + 0x74) | 0x32, hwif->dma_master + 0x74);
+ outb(inb(base + 0x60) | 0x32, base + 0x60);
+ outb(inb(base + 0x64) | 0x32, base + 0x64);
/* Complete reset */
- outb(0x00, hwif->dma_master + 0x79);
+ outb(0x00, base + 0x69);
/* Reconnect channels to bus */
- outb(0x00, hwif->dma_master + 0x73);
- outb(0x00, hwif->dma_master + 0x77);
+ outb(0x00, base + 0x63);
+ outb(0x00, base + 0x67);
}
/**
@@ -1210,7 +1185,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
* We also don't like using the DPLL because this causes glitches
* on PRST-/SRST- when the state engine gets reset...
*/
- if (chip_type >= HPT374 || info->settings[clock] == NULL) {
+ if (chip_type >= HPT374 || info->timings->clock_table[clock] == NULL) {
u16 f_low, delta = pci_clk < 50 ? 2 : 4;
int adjust;
@@ -1226,7 +1201,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
clock = ATA_CLOCK_50MHZ;
}
- if (info->settings[clock] == NULL) {
+ if (info->timings->clock_table[clock] == NULL) {
printk(KERN_ERR "%s: unknown bus timing!\n", name);
kfree(info);
return -EIO;
@@ -1267,15 +1242,10 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
printk("%s: using %d MHz PCI clock\n", name, pci_clk);
}
- /*
- * Advance the table pointer to a slot which points to the list
- * of the register values settings matching the clock being used.
- */
- info->settings += clock;
-
/* Store the clock frequencies. */
info->dpll_clk = dpll_clk;
info->pci_clk = pci_clk;
+ info->clock = clock;
/* Point to this chip's own instance of the hpt_info structure. */
pci_set_drvdata(dev, info);
@@ -1320,8 +1290,8 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
hwif->set_pio_mode = &hpt3xx_set_pio_mode;
hwif->set_dma_mode = &hpt3xx_set_mode;
+
hwif->quirkproc = &hpt3xx_quirkproc;
- hwif->intrproc = &hpt3xx_intrproc;
hwif->maskproc = &hpt3xx_maskproc;
hwif->busproc = &hpt3xx_busproc;
@@ -1494,6 +1464,11 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
return 0;
}
+#define IDE_HFLAGS_HPT3XX \
+ (IDE_HFLAG_NO_ATAPI_DMA | \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE | \
+ IDE_HFLAG_OFF_BOARD)
+
static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
{ /* 0 */
.name = "HPT36x",
@@ -1508,9 +1483,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
*/
.enablebits = {{0x50,0x10,0x10}, {0x54,0x04,0x04}},
.extra = 240,
- .host_flags = IDE_HFLAG_SINGLE |
- IDE_HFLAG_NO_ATAPI_DMA |
- IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT3XX | IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
},{ /* 1 */
@@ -1520,7 +1493,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.extra = 240,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
},{ /* 2 */
@@ -1530,7 +1503,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.extra = 240,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
},{ /* 3 */
@@ -1540,7 +1513,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.extra = 240,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
},{ /* 4 */
@@ -1551,7 +1524,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.udma_mask = ATA_UDMA5,
.extra = 240,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
},{ /* 5 */
@@ -1561,7 +1534,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
.init_dma = init_dma_hpt366,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.extra = 240,
- .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_HPT3XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
}
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 90b52ed37bf..2a0f45c4f4c 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -101,24 +101,11 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_read_config_byte(dev, 0x54, &reg54);
pci_read_config_byte(dev, 0x55, &reg55);
- switch(speed) {
- case XFER_UDMA_6:
- case XFER_UDMA_4:
- case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
- case XFER_UDMA_5:
- case XFER_UDMA_3:
- case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
- case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
- break;
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_SW_DMA_2:
- break;
- default:
- return;
- }
-
if (speed >= XFER_UDMA_0) {
+ u8 udma = speed - XFER_UDMA_0;
+
+ u_speed = min_t(u8, 2 - (udma & 1), udma) << (drive->dn * 4);
+
if (!(reg48 & u_flag))
pci_write_config_byte(dev, 0x48, reg48 | u_flag);
if (speed >= XFER_UDMA_5) {
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 99b7d763b6c..e610a5340fd 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -431,33 +431,29 @@ static u8 __devinit ata66_it821x(ide_hwif_t *hwif)
}
/**
- * it821x_fixup - post init callback
- * @hwif: interface
+ * it821x_quirkproc - post init callback
+ * @drive: drive
*
- * This callback is run after the drives have been probed but
+ * This callback is run after the drive has been probed but
* before anything gets attached. It allows drivers to do any
* final tuning that is needed, or fixups to work around bugs.
*/
-static void __devinit it821x_fixups(ide_hwif_t *hwif)
+static void __devinit it821x_quirkproc(ide_drive_t *drive)
{
- struct it821x_dev *itdev = ide_get_hwifdata(hwif);
- int i;
+ struct it821x_dev *itdev = ide_get_hwifdata(drive->hwif);
+ struct hd_driveid *id = drive->id;
+ u16 *idbits = (u16 *)drive->id;
- if(!itdev->smart) {
+ if (!itdev->smart) {
/*
* If we are in pass through mode then not much
* needs to be done, but we do bother to clear the
* IRQ mask as we may well be in PIO (eg rev 0x10)
* for now and we know unmasking is safe on this chipset.
*/
- for (i = 0; i < 2; i++) {
- ide_drive_t *drive = &hwif->drives[i];
- if(drive->present)
- drive->unmask = 1;
- }
- return;
- }
+ drive->unmask = 1;
+ } else {
/*
* Perform fixups on smart mode. We need to "lose" some
* capabilities the firmware lacks but does not filter, and
@@ -465,16 +461,6 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
* in RAID mode.
*/
- for(i = 0; i < 2; i++) {
- ide_drive_t *drive = &hwif->drives[i];
- struct hd_driveid *id;
- u16 *idbits;
-
- if(!drive->present)
- continue;
- id = drive->id;
- idbits = (u16 *)drive->id;
-
/* Check for RAID v native */
if(strstr(id->model, "Integrated Technology Express")) {
/* In raid mode the ident block is slightly buggy
@@ -537,6 +523,8 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
u8 conf;
+ hwif->quirkproc = &it821x_quirkproc;
+
if (idev == NULL) {
printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
return;
@@ -633,7 +621,6 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
.name = name_str, \
.init_chipset = init_chipset_it821x, \
.init_hwif = init_hwif_it821x, \
- .fixup = it821x_fixups, \
.host_flags = IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
}
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 2b4f44e45a1..89d2363a1eb 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -146,7 +146,7 @@ static struct udma_timing {
{ 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */
};
-static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
+static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
@@ -162,45 +162,18 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
if (max_dma_rate(hwif->pci_dev) == 4) {
u8 mode = speed & 0x07;
- switch (speed) {
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- set_indexed_reg(hwif, 0x10 + adj,
- udma_timings[mode].reg10);
- set_indexed_reg(hwif, 0x11 + adj,
- udma_timings[mode].reg11);
- set_indexed_reg(hwif, 0x12 + adj,
- udma_timings[mode].reg12);
- break;
-
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- set_indexed_reg(hwif, 0x0e + adj,
- mwdma_timings[mode].reg0e);
- set_indexed_reg(hwif, 0x0f + adj,
- mwdma_timings[mode].reg0f);
- break;
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- set_indexed_reg(hwif, 0x0c + adj,
- pio_timings[mode].reg0c);
- set_indexed_reg(hwif, 0x0d + adj,
- pio_timings[mode].reg0d);
- set_indexed_reg(hwif, 0x13 + adj,
- pio_timings[mode].reg13);
- break;
- default:
- printk(KERN_ERR "pdc202xx_new: "
- "Unknown speed %d ignored\n", speed);
+ if (speed >= XFER_UDMA_0) {
+ set_indexed_reg(hwif, 0x10 + adj,
+ udma_timings[mode].reg10);
+ set_indexed_reg(hwif, 0x11 + adj,
+ udma_timings[mode].reg11);
+ set_indexed_reg(hwif, 0x12 + adj,
+ udma_timings[mode].reg12);
+ } else {
+ set_indexed_reg(hwif, 0x0e + adj,
+ mwdma_timings[mode].reg0e);
+ set_indexed_reg(hwif, 0x0f + adj,
+ mwdma_timings[mode].reg0f);
}
} else if (speed == XFER_UDMA_2) {
/* Set tHOLD bit to 0 if using UDMA mode 2 */
@@ -212,7 +185,14 @@ static void pdcnew_set_mode(ide_drive_t *drive, const u8 speed)
static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pdcnew_set_mode(drive, XFER_PIO_0 + pio);
+ ide_hwif_t *hwif = drive->hwif;
+ u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
+
+ if (max_dma_rate(hwif->pci_dev) == 4) {
+ set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c);
+ set_indexed_reg(hwif, 0x0d + adj, pio_timings[pio].reg0d);
+ set_indexed_reg(hwif, 0x13 + adj, pio_timings[pio].reg13);
+ }
}
static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
@@ -223,14 +203,17 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static int pdcnew_quirkproc(ide_drive_t *drive)
+static void pdcnew_quirkproc(ide_drive_t *drive)
{
const char **list, *model = drive->id->model;
for (list = pdc_quirk_drives; *list != NULL; list++)
- if (strstr(model, *list) != NULL)
- return 2;
- return 0;
+ if (strstr(model, *list) != NULL) {
+ drive->quirk_list = 2;
+ return;
+ }
+
+ drive->quirk_list = 0;
}
static void pdcnew_reset(ide_drive_t *drive)
@@ -466,7 +449,7 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
{
hwif->set_pio_mode = &pdcnew_set_pio_mode;
- hwif->set_dma_mode = &pdcnew_set_mode;
+ hwif->set_dma_mode = &pdcnew_set_dma_mode;
hwif->quirkproc = &pdcnew_quirkproc;
hwif->resetproc = &pdcnew_reset;
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index e09742e2ba5..3a1e081fe39 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -162,7 +162,7 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
*/
static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
{
- unsigned long clock_reg = hwif->dma_master + 0x11;
+ unsigned long clock_reg = hwif->extra_base + 0x01;
u8 clock = inb(clock_reg);
outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
@@ -170,20 +170,23 @@ static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
{
- unsigned long clock_reg = hwif->dma_master + 0x11;
+ unsigned long clock_reg = hwif->extra_base + 0x01;
u8 clock = inb(clock_reg);
outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
}
-static int pdc202xx_quirkproc (ide_drive_t *drive)
+static void pdc202xx_quirkproc(ide_drive_t *drive)
{
const char **list, *model = drive->id->model;
for (list = pdc_quirk_drives; *list != NULL; list++)
- if (strstr(model, *list) != NULL)
- return 2;
- return 0;
+ if (strstr(model, *list) != NULL) {
+ drive->quirk_list = 2;
+ return;
+ }
+
+ drive->quirk_list = 0;
}
static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
@@ -193,7 +196,7 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
if (drive->media != ide_disk || drive->addressing == 1) {
struct request *rq = HWGROUP(drive)->rq;
ide_hwif_t *hwif = HWIF(drive);
- unsigned long high_16 = hwif->dma_master;
+ unsigned long high_16 = hwif->extra_base - 16;
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
u32 word_count = 0;
u8 clock = inb(high_16 + 0x11);
@@ -212,7 +215,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
{
if (drive->media != ide_disk || drive->addressing == 1) {
ide_hwif_t *hwif = HWIF(drive);
- unsigned long high_16 = hwif->dma_master;
+ unsigned long high_16 = hwif->extra_base - 16;
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
u8 clock = 0;
@@ -228,7 +231,7 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
- unsigned long high_16 = hwif->dma_master;
+ unsigned long high_16 = hwif->extra_base - 16;
u8 dma_stat = inb(hwif->dma_status);
u8 sc1d = inb(high_16 + 0x001d);
@@ -271,7 +274,7 @@ static void pdc202xx_dma_timeout(ide_drive_t *drive)
static void pdc202xx_reset_host (ide_hwif_t *hwif)
{
- unsigned long high_16 = hwif->dma_master;
+ unsigned long high_16 = hwif->extra_base - 16;
u8 udma_speed_flag = inb(high_16 | 0x001f);
outb(udma_speed_flag | 0x10, high_16 | 0x001f);
@@ -375,6 +378,11 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
}
}
+#define IDE_HFLAGS_PDC202XX \
+ (IDE_HFLAG_ERROR_STOPS_FIFO | \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE | \
+ IDE_HFLAG_OFF_BOARD)
+
#define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
{ \
.name = name_str, \
@@ -382,9 +390,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
.init_hwif = init_hwif_pdc202xx, \
.init_dma = init_dma_pdc202xx, \
.extra = 48, \
- .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | \
- extra_flags | \
- IDE_HFLAG_OFF_BOARD, \
+ .host_flags = IDE_HFLAGS_PDC202XX | extra_flags, \
.pio_mask = ATA_PIO4, \
.mwdma_mask = ATA_MWDMA2, \
.udma_mask = udma, \
@@ -397,8 +403,7 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
.extra = 16,
- .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO |
- IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAGS_PDC202XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 27781d294ce..bd6d3f77d30 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -203,20 +203,11 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_read_config_byte(dev, 0x54, &reg54);
pci_read_config_byte(dev, 0x55, &reg55);
- switch(speed) {
- case XFER_UDMA_4:
- case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
- case XFER_UDMA_5:
- case XFER_UDMA_3:
- case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
- case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_SW_DMA_2: break;
- default: return;
- }
-
if (speed >= XFER_UDMA_0) {
+ u8 udma = speed - XFER_UDMA_0;
+
+ u_speed = min_t(u8, 2 - (udma & 1), udma) << (drive->dn * 4);
+
if (!(reg48 & u_flag))
pci_write_config_byte(dev, 0x48, reg48 | u_flag);
if (speed == XFER_UDMA_5) {
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 707d5ff66b0..32fdf53379f 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -135,59 +135,29 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
unsigned short pci_clock;
unsigned int basereg = hwif->channel ? 0x50 : 0x40;
+ static const u32 udma_timing[3][3] = {
+ { 0x00921250, 0x00911140, 0x00911030 },
+ { 0x00932470, 0x00922260, 0x00922140 },
+ { 0x009436a1, 0x00933481, 0x00923261 },
+ };
+
+ static const u32 mwdma_timing[3][3] = {
+ { 0x00077771, 0x00012121, 0x00002020 },
+ { 0x000bbbb2, 0x00024241, 0x00013131 },
+ { 0x000ffff3, 0x00035352, 0x00015151 },
+ };
+
pci_clock = sc1200_get_pci_clock();
/*
* Note that each DMA mode has several timings associated with it.
* The correct timing depends on the fast PCI clock freq.
*/
- timings = 0;
- switch (mode) {
- case XFER_UDMA_0:
- switch (pci_clock) {
- case PCI_CLK_33: timings = 0x00921250; break;
- case PCI_CLK_48: timings = 0x00932470; break;
- case PCI_CLK_66: timings = 0x009436a1; break;
- }
- break;
- case XFER_UDMA_1:
- switch (pci_clock) {
- case PCI_CLK_33: timings = 0x00911140; break;
- case PCI_CLK_48: timings = 0x00922260; break;
- case PCI_CLK_66: timings = 0x00933481; break;
- }
- break;
- case XFER_UDMA_2:
- switch (pci_clock) {
- case PCI_CLK_33: timings = 0x00911030; break;
- case PCI_CLK_48: timings = 0x00922140; break;
- case PCI_CLK_66: timings = 0x00923261; break;
- }
- break;
- case XFER_MW_DMA_0:
- switch (pci_clock) {
- case PCI_CLK_33: timings = 0x00077771; break;
- case PCI_CLK_48: timings = 0x000bbbb2; break;
- case PCI_CLK_66: timings = 0x000ffff3; break;
- }
- break;
- case XFER_MW_DMA_1:
- switch (pci_clock) {
- case PCI_CLK_33: timings = 0x00012121; break;
- case PCI_CLK_48: timings = 0x00024241; break;
- case PCI_CLK_66: timings = 0x00035352; break;
- }
- break;
- case XFER_MW_DMA_2:
- switch (pci_clock) {
- case PCI_CLK_33: timings = 0x00002020; break;
- case PCI_CLK_48: timings = 0x00013131; break;
- case PCI_CLK_66: timings = 0x00015151; break;
- }
- break;
- default:
- return;
- }
+
+ if (mode >= XFER_UDMA_0)
+ timings = udma_timing[pci_clock][mode - XFER_UDMA_0];
+ else
+ timings = mwdma_timing[pci_clock][mode - XFER_MW_DMA_0];
if (unit == 0) { /* are we configuring drive0? */
pci_read_config_dword(hwif->pci_dev, basereg+4, &reg);
@@ -250,9 +220,9 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
if (mode != -1) {
printk("SC1200: %s: changing (U)DMA mode\n", drive->name);
- hwif->dma_off_quietly(drive);
- if (ide_set_dma_mode(drive, mode) == 0)
- hwif->dma_host_on(drive);
+ ide_dma_off_quietly(drive);
+ if (ide_set_dma_mode(drive, mode) == 0 && drive->using_dma)
+ hwif->dma_host_set(drive, 1);
return;
}
@@ -260,66 +230,39 @@ static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
#ifdef CONFIG_PM
-static ide_hwif_t *lookup_pci_dev (ide_hwif_t *prev, struct pci_dev *dev)
-{
- int h;
-
- for (h = 0; h < MAX_HWIFS; h++) {
- ide_hwif_t *hwif = &ide_hwifs[h];
- if (prev) {
- if (hwif == prev)
- prev = NULL; // found previous, now look for next match
- } else {
- if (hwif && hwif->pci_dev == dev)
- return hwif; // found next match
- }
- }
- return NULL; // not found
-}
-
-typedef struct sc1200_saved_state_s {
- __u32 regs[4];
-} sc1200_saved_state_t;
-
+struct sc1200_saved_state {
+ u32 regs[8];
+};
static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
{
- ide_hwif_t *hwif = NULL;
-
printk("SC1200: suspend(%u)\n", state.event);
+ /*
+ * we only save state when going from full power to less
+ */
if (state.event == PM_EVENT_ON) {
- // we only save state when going from full power to less
-
- //
- // Loop over all interfaces that are part of this PCI device:
- //
- while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
- sc1200_saved_state_t *ss;
- unsigned int basereg, r;
- //
- // allocate a permanent save area, if not already allocated
- //
- ss = (sc1200_saved_state_t *)hwif->config_data;
- if (ss == NULL) {
- ss = kmalloc(sizeof(sc1200_saved_state_t), GFP_KERNEL);
- if (ss == NULL)
- return -ENOMEM;
- hwif->config_data = (unsigned long)ss;
- }
- ss = (sc1200_saved_state_t *)hwif->config_data;
- //
- // Save timing registers: this may be unnecessary if
- // BIOS also does it
- //
- basereg = hwif->channel ? 0x50 : 0x40;
- for (r = 0; r < 4; ++r) {
- pci_read_config_dword (hwif->pci_dev, basereg + (r<<2), &ss->regs[r]);
- }
+ struct sc1200_saved_state *ss;
+ unsigned int r;
+
+ /*
+ * allocate a permanent save area, if not already allocated
+ */
+ ss = (struct sc1200_saved_state *)pci_get_drvdata(dev);
+ if (ss == NULL) {
+ ss = kmalloc(sizeof(*ss), GFP_KERNEL);
+ if (ss == NULL)
+ return -ENOMEM;
+ pci_set_drvdata(dev, ss);
}
- }
- /* You don't need to iterate over disks -- sysfs should have done that for you already */
+ /*
+ * save timing registers
+ * (this may be unnecessary if BIOS also does it)
+ */
+ for (r = 0; r < 8; r++)
+ pci_read_config_dword(dev, 0x40 + r * 4, &ss->regs[r]);
+ }
pci_disable_device(dev);
pci_set_power_state(dev, pci_choose_state(dev, state));
@@ -328,30 +271,25 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
static int sc1200_resume (struct pci_dev *dev)
{
- ide_hwif_t *hwif = NULL;
- int i;
+ struct sc1200_saved_state *ss;
+ unsigned int r;
+ int i;
i = pci_enable_device(dev);
if (i)
return i;
- //
- // loop over all interfaces that are part of this pci device:
- //
- while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
- unsigned int basereg, r;
- sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data;
-
- //
- // Restore timing registers: this may be unnecessary if BIOS also does it
- //
- basereg = hwif->channel ? 0x50 : 0x40;
- if (ss != NULL) {
- for (r = 0; r < 4; ++r) {
- pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]);
- }
- }
+ ss = (struct sc1200_saved_state *)pci_get_drvdata(dev);
+
+ /*
+ * restore timing registers
+ * (this may be unnecessary if BIOS also does it)
+ */
+ if (ss) {
+ for (r = 0; r < 8; r++)
+ pci_write_config_dword(dev, 0x40 + r * 4, ss->regs[r]);
}
+
return 0;
}
#endif
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index ebb7132b9b8..24a85bbcd2a 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -254,19 +254,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
offset = 0; /* 100MHz */
}
- switch (speed) {
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- idx = speed - XFER_UDMA_0;
- break;
- default:
- return;
- }
+ idx = speed - XFER_UDMA_0;
jcactsel = JCACTSELtbl[offset][idx];
if (is_slave) {
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index a7280311357..877c09bf482 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -164,25 +164,12 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
ultra_timing &= ~(0x0F << (4*unit));
ultra_enable &= ~(0x01 << drive->dn);
- switch(speed) {
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
- break;
-
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- dma_timing |= dma_modes[2];
- ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
- ultra_enable |= (0x01 << drive->dn);
- default:
- break;
- }
+ if (speed >= XFER_UDMA_0) {
+ dma_timing |= dma_modes[2];
+ ultra_timing |= (udma_modes[speed - XFER_UDMA_0] << (4 * unit));
+ ultra_enable |= (0x01 << drive->dn);
+ } else if (speed >= XFER_MW_DMA_0)
+ dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
@@ -366,12 +353,17 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
}
}
+#define IDE_HFLAGS_SVWKS \
+ (IDE_HFLAG_LEGACY_IRQS | \
+ IDE_HFLAG_ABUSE_SET_DMA_MODE | \
+ IDE_HFLAG_BOOTABLE)
+
static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
{ /* 0 */
.name = "SvrWks OSB4",
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* UDMA is problematic on OSB4 */
@@ -379,7 +371,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = "SvrWks CSB5",
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -387,7 +379,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = "SvrWks CSB6",
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAGS_SVWKS,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -395,8 +387,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = "SvrWks CSB6",
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
- IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
@@ -404,8 +395,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
.name = "SvrWks HT1000",
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE |
- IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAGS_SVWKS | IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index de820aa58cd..9e0be7d5498 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -277,21 +277,6 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
return dma_stat;
}
-static int
-sgiioc4_ide_dma_on(ide_drive_t * drive)
-{
- drive->using_dma = 1;
-
- return 0;
-}
-
-static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
-{
- drive->using_dma = 0;
-
- drive->hwif->dma_host_off(drive);
-}
-
static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
}
@@ -303,13 +288,10 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
return sgiioc4_checkirq(HWIF(drive));
}
-static void sgiioc4_dma_host_on(ide_drive_t * drive)
-{
-}
-
-static void sgiioc4_dma_host_off(ide_drive_t * drive)
+static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
{
- sgiioc4_clearirq(drive);
+ if (!on)
+ sgiioc4_clearirq(drive);
}
static void
@@ -582,7 +564,6 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine,
clear interrupts */
- hwif->intrproc = NULL; /* Enable or Disable interrupt from drive */
hwif->maskproc = &sgiioc4_maskproc; /* Mask on/off NIEN register */
hwif->quirkproc = NULL;
hwif->busproc = NULL;
@@ -594,14 +575,11 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
hwif->mwdma_mask = ATA_MWDMA2_ONLY;
+ hwif->dma_host_set = &sgiioc4_dma_host_set;
hwif->dma_setup = &sgiioc4_ide_dma_setup;
hwif->dma_start = &sgiioc4_ide_dma_start;
hwif->ide_dma_end = &sgiioc4_ide_dma_end;
- hwif->ide_dma_on = &sgiioc4_ide_dma_on;
- hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
- hwif->dma_host_on = &sgiioc4_dma_host_on;
- hwif->dma_host_off = &sgiioc4_dma_host_off;
hwif->dma_lost_irq = &sgiioc4_dma_lost_irq;
hwif->dma_timeout = &ide_dma_timeout;
}
@@ -615,6 +593,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
ide_hwif_t *hwif;
int h;
u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ hw_regs_t hw;
/*
* Find an empty HWIF; if none available, return -ENOMEM.
@@ -654,21 +633,16 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
return -ENOMEM;
}
- if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
- hw_regs_t hw;
-
- /* Initialize the IO registers */
- memset(&hw, 0, sizeof(hw));
- sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
- memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
- hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
- }
+ /* Initialize the IO registers */
+ memset(&hw, 0, sizeof(hw));
+ sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
+ hw.irq = dev->irq;
+ hw.chipset = ide_pci;
+ hw.dev = &dev->dev;
+ ide_init_port_hw(hwif, &hw);
- hwif->irq = dev->irq;
- hwif->chipset = ide_pci;
hwif->pci_dev = dev;
hwif->channel = 0; /* Single Channel chip */
- hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
/* The IOC4 uses MMIO rather than Port IO. */
default_hwif_mmiops(hwif);
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 5709c252543..908f37b4e0e 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -278,27 +278,14 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
scsc = is_sata(hwif) ? 1 : scsc;
- switch(speed) {
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- multi = dma[speed - XFER_MW_DMA_0];
- mode |= ((unit) ? 0x20 : 0x02);
- break;
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- multi = dma[2];
- ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) :
- (ultra5[speed - XFER_UDMA_0]));
- mode |= ((unit) ? 0x30 : 0x03);
- break;
- default:
- return;
+ if (speed >= XFER_UDMA_0) {
+ multi = dma[2];
+ ultra |= (scsc ? ultra6[speed - XFER_UDMA_0] :
+ ultra5[speed - XFER_UDMA_0]);
+ mode |= (unit ? 0x30 : 0x03);
+ } else {
+ multi = dma[speed - XFER_MW_DMA_0];
+ mode |= (unit ? 0x20 : 0x02);
}
if (hwif->mmio) {
@@ -726,9 +713,6 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
const char *s = &drive->id->model[0];
unsigned len;
- if (!drive->present)
- return 0;
-
len = strnlen(s, sizeof(drive->id->model));
if ((len > 4) && (!memcmp(s, "ST", 2))) {
@@ -743,18 +727,20 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
}
/**
- * siimage_fixup - post probe fixups
- * @hwif: interface to fix up
+ * sil_quirkproc - post probe fixups
+ * @drive: drive
*
* Called after drive probe we use this to decide whether the
* Seagate fixup must be applied. This used to be in init_iops but
* that can occur before we know what drives are present.
*/
-static void __devinit siimage_fixup(ide_hwif_t *hwif)
+static void __devinit sil_quirkproc(ide_drive_t *drive)
{
+ ide_hwif_t *hwif = drive->hwif;
+
/* Try and raise the rqsize */
- if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0]))
+ if (!is_sata(hwif) || !is_dev_seagate_sata(drive))
hwif->rqsize = 128;
}
@@ -817,6 +803,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
hwif->set_pio_mode = &sil_set_pio_mode;
hwif->set_dma_mode = &sil_set_dma_mode;
+ hwif->quirkproc = &sil_quirkproc;
if (sata) {
static int first = 1;
@@ -855,7 +842,6 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
.init_chipset = init_chipset_siimage, \
.init_iops = init_iops_siimage, \
.init_hwif = init_hwif_siimage, \
- .fixup = siimage_fixup, \
.host_flags = IDE_HFLAG_BOOTABLE, \
.pio_mask = ATA_PIO4, \
.mwdma_mask = ATA_MWDMA2, \
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index d90b4291777..85d36996e6a 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -305,59 +305,56 @@ static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
sis_program_timings(drive, XFER_PIO_0 + pio);
}
-static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sis_ata133_program_udma_timings(ide_drive_t *drive, const u8 mode)
{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ u32 regdw = 0;
+ u8 drive_pci = sis_ata133_get_base(drive), clk, idx;
- /* Config chip for mode */
- switch(speed) {
- case XFER_UDMA_6:
- case XFER_UDMA_5:
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- if (chipset_family >= ATA_133) {
- u32 regdw = 0;
- u8 drive_pci = sis_ata133_get_base(drive);
-
- pci_read_config_dword(dev, drive_pci, &regdw);
- regdw |= 0x04;
- regdw &= 0xfffff00f;
- /* check if ATA133 enable */
- if (regdw & 0x08) {
- regdw |= (unsigned long)cycle_time_value[ATA_133][speed-XFER_UDMA_0] << 4;
- regdw |= (unsigned long)cvs_time_value[ATA_133][speed-XFER_UDMA_0] << 8;
- } else {
- regdw |= (unsigned long)cycle_time_value[ATA_100][speed-XFER_UDMA_0] << 4;
- regdw |= (unsigned long)cvs_time_value[ATA_100][speed-XFER_UDMA_0] << 8;
- }
- pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);
- } else {
- u8 drive_pci = 0x40 + drive->dn * 2, reg = 0;
-
- pci_read_config_byte(dev, drive_pci+1, &reg);
- /* Force the UDMA bit on if we want to use UDMA */
- reg |= 0x80;
- /* clean reg cycle time bits */
- reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family]))
- << cycle_time_offset[chipset_family]);
- /* set reg cycle time bits */
- reg |= cycle_time_value[chipset_family][speed-XFER_UDMA_0]
- << cycle_time_offset[chipset_family];
- pci_write_config_byte(dev, drive_pci+1, reg);
- }
- break;
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- sis_program_timings(drive, speed);
- break;
- default:
- break;
- }
+ pci_read_config_dword(dev, drive_pci, &regdw);
+
+ regdw |= 0x04;
+ regdw &= 0xfffff00f;
+ /* check if ATA133 enable */
+ clk = (regdw & 0x08) ? ATA_133 : ATA_100;
+ idx = mode - XFER_UDMA_0;
+ regdw |= cycle_time_value[clk][idx] << 4;
+ regdw |= cvs_time_value[clk][idx] << 8;
+
+ pci_write_config_dword(dev, drive_pci, regdw);
+}
+
+static void sis_ata33_program_udma_timings(ide_drive_t *drive, const u8 mode)
+{
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ u8 drive_pci = 0x40 + drive->dn * 2, reg = 0, i = chipset_family;
+
+ pci_read_config_byte(dev, drive_pci + 1, &reg);
+
+ /* force the UDMA bit on if we want to use UDMA */
+ reg |= 0x80;
+ /* clean reg cycle time bits */
+ reg &= ~((0xff >> (8 - cycle_time_range[i])) << cycle_time_offset[i]);
+ /* set reg cycle time bits */
+ reg |= cycle_time_value[i][mode - XFER_UDMA_0] << cycle_time_offset[i];
+
+ pci_write_config_byte(dev, drive_pci + 1, reg);
+}
+
+static void sis_program_udma_timings(ide_drive_t *drive, const u8 mode)
+{
+ if (chipset_family >= ATA_133) /* ATA_133 */
+ sis_ata133_program_udma_timings(drive, mode);
+ else /* ATA_33/66/100a/100/133a */
+ sis_ata33_program_udma_timings(drive, mode);
+}
+
+static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
+{
+ if (speed >= XFER_UDMA_0)
+ sis_program_udma_timings(drive, speed);
+ else
+ sis_program_timings(drive, speed);
}
static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 147d783f752..c7a125b66c2 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -13,6 +13,7 @@
* -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org
*
* Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*/
#include <linux/types.h>
@@ -90,14 +91,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->drive_data &= 0xffff0000;
drive->drive_data |= drv_ctrl;
- if (!drive->using_dma) {
- /*
- * If we are actually using MW DMA, then we can not
- * reprogram the interface drive control register.
- */
- pci_write_config_word(dev, reg, drv_ctrl);
- pci_read_config_word (dev, reg, &drv_ctrl);
- }
+ pci_write_config_word(dev, reg, drv_ctrl);
+ pci_read_config_word (dev, reg, &drv_ctrl);
printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name,
ide_xfer_verbose(pio + XFER_PIO_0),
@@ -115,33 +110,14 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
drive->name, ide_xfer_verbose(speed)));
- switch (speed) {
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];
+ drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];
- /*
- * Store the DMA timings so that we can actually program
- * them when DMA will be turned on...
- */
- drive->drive_data &= 0x0000ffff;
- drive->drive_data |= (unsigned long)drv_ctrl << 16;
-
- /*
- * If we are already using DMA, we just reprogram
- * the drive control register.
- */
- if (drive->using_dma) {
- struct pci_dev *dev = HWIF(drive)->pci_dev;
- int reg = 0x44 + drive->dn * 4;
-
- pci_write_config_word(dev, reg, drv_ctrl);
- }
- break;
- default:
- return;
- }
+ /*
+ * Store the DMA timings so that we can actually program
+ * them when DMA will be turned on...
+ */
+ drive->drive_data &= 0x0000ffff;
+ drive->drive_data |= (unsigned long)drv_ctrl << 16;
}
/*
@@ -209,6 +185,11 @@ static void sl82c105_dma_start(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
+ int reg = 0x44 + drive->dn * 4;
+
+ DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
+
+ pci_write_config_word(dev, reg, drive->drive_data >> 16);
sl82c105_reset_host(dev);
ide_dma_start(drive);
@@ -222,64 +203,24 @@ static void sl82c105_dma_timeout(ide_drive_t *drive)
ide_dma_timeout(drive);
}
-static int sl82c105_ide_dma_on(ide_drive_t *drive)
-{
- struct pci_dev *dev = HWIF(drive)->pci_dev;
- int rc, reg = 0x44 + drive->dn * 4;
-
- DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
-
- rc = __ide_dma_on(drive);
- if (rc == 0) {
- pci_write_config_word(dev, reg, drive->drive_data >> 16);
-
- printk(KERN_INFO "%s: DMA enabled\n", drive->name);
- }
- return rc;
-}
-
-static void sl82c105_dma_off_quietly(ide_drive_t *drive)
+static int sl82c105_dma_end(ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
int reg = 0x44 + drive->dn * 4;
+ int ret;
- DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name));
+ DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name));
- pci_write_config_word(dev, reg, drive->drive_data);
+ ret = __ide_dma_end(drive);
- ide_dma_off_quietly(drive);
-}
+ pci_write_config_word(dev, reg, drive->drive_data);
-/*
- * Ok, that is nasty, but we must make sure the DMA timings
- * won't be used for a PIO access. The solution here is
- * to make sure the 16 bits mode is diabled on the channel
- * when DMA is enabled, thus causing the chip to use PIO0
- * timings for those operations.
- */
-static void sl82c105_selectproc(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
- u32 val, old, mask;
-
- //DBG(("sl82c105_selectproc(drive:%s)\n", drive->name));
-
- mask = hwif->channel ? CTRL_P1F16 : CTRL_P0F16;
- old = val = (u32)pci_get_drvdata(dev);
- if (drive->using_dma)
- val &= ~mask;
- else
- val |= mask;
- if (old != val) {
- pci_write_config_dword(dev, 0x40, val);
- pci_set_drvdata(dev, (void *)val);
- }
+ return ret;
}
/*
* ATA reset will clear the 16 bits mode in the control
- * register, we need to update our cache
+ * register, we need to reprogram it
*/
static void sl82c105_resetproc(ide_drive_t *drive)
{
@@ -289,7 +230,8 @@ static void sl82c105_resetproc(ide_drive_t *drive)
DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
pci_read_config_dword(dev, 0x40, &val);
- pci_set_drvdata(dev, (void *)val);
+ val |= (CTRL_P1F16 | CTRL_P0F16);
+ pci_write_config_dword(dev, 0x40, val);
}
/*
@@ -342,7 +284,6 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
pci_read_config_dword(dev, 0x40, &val);
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
- pci_set_drvdata(dev, (void *)val);
return dev->irq;
}
@@ -358,7 +299,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->set_pio_mode = &sl82c105_set_pio_mode;
hwif->set_dma_mode = &sl82c105_set_dma_mode;
- hwif->selectproc = &sl82c105_selectproc;
hwif->resetproc = &sl82c105_resetproc;
if (!hwif->dma_base)
@@ -377,10 +317,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->mwdma_mask = ATA_MWDMA2;
- hwif->ide_dma_on = &sl82c105_ide_dma_on;
- hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
hwif->dma_lost_irq = &sl82c105_dma_lost_irq;
hwif->dma_start = &sl82c105_dma_start;
+ hwif->ide_dma_end = &sl82c105_dma_end;
hwif->dma_timeout = &sl82c105_dma_timeout;
if (hwif->mate)
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index eb4445b229e..dbbb46819a2 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -91,19 +91,9 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_read_config_word(dev, 0x48, &reg48);
pci_read_config_word(dev, 0x4a, &reg4a);
- switch(speed) {
- case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break;
- case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break;
- case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
- case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
- case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_SW_DMA_2: break;
- default: return;
- }
-
if (speed >= XFER_UDMA_0) {
+ u_speed = (speed - XFER_UDMA_0) << (drive->dn * 4);
+
if (!(reg48 & u_flag))
pci_write_config_word(dev, 0x48, reg48|u_flag);
/* FIXME: (reg4a & a_speed) ? */
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index a66ebd14664..e1faf6c2fe1 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -222,7 +222,8 @@ static const struct ide_port_info tc86c001_chipset __devinitdata = {
.name = "TC86C001",
.init_chipset = init_chipset_tc86c001,
.init_hwif = init_hwif_tc86c001,
- .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index a227c41d23a..ae52a96a1cf 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -81,8 +81,6 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
case XFER_PIO_0:
timing = 0x0808;
break;
- default:
- return;
}
triflex_timings &= ~(0xFFFF << (16 * unit));
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 0151d7fdfb8..04cd893e1ab 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -241,11 +241,7 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
return (status == 0x00ff);
}
-static void trm290_dma_host_on(ide_drive_t *drive)
-{
-}
-
-static void trm290_dma_host_off(ide_drive_t *drive)
+static void trm290_dma_host_set(ide_drive_t *drive, int on)
{
}
@@ -289,8 +285,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
- hwif->dma_host_off = &trm290_dma_host_off;
- hwif->dma_host_on = &trm290_dma_host_on;
+ hwif->dma_host_set = &trm290_dma_host_set;
hwif->dma_setup = &trm290_dma_setup;
hwif->dma_exec_cmd = &trm290_dma_exec_cmd;
hwif->dma_start = &trm290_dma_start;
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index a0d3c16b68e..4b32c90f489 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -439,6 +439,7 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
.enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
.host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
IDE_HFLAG_PIO_NO_DOWNGRADE |
+ IDE_HFLAG_ABUSE_SET_DMA_MODE |
IDE_HFLAG_POST_SET_MODE |
IDE_HFLAG_IO_32BIT |
IDE_HFLAG_BOOTABLE,