summaryrefslogtreecommitdiff
path: root/drivers/ide/pci
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2007-10-13 05:27:47 +0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2007-10-13 05:27:47 +0400
commitb981d8b3f5e008ff10d993be633ad00564fc22cd (patch)
treee292dc07b22308912cf6a58354a608b9e5e8e1fd /drivers/ide/pci
parentb11d2127c4893a7315d1e16273bc8560049fa3ca (diff)
parent2b9e0aae1d50e880c58d46788e5e3ebd89d75d62 (diff)
downloadlinux-b981d8b3f5e008ff10d993be633ad00564fc22cd.tar.xz
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/macintosh/adbhid.c
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r--drivers/ide/pci/aec62xx.c29
-rw-r--r--drivers/ide/pci/alim15x3.c61
-rw-r--r--drivers/ide/pci/amd74xx.c37
-rw-r--r--drivers/ide/pci/atiixp.c43
-rw-r--r--drivers/ide/pci/cmd640.c46
-rw-r--r--drivers/ide/pci/cmd64x.c64
-rw-r--r--drivers/ide/pci/cs5520.c61
-rw-r--r--drivers/ide/pci/cs5530.c36
-rw-r--r--drivers/ide/pci/cs5535.c58
-rw-r--r--drivers/ide/pci/cy82c693.c23
-rw-r--r--drivers/ide/pci/generic.c15
-rw-r--r--drivers/ide/pci/hpt34x.c31
-rw-r--r--drivers/ide/pci/hpt366.c210
-rw-r--r--drivers/ide/pci/it8213.c50
-rw-r--r--drivers/ide/pci/it821x.c32
-rw-r--r--drivers/ide/pci/jmicron.c96
-rw-r--r--drivers/ide/pci/ns87415.c10
-rw-r--r--drivers/ide/pci/opti621.c23
-rw-r--r--drivers/ide/pci/pdc202xx_new.c106
-rw-r--r--drivers/ide/pci/pdc202xx_old.c44
-rw-r--r--drivers/ide/pci/piix.c49
-rw-r--r--drivers/ide/pci/rz1000.c1
-rw-r--r--drivers/ide/pci/sc1200.c73
-rw-r--r--drivers/ide/pci/scc_pata.c138
-rw-r--r--drivers/ide/pci/serverworks.c108
-rw-r--r--drivers/ide/pci/sgiioc4.c89
-rw-r--r--drivers/ide/pci/siimage.c170
-rw-r--r--drivers/ide/pci/sis5513.c54
-rw-r--r--drivers/ide/pci/sl82c105.c47
-rw-r--r--drivers/ide/pci/slc90e66.c25
-rw-r--r--drivers/ide/pci/tc86c001.c16
-rw-r--r--drivers/ide/pci/triflex.c17
-rw-r--r--drivers/ide/pci/trm290.c1
-rw-r--r--drivers/ide/pci/via82cxxx.c58
34 files changed, 824 insertions, 1097 deletions
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index e5d09367627e..0d5f62c5dfae 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -87,12 +87,11 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
return chipset_table->ultra_settings;
}
-static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int aec6210_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u16 d_conf = 0;
- u8 speed = ide_rate_filter(drive, xferspeed);
u8 ultra = 0, ultra_conf = 0;
u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
unsigned long flags;
@@ -115,11 +114,10 @@ static int aec6210_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return(ide_config_drive_speed(drive, speed));
}
-static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int aec6260_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- u8 speed = ide_rate_filter(drive, xferspeed);
u8 unit = (drive->select.b.unit & 0x01);
u8 tmp1 = 0, tmp2 = 0;
u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
@@ -140,9 +138,8 @@ static int aec6260_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return(ide_config_drive_speed(drive, speed));
}
-static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
+static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void) HWIF(drive)->speedproc(drive, pio + XFER_PIO_0);
}
@@ -152,7 +149,7 @@ static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- aec62xx_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -174,12 +171,6 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch
{
int bus_speed = system_bus_clock();
- if (dev->resource[PCI_ROM_RESOURCE].start) {
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name,
- (unsigned long)dev->resource[PCI_ROM_RESOURCE].start);
- }
-
if (bus_speed <= 33)
pci_set_drvdata(dev, (void *) aec6xxx_33_base);
else
@@ -209,7 +200,7 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
u8 reg54 = 0, mask = hwif->channel ? 0xf0 : 0x0f;
unsigned long flags;
- hwif->tuneproc = &aec62xx_tune_drive;
+ hwif->set_pio_mode = &aec_set_pio_mode;
if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
if(hwif->mate)
@@ -271,48 +262,48 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
.init_setup = init_setup_aec62xx,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x07, /* udma0-2 */
},{ /* 1 */
.name = "AEC6260",
.init_setup = init_setup_aec62xx,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x1f, /* udma0-4 */
},{ /* 2 */
.name = "AEC6260R",
.init_setup = init_setup_aec62xx,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.bootable = NEVER_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x1f, /* udma0-4 */
},{ /* 3 */
.name = "AEC6280",
.init_setup = init_setup_aec6x80,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
},{ /* 4 */
.name = "AEC6280R",
.init_setup = init_setup_aec6x80,
.init_chipset = init_chipset_aec62xx,
.init_hwif = init_hwif_aec62xx,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
}
};
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index ba0fb92b0417..d04b966b4347 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/alim15x3.c Version 0.25 Jun 9 2007
+ * linux/drivers/ide/pci/alim15x3.c Version 0.26 Jul 14 2007
*
* Copyright (C) 1998-2000 Michel Aubry, Maintainer
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -283,19 +283,15 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_IDE_PROC_FS) */
/**
- * ali15x3_tune_pio - set up chipset for PIO mode
- * @drive: drive to tune
- * @pio: desired mode
+ * ali_tune_pio - set host controller for PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
- * Select the best PIO mode for the drive in question.
- * Then program the controller for this mode.
- *
- * Returns the PIO mode programmed.
+ * Program the controller for the given PIO mode.
*/
-
-static u8 ali15x3_tune_pio (ide_drive_t *drive, u8 pio)
+
+static void ali_tune_pio(ide_drive_t *drive, const u8 pio)
{
- ide_pio_data_t d;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
int s_time, a_time, c_time;
@@ -307,7 +303,6 @@ static u8 ali15x3_tune_pio (ide_drive_t *drive, u8 pio)
u8 cd_dma_fifo = 0;
int unit = drive->select.b.unit & 1;
- pio = ide_get_best_pio_mode(drive, pio, 5, &d);
s_time = ide_pio_timings[pio].setup_time;
a_time = ide_pio_timings[pio].active_time;
if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
@@ -360,22 +355,20 @@ static u8 ali15x3_tune_pio (ide_drive_t *drive, u8 pio)
* { 25, 70, 25 }, PIO Mode 4 with IORDY ns
* { 20, 50, 30 } PIO Mode 5 with IORDY (nonstandard)
*/
-
- return pio;
}
/**
- * ali15x3_tune_drive - set up drive for PIO mode
+ * ali_set_pio_mode - set up drive for PIO mode
* @drive: drive to tune
* @pio: desired mode
*
- * Program the controller with the best PIO timing for the given drive.
+ * Program the controller with the desired PIO timing for the given drive.
* Then set up the drive itself.
*/
-static void ali15x3_tune_drive (ide_drive_t *drive, u8 pio)
+static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ali15x3_tune_pio(drive, pio);
+ ali_tune_pio(drive, pio);
(void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
@@ -410,22 +403,24 @@ static u8 ali_udma_filter(ide_drive_t *drive)
/**
* ali15x3_tune_chipset - set up chipset/drive for new speed
* @drive: drive to configure for
- * @xferspeed: desired speed
+ * @speed: desired speed
*
* Configure the hardware for the desired IDE transfer mode.
* We also do the needed drive configuration through helpers
*/
-
-static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+
+static int ali15x3_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- u8 speed = ide_rate_filter(drive, xferspeed);
u8 speed1 = speed;
u8 unit = (drive->select.b.unit & 0x01);
u8 tmpbyte = 0x00;
int m5229_udma = (hwif->channel) ? 0x57 : 0x56;
+ if (speed < XFER_PIO_0)
+ return 1;
+
if (speed == XFER_UDMA_6)
speed1 = 0x47;
@@ -438,8 +433,9 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, u8 xferspeed)
tmpbyte &= ultra_enable;
pci_write_config_byte(dev, m5229_udma, tmpbyte);
- if (speed < XFER_SW_DMA_0)
- (void) ali15x3_tune_pio(drive, speed - XFER_PIO_0);
+ /*
+ * FIXME: Oh, my... DMA timings are never set.
+ */
} else {
pci_read_config_byte(dev, m5229_udma, &tmpbyte);
tmpbyte &= (0x0f << ((1-unit) << 2));
@@ -472,7 +468,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
if (ide_tune_dma(drive))
return 0;
- ali15x3_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -589,12 +585,19 @@ out:
* Cable special cases
*/
-static struct dmi_system_id cable_dmi_table[] = {
+static const struct dmi_system_id cable_dmi_table[] = {
{
.ident = "HP Pavilion N5430",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
- DMI_MATCH(DMI_BOARD_NAME, "OmniBook N32N-736"),
+ DMI_MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736"),
+ },
+ },
+ {
+ .ident = "Toshiba Satellite S1800-814",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S1800-814"),
},
},
{ }
@@ -695,7 +698,7 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
{
hwif->autodma = 0;
- hwif->tuneproc = &ali15x3_tune_drive;
+ hwif->set_pio_mode = &ali_set_pio_mode;
hwif->speedproc = &ali15x3_tune_chipset;
hwif->udma_filter = &ali_udma_filter;
@@ -817,9 +820,9 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = {
.init_chipset = init_chipset_ali15x3,
.init_hwif = init_hwif_ali15x3,
.init_dma = init_dma_ali15x3,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO5,
};
/**
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 8d30b99a54d8..513205e52ad2 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -1,5 +1,5 @@
/*
- * Version 2.20
+ * Version 2.22
*
* AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04
* IDE driver for Linux.
@@ -234,7 +234,7 @@ static void amd_set_speed(struct pci_dev *dev, unsigned char dn, struct ide_timi
* by upper layers.
*/
-static int amd_set_drive(ide_drive_t *drive, u8 speed)
+static int amd_set_drive(ide_drive_t *drive, const u8 speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct ide_timing t, p;
@@ -266,32 +266,21 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed)
}
/*
- * amd74xx_tune_drive() is a callback from upper layers for
- * PIO-only tuning.
+ * amd_set_pio_mode() is a callback from upper layers for PIO-only tuning.
*/
-static void amd74xx_tune_drive(ide_drive_t *drive, u8 pio)
+static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- if (pio == 255) {
- amd_set_drive(drive, ide_find_best_pio_mode(drive));
- return;
- }
-
- amd_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
+ amd_set_drive(drive, XFER_PIO_0 + pio);
}
static int amd74xx_ide_dma_check(ide_drive_t *drive)
{
- u8 speed = ide_max_dma_mode(drive);
-
- if (speed == 0)
- speed = ide_find_best_pio_mode(drive);
-
- amd_set_drive(drive, speed);
-
- if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+ if (ide_tune_dma(drive))
return 0;
+ ide_set_max_pio(drive);
+
return -1;
}
@@ -409,7 +398,7 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
hwif->autodma = 0;
- hwif->tuneproc = &amd74xx_tune_drive;
+ hwif->set_pio_mode = &amd_set_pio_mode;
hwif->speedproc = &amd_set_drive;
for (i = 0; i < 2; i++) {
@@ -448,10 +437,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.name = name_str, \
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
- .channels = 2, \
.autodma = AUTODMA, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
.bootable = ON_BOARD, \
+ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \
+ | IDE_HFLAG_PIO_NO_DOWNGRADE, \
+ .pio_mask = ATA_PIO5, \
}
#define DECLARE_NV_DEV(name_str) \
@@ -459,10 +450,12 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.name = name_str, \
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
- .channels = 2, \
.autodma = AUTODMA, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
.bootable = ON_BOARD, \
+ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \
+ | IDE_HFLAG_PIO_NO_DOWNGRADE, \
+ .pio_mask = ATA_PIO5, \
}
static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 2761510309b3..178876a3afca 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -1,9 +1,8 @@
/*
- * linux/drivers/ide/pci/atiixp.c Version 0.01-bart2 Feb. 26, 2004
+ * linux/drivers/ide/pci/atiixp.c Version 0.02 Jun 16 2007
*
* Copyright (C) 2003 ATI Inc. <hyu@ati.com>
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
- *
+ * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
*/
#include <linux/types.h>
@@ -123,14 +122,14 @@ static void atiixp_dma_host_off(ide_drive_t *drive)
}
/**
- * atiixp_tune_drive - tune a drive attached to a ATIIXP
+ * atiixp_tune_pio - tune a drive attached to a ATIIXP
* @drive: drive to tune
* @pio: desired PIO mode
*
* Set the interface PIO mode.
*/
-static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
+static void atiixp_tune_pio(ide_drive_t *drive, u8 pio)
{
struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags;
@@ -154,26 +153,30 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
spin_unlock_irqrestore(&atiixp_lock, flags);
}
+static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ atiixp_tune_pio(drive, pio);
+ (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
+}
+
/**
* atiixp_tune_chipset - tune a ATIIXP interface
* @drive: IDE drive to tune
- * @xferspeed: speed to configure
+ * @speed: speed to configure
*
* Set a ATIIXP interface channel to the desired speeds. This involves
* requires the right timing data into the ATIIXP configuration space
* then setting the drive parameters appropriately
*/
-static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
+static int atiixp_speedproc(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = drive->hwif->pci_dev;
unsigned long flags;
int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8;
u32 tmp32;
u16 tmp16;
- u8 speed, pio;
-
- speed = ide_rate_filter(drive, xferspeed);
+ u8 pio;
spin_lock_irqsave(&atiixp_lock, flags);
@@ -201,7 +204,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
else
pio = speed - XFER_PIO_0;
- atiixp_tuneproc(drive, pio);
+ atiixp_tune_pio(drive, pio);
return ide_config_drive_speed(drive, speed);
}
@@ -216,18 +219,13 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
static int atiixp_dma_check(ide_drive_t *drive)
{
- u8 tspeed, speed;
-
drive->init_speed = 0;
if (ide_tune_dma(drive))
return 0;
- if (ide_use_fast_pio(drive)) {
- tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
- speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
- atiixp_speedproc(drive, speed);
- }
+ if (ide_use_fast_pio(drive))
+ ide_set_max_pio(drive);
return -1;
}
@@ -250,7 +248,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->irq = ch ? 15 : 14;
hwif->autodma = 0;
- hwif->tuneproc = &atiixp_tuneproc;
+ hwif->set_pio_mode = &atiixp_set_pio_mode;
hwif->speedproc = &atiixp_speedproc;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
@@ -285,17 +283,18 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
{ /* 0 */
.name = "ATIIXP",
.init_hwif = init_hwif_atiixp,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
},{ /* 1 */
.name = "SB600_PATA",
.init_hwif = init_hwif_atiixp,
- .channels = 1,
.autodma = AUTODMA,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
},
};
@@ -318,7 +317,7 @@ static struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index dc43f009acab..f369645e4d16 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -628,50 +628,42 @@ static void cmd640_set_mode (unsigned int index, u8 pio_mode, unsigned int cycle
program_drive_counts (index);
}
-/*
- * Drive PIO mode selection:
- */
-static void cmd640_tune_drive (ide_drive_t *drive, u8 mode_wanted)
+static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
+ unsigned int index = 0, cycle_time;
u8 b;
- ide_pio_data_t d;
- unsigned int index = 0;
while (drive != cmd_drives[index]) {
if (++index > 3) {
- printk("%s: bad news in cmd640_tune_drive\n", drive->name);
+ printk(KERN_ERR "%s: bad news in %s\n",
+ drive->name, __FUNCTION__);
return;
}
}
- switch (mode_wanted) {
+ switch (pio) {
case 6: /* set fast-devsel off */
case 7: /* set fast-devsel on */
- mode_wanted &= 1;
b = get_cmd640_reg(CNTRL) & ~0x27;
- if (mode_wanted)
+ if (pio & 1)
b |= 0x27;
put_cmd640_reg(CNTRL, b);
- printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, mode_wanted ? "en" : "dis");
+ printk("%s: %sabled cmd640 fast host timing (devsel)\n", drive->name, (pio & 1) ? "en" : "dis");
return;
case 8: /* set prefetch off */
case 9: /* set prefetch on */
- mode_wanted &= 1;
- set_prefetch_mode(index, mode_wanted);
- printk("%s: %sabled cmd640 prefetch\n", drive->name, mode_wanted ? "en" : "dis");
+ set_prefetch_mode(index, pio & 1);
+ printk("%s: %sabled cmd640 prefetch\n", drive->name, (pio & 1) ? "en" : "dis");
return;
}
- (void) ide_get_best_pio_mode (drive, mode_wanted, 5, &d);
- cmd640_set_mode (index, d.pio_mode, d.cycle_time);
+ cycle_time = ide_pio_cycle_time(drive, pio);
+ cmd640_set_mode(index, pio, cycle_time);
+
+ printk("%s: selected cmd640 PIO mode%d (%dns)",
+ drive->name, pio, cycle_time);
- printk ("%s: selected cmd640 PIO mode%d (%dns)%s",
- drive->name,
- d.pio_mode,
- d.cycle_time,
- d.overridden ? " (overriding vendor mode)" : "");
display_clocks(index);
- return;
}
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
@@ -769,7 +761,10 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif0->name, 'a' + cmd640_chip_version - 1, bus_type, cfr);
cmd_hwif0->chipset = ide_cmd640;
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- cmd_hwif0->tuneproc = &cmd640_tune_drive;
+ cmd_hwif0->host_flags = IDE_HFLAG_ABUSE_PREFETCH |
+ IDE_HFLAG_ABUSE_FAST_DEVSEL;
+ cmd_hwif0->pio_mask = ATA_PIO5;
+ cmd_hwif0->set_pio_mode = &cmd640_set_pio_mode;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
/*
@@ -824,7 +819,10 @@ int __init ide_probe_for_cmd640x (void)
cmd_hwif1->mate = cmd_hwif0;
cmd_hwif1->channel = 1;
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
- cmd_hwif1->tuneproc = &cmd640_tune_drive;
+ cmd_hwif1->host_flags = IDE_HFLAG_ABUSE_PREFETCH |
+ IDE_HFLAG_ABUSE_FAST_DEVSEL;
+ cmd_hwif1->pio_mask = ATA_PIO5;
+ cmd_hwif1->set_pio_mode = &cmd640_set_pio_mode;
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
}
printk(KERN_INFO "%s: %sserialized, secondary interface %s\n", cmd_hwif1->name,
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index 1e89dd6e5bbf..0b568c60f926 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -214,27 +214,25 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_
}
/*
- * This routine selects drive's best PIO mode and writes into the chipset
- * registers setup/active/recovery timings.
+ * This routine writes into the chipset registers
+ * PIO setup/active/recovery timings.
*/
-static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted)
+static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- ide_pio_data_t pio;
- u8 pio_mode, setup_count, arttim = 0;
+ unsigned int cycle_time;
+ u8 setup_count, arttim = 0;
+
static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
- pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio);
- cmdprintk("%s: PIO mode wanted %d, selected %d (%d ns)%s\n",
- drive->name, mode_wanted, pio_mode, pio.cycle_time,
- pio.overridden ? " (overriding vendor mode)" : "");
+ cycle_time = ide_pio_cycle_time(drive, pio);
- program_cycle_times(drive, pio.cycle_time,
- ide_pio_timings[pio_mode].active_time);
+ program_cycle_times(drive, cycle_time,
+ ide_pio_timings[pio].active_time);
- setup_count = quantize_timing(ide_pio_timings[pio_mode].setup_time,
+ setup_count = quantize_timing(ide_pio_timings[pio].setup_time,
1000 / system_bus_clock());
/*
@@ -265,16 +263,14 @@ static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted)
arttim |= setup_values[setup_count];
(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]);
-
- return pio_mode;
}
/*
* Attempts to set drive's PIO mode.
- * Special cases are 8: prefetch off, 9: prefetch on (both never worked),
- * and 255: auto-select best mode (used at boot time).
+ * Special cases are 8: prefetch off, 9: prefetch on (both never worked)
*/
-static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio)
+
+static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
/*
* Filter out the prefetch control values
@@ -283,19 +279,17 @@ static void cmd64x_tune_drive (ide_drive_t *drive, u8 pio)
if (pio == 8 || pio == 9)
return;
- pio = cmd64x_tune_pio(drive, pio);
+ cmd64x_tune_pio(drive, pio);
(void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
-static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed)
+static int cmd64x_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 unit = drive->dn & 0x01;
u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0;
- speed = ide_rate_filter(drive, speed);
-
if (speed >= XFER_SW_DMA_0) {
(void) pci_read_config_byte(dev, pciU, &regU);
regU &= ~(unit ? 0xCA : 0x35);
@@ -329,14 +323,6 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, u8 speed)
case XFER_MW_DMA_0:
program_cycle_times(drive, 480, 215);
break;
- case XFER_PIO_5:
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- (void) cmd64x_tune_pio(drive, speed - XFER_PIO_0);
- break;
default:
return 1;
}
@@ -353,7 +339,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- cmd64x_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -474,11 +460,11 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha
switch (rev) {
case 0x07:
case 0x05:
- printk("%s: UltraDMA capable", name);
+ printk("%s: UltraDMA capable\n", name);
break;
case 0x03:
default:
- printk("%s: MultiWord DMA force limited", name);
+ printk("%s: MultiWord DMA force limited\n", name);
break;
case 0x01:
printk("%s: MultiWord DMA limited, "
@@ -537,7 +523,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
- hwif->tuneproc = &cmd64x_tune_drive;
+ hwif->set_pio_mode = &cmd64x_set_pio_mode;
hwif->speedproc = &cmd64x_tune_chipset;
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
@@ -618,40 +604,44 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
.init_setup = init_setup_cmd64x,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .pio_mask = ATA_PIO5,
.udma_mask = 0x00, /* no udma */
},{ /* 1 */
.name = "CMD646",
.init_setup = init_setup_cmd646,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .pio_mask = ATA_PIO5,
.udma_mask = 0x07, /* udma0-2 */
},{ /* 2 */
.name = "CMD648",
.init_setup = init_setup_cmd64x,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .pio_mask = ATA_PIO5,
.udma_mask = 0x1f, /* udma0-4 */
},{ /* 3 */
.name = "CMD649",
.init_setup = init_setup_cmd64x,
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH,
+ .pio_mask = ATA_PIO5,
.udma_mask = 0x3f, /* udma0-5 */
}
};
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index 3b88a3a56116..1217d2a747fb 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -66,32 +66,13 @@ static struct pio_clocks cs5520_pio_clocks[]={
{1, 2, 1}
};
-static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed)
+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;
- u8 speed = min((u8)XFER_PIO_4, xferspeed);
- int pio = speed;
- u8 reg;
int controller = drive->dn > 1 ? 1 : 0;
- int error;
-
- switch(speed)
- {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- pio -= XFER_PIO_0;
- break;
- default:
- pio = 0;
- printk(KERN_ERR "cs55x0: bad ide timing.\n");
- }
-
- printk("PIO clocking = %d\n", pio);
-
+ u8 reg;
+
/* FIXME: if DMA = 1 do we need to set the DMA bit here ? */
/* 8bit CAT/CRT - 8bit command timing for channel */
@@ -115,25 +96,28 @@ static int cs5520_tune_chipset(ide_drive_t *drive, u8 xferspeed)
reg = inb(hwif->dma_base + 0x02 + 8*controller);
reg |= 1<<((drive->dn&1)+5);
outb(reg, hwif->dma_base + 0x02 + 8*controller);
-
- error = ide_config_drive_speed(drive, speed);
- /* ATAPI is harder so leave it for now */
- if(!error && drive->media == ide_disk)
- error = hwif->ide_dma_on(drive);
- return error;
-}
-
-static void cs5520_tune_drive(ide_drive_t *drive, u8 pio)
+ (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
+}
+
+static int cs5520_tune_chipset(ide_drive_t *drive, const u8 speed)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
- cs5520_tune_chipset(drive, (XFER_PIO_0 + pio));
+ printk(KERN_ERR "cs55x0: bad ide timing.\n");
+
+ cs5520_set_pio_mode(drive, 0);
+
+ /*
+ * FIXME: this is incorrect to return zero here but
+ * since all users of ide_set_xfer_rate() ignore
+ * the return value it is not a problem currently
+ */
+ return 0;
}
static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
{
/* Tune the drive for PIO modes up to PIO 4 */
- cs5520_tune_drive(drive, 4);
+ ide_set_max_pio(drive);
/* Then tell the core to use DMA operations */
return 0;
@@ -165,7 +149,7 @@ static int cs5520_dma_on(ide_drive_t *drive)
static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
{
- hwif->tuneproc = &cs5520_tune_drive;
+ hwif->set_pio_mode = &cs5520_set_pio_mode;
hwif->speedproc = &cs5520_tune_chipset;
hwif->ide_dma_check = &cs5520_config_drive_xfer_rate;
hwif->ide_dma_on = &cs5520_dma_on;
@@ -179,7 +163,8 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
hwif->drives[1].autotune = 1;
return;
}
-
+
+ /* ATAPI is harder so leave it for now */
hwif->atapi_dma = 0;
hwif->ultra_mask = 0;
hwif->swdma_mask = 0;
@@ -194,10 +179,10 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
.name = name_str, \
.init_setup_dma = cs5520_init_setup_dma, \
.init_hwif = init_hwif_cs5520, \
- .channels = 2, \
.autodma = AUTODMA, \
.bootable = ON_BOARD, \
- .flags = IDEPCI_FLAG_ISA_PORTS, \
+ .host_flags = IDE_HFLAG_ISA_PORTS, \
+ .pio_mask = ATA_PIO4, \
}
static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index b5c00d15a704..741507b4cd93 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007
+ * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2000 Mark Lord <mlord@pobox.com>
@@ -71,19 +71,18 @@ static void cs5530_tunepio(ide_drive_t *drive, u8 pio)
}
/**
- * cs5530_tuneproc - select/set PIO modes
+ * cs5530_set_pio_mode - set PIO mode
+ * @drive: drive
+ * @pio: PIO mode number
*
- * cs5530_tuneproc() handles selection/setting of PIO modes
- * for both the chipset and drive.
+ * Handles setting of PIO mode for both the chipset and drive.
*
- * The ide_init_cs5530() routine guarantees that all drives
+ * The init_hwif_cs5530() routine guarantees that all drives
* will have valid default PIO timings set up before we get here.
*/
-static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autotune" */
+static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-
if (cs5530_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
cs5530_tunepio(drive, pio);
}
@@ -143,13 +142,11 @@ static int cs5530_config_dma(ide_drive_t *drive)
return 1;
}
-static int cs5530_tune_chipset(ide_drive_t *drive, u8 mode)
+static int cs5530_tune_chipset(ide_drive_t *drive, const u8 mode)
{
unsigned long basereg;
unsigned int reg, timings = 0;
- mode = ide_rate_filter(drive, mode);
-
/*
* Tell the drive to switch to the new mode; abort on failure.
*/
@@ -166,13 +163,6 @@ static int cs5530_tune_chipset(ide_drive_t *drive, 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;
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- cs5530_tunepio(drive, mode - XFER_PIO_0);
- return 0;
default:
BUG();
break;
@@ -207,6 +197,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
unsigned long flags;
+ if (pci_resource_start(dev, 4) == 0)
+ return -EFAULT;
+
dev = NULL;
while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
switch (dev->device) {
@@ -305,7 +298,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
if (hwif->mate)
hwif->serialized = hwif->mate->serialized = 1;
- hwif->tuneproc = &cs5530_tuneproc;
+ hwif->set_pio_mode = &cs5530_set_pio_mode;
hwif->speedproc = &cs5530_tune_chipset;
basereg = CS5530_BASEREG(hwif);
@@ -325,6 +318,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
/* needs autotuning later */
}
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->ultra_mask = 0x07;
hwif->mwdma_mask = 0x07;
@@ -341,9 +337,9 @@ static ide_pci_device_t cs5530_chipset __devinitdata = {
.name = "CS5530",
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
};
static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 10f61f38243c..383b7eccbcbb 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -2,6 +2,7 @@
* linux/drivers/ide/pci/cs5535.c
*
* Copyright (C) 2004-2005 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*
* History:
* 09/20/2005 - Jaya Kumar <jayakumar.ide@gmail.com>
@@ -74,7 +75,7 @@ static unsigned int cs5535_udma_timings[5] =
*
* cs5535_set_speed() configures the chipset to a new speed.
*/
-static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
+static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
{
u32 reg = 0, dummy;
@@ -83,14 +84,17 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
/* Set the PIO timings */
if ((speed & XFER_MODE) == XFER_PIO) {
- u8 pioa;
- u8 piob;
- u8 cmd;
+ ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1];
+ u8 cmd, pioa;
- pioa = speed - XFER_PIO_0;
- piob = ide_get_best_pio_mode(&(drive->hwif->drives[!unit]),
- 255, 4, NULL);
- cmd = pioa < piob ? pioa : piob;
+ cmd = pioa = speed - XFER_PIO_0;
+
+ if (pair->present) {
+ u8 piob = ide_get_best_pio_mode(pair, 255, 4);
+
+ if (piob < cmd)
+ cmd = piob;
+ }
/* Write the speed of the current drive */
reg = (cs5535_pio_cmd_timings[cmd] << 16) |
@@ -116,7 +120,7 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
reg &= 0x80000000UL; /* Preserve the PIO format bit */
- if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_7)
+ if (speed >= XFER_UDMA_0 && speed <= XFER_UDMA_4)
reg |= cs5535_udma_timings[speed - XFER_UDMA_0];
else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
reg |= cs5535_mwdma_timings[speed - XFER_MW_DMA_0];
@@ -137,46 +141,35 @@ static void cs5535_set_speed(ide_drive_t *drive, u8 speed)
*/
static int cs5535_set_drive(ide_drive_t *drive, u8 speed)
{
- speed = ide_rate_filter(drive, speed);
ide_config_drive_speed(drive, speed);
cs5535_set_speed(drive, speed);
return 0;
}
-/****
- * cs5535_tuneproc - PIO setup
- * @drive: drive to set up
- * @pio: mode to use (255 for 'best possible')
+/**
+ * cs5535_set_pio_mode - PIO setup
+ * @drive: drive
+ * @pio: PIO mode number
*
* A callback from the upper layers for PIO-only tuning.
*/
-static void cs5535_tuneproc(ide_drive_t *drive, u8 xferspeed)
+
+static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- u8 modes[] = { XFER_PIO_0, XFER_PIO_1, XFER_PIO_2, XFER_PIO_3,
- XFER_PIO_4 };
-
- /* cs5535 max pio is pio 4, best_pio will check the blacklist.
- i think we don't need to rate_filter the incoming xferspeed
- since we know we're only going to choose pio */
- xferspeed = ide_get_best_pio_mode(drive, xferspeed, 4, NULL);
- ide_config_drive_speed(drive, modes[xferspeed]);
- cs5535_set_speed(drive, xferspeed);
+ ide_config_drive_speed(drive, XFER_PIO_0 + pio);
+ cs5535_set_speed(drive, XFER_PIO_0 + pio);
}
static int cs5535_dma_check(ide_drive_t *drive)
{
- u8 speed;
-
drive->init_speed = 0;
if (ide_tune_dma(drive))
return 0;
- if (ide_use_fast_pio(drive)) {
- speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
- cs5535_set_drive(drive, speed);
- }
+ if (ide_use_fast_pio(drive))
+ ide_set_max_pio(drive);
return -1;
}
@@ -205,7 +198,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
hwif->autodma = 0;
- hwif->tuneproc = &cs5535_tuneproc;
+ hwif->set_pio_mode = &cs5535_set_pio_mode;
hwif->speedproc = &cs5535_set_drive;
hwif->ide_dma_check = &cs5535_dma_check;
@@ -228,9 +221,10 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
static ide_pci_device_t cs5535_chipset __devinitdata = {
.name = "CS5535",
.init_hwif = init_hwif_cs5535,
- .channels = 1,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
};
static int __devinit cs5535_init_one(struct pci_dev *dev,
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 103b9db97853..dc278025d318 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -97,9 +97,6 @@
#define CY82_INDEX_CHANNEL1 0x31
#define CY82_INDEX_TIMEOUT 0x32
-/* the max PIO mode - from datasheet */
-#define CY82C693_MAX_PIO 4
-
/* the min and max PCI bus speed in MHz - from datasheet */
#define CY82C963_MIN_BUS_SPEED 25
#define CY82C963_MAX_BUS_SPEED 33
@@ -148,9 +145,6 @@ static void compute_clocks (u8 pio, pio_clocks_t *p_pclk)
* so you can play with the idebus=xx parameter
*/
- if (pio > CY82C693_MAX_PIO)
- pio = CY82C693_MAX_PIO;
-
/* let's calc the address setup time clocks */
p_pclk->address_time = (u8)calc_clk(ide_pio_timings[pio].setup_time, bus_speed);
@@ -269,10 +263,7 @@ static int cy82c693_ide_dma_on (ide_drive_t *drive)
return __ide_dma_on(drive);
}
-/*
- * tune ide drive - set PIO mode
- */
-static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
+static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -329,13 +320,6 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio)
addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
#endif /* CY82C693_DEBUG_LOGS */
- /* first let's calc the pio modes */
- pio = ide_get_best_pio_mode(drive, pio, CY82C693_MAX_PIO, NULL);
-
-#if CY82C693_DEBUG_INFO
- printk (KERN_INFO "%s: Selected PIO mode %d\n", drive->name, pio);
-#endif /* CY82C693_DEBUG_INFO */
-
/* let's calc the values for this PIO mode */
compute_clocks(pio, &pclk);
@@ -447,7 +431,7 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->chipset = ide_cy82c693;
- hwif->tuneproc = &cy82c693_tune_drive;
+ hwif->set_pio_mode = &cy82c693_set_pio_mode;
if (!hwif->dma_base) {
hwif->drives[0].autotune = 1;
@@ -483,9 +467,10 @@ static ide_pci_device_t cy82c693_chipset __devinitdata = {
.init_chipset = init_chipset_cy82c693,
.init_iops = init_iops_cy82c693,
.init_hwif = init_hwif_cy82c693,
- .channels = 1,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
};
static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 0d51a11e81da..48caa468b762 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -95,92 +95,77 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
{ /* 0 */
.name = "Unknown",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
},{ /* 1 */
.name = "NS87410",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
.bootable = ON_BOARD,
},{ /* 2 */
.name = "SAMURAI",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
},{ /* 3 */
.name = "HT6565",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
},{ /* 4 */
.name = "UM8673F",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NODMA,
.bootable = ON_BOARD,
},{ /* 5 */
.name = "UM8886A",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NODMA,
.bootable = ON_BOARD,
},{ /* 6 */
.name = "UM8886BF",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NODMA,
.bootable = ON_BOARD,
},{ /* 7 */
.name = "HINT_IDE",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
},{ /* 8 */
.name = "VIA_IDE",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = ON_BOARD,
},{ /* 9 */
.name = "OPTI621V",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = ON_BOARD,
},{ /* 10 */
.name = "VIA8237SATA",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
},{ /* 11 */
.name = "Piccolo0102",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = ON_BOARD,
},{ /* 12 */
.name = "Piccolo0103",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = ON_BOARD,
},{ /* 13 */
.name = "Piccolo0105",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = ON_BOARD,
},{ /* 14 */
.name = "Revolution",
.init_hwif = init_hwif_generic,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
}
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 2c24c3de8846..a1bb10188fe5 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -43,10 +43,9 @@
#define HPT343_DEBUG_DRIVE_INFO 0
-static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int hpt34x_tune_chipset(ide_drive_t *drive, const u8 speed)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
- u8 speed = ide_rate_filter(drive, xferspeed);
u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
u8 hi_speed, lo_speed;
@@ -78,9 +77,8 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return(ide_config_drive_speed(drive, speed));
}
-static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
+static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
(void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
}
@@ -89,14 +87,10 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
drive->init_speed = 0;
if (ide_tune_dma(drive))
-#ifndef CONFIG_HPT34X_AUTODMA
return -1;
-#else
- return 0;
-#endif
if (ide_use_fast_pio(drive))
- hpt34x_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -120,17 +114,10 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha
pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
- if (cmd & PCI_COMMAND_MEMORY) {
- if (pci_resource_start(dev, PCI_ROM_RESOURCE)) {
- pci_write_config_dword(dev, PCI_ROM_ADDRESS,
- dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n",
- (unsigned long)dev->resource[PCI_ROM_RESOURCE].start);
- }
+ if (cmd & PCI_COMMAND_MEMORY)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
- } else {
+ else
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
- }
/*
* Since 20-23 can be assigned and are R/W, we correct them.
@@ -157,7 +144,7 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
hwif->autodma = 0;
- hwif->tuneproc = &hpt34x_tune_drive;
+ hwif->set_pio_mode = &hpt34x_set_pio_mode;
hwif->speedproc = &hpt34x_tune_chipset;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
@@ -167,9 +154,11 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
if (!hwif->dma_base)
return;
+#ifdef CONFIG_HPT34X_AUTODMA
hwif->ultra_mask = 0x07;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
+#endif
hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate;
if (!noautodma)
@@ -182,10 +171,10 @@ static ide_pci_device_t hpt34x_chipset __devinitdata = {
.name = "HPT34X",
.init_chipset = init_chipset_hpt34x,
.init_hwif = init_hwif_hpt34x,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = NEVER_BOARD,
- .extra = 16
+ .extra = 16,
+ .pio_mask = ATA_PIO5,
};
static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index e9b07a97c340..0e7d3b60d43c 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.10 Jun 29, 2007
+ * linux/drivers/ide/pci/hpt366.c Version 1.13 Sep 29, 2007
*
* Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org>
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
@@ -68,7 +68,8 @@
* HPT37x chip family; save space by introducing the separate transfer mode
* table in which the mode lookup is done
* - use f_CNT value saved by the HighPoint BIOS as reading it directly gives
- * the wrong PCI frequency since DPLL has already been calibrated by BIOS
+ * the wrong PCI frequency since DPLL has already been calibrated by BIOS;
+ * read it only from the function 0 of HPT374 chips
* - fix the hotswap code: it caused RESET- to glitch when tristating the bus,
* and for HPT36x the obsolete HDIO_TRISTATE_HWIF handler was called instead
* - pass to init_chipset() handlers a copy of the IDE PCI device structure as
@@ -113,6 +114,7 @@
* unify HPT36x/37x timing setup code and the speedproc handlers by joining
* the register setting lists into the table indexed by the clock selected
* - set the correct hwif->ultra_mask for each individual chip
+ * - add Ultra and MW DMA mode filtering for the HPT37[24] based SATA cards
* Sergei Shtylyov, <sshtylyov@ru.mvista.com> or <source@mvista.com>
*/
@@ -517,47 +519,67 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
}
/*
- * Note for the future; the SATA hpt37x we must set
- * either PIO or UDMA modes 0,4,5
+ * The Marvell bridge chips used on the HighPoint SATA cards do not seem
+ * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
*/
static u8 hpt3xx_udma_filter(ide_drive_t *drive)
{
- struct hpt_info *info = pci_get_drvdata(HWIF(drive)->pci_dev);
- u8 mask;
+ ide_hwif_t *hwif = HWIF(drive);
+ struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
+ u8 mask = hwif->ultra_mask;
switch (info->chip_type) {
- case HPT370A:
- if (!HPT370_ALLOW_ATA100_5 ||
- check_in_drive_list(drive, bad_ata100_5))
- return 0x1f;
- else
- return 0x3f;
- case HPT370:
- if (!HPT370_ALLOW_ATA100_5 ||
- check_in_drive_list(drive, bad_ata100_5))
- mask = 0x1f;
- else
- mask = 0x3f;
- break;
case HPT36x:
if (!HPT366_ALLOW_ATA66_4 ||
check_in_drive_list(drive, bad_ata66_4))
- mask = 0x0f;
- else
- mask = 0x1f;
+ mask = ATA_UDMA3;
if (!HPT366_ALLOW_ATA66_3 ||
check_in_drive_list(drive, bad_ata66_3))
- mask = 0x07;
+ mask = ATA_UDMA2;
+ break;
+ case HPT370:
+ if (!HPT370_ALLOW_ATA100_5 ||
+ check_in_drive_list(drive, bad_ata100_5))
+ mask = ATA_UDMA4;
break;
+ case HPT370A:
+ if (!HPT370_ALLOW_ATA100_5 ||
+ check_in_drive_list(drive, bad_ata100_5))
+ return ATA_UDMA4;
+ case HPT372 :
+ case HPT372A:
+ case HPT372N:
+ case HPT374 :
+ if (ide_dev_is_sata(drive->id))
+ mask &= ~0x0e;
+ /* Fall thru */
default:
- return 0x7f;
+ return mask;
}
return check_in_drive_list(drive, bad_ata33) ? 0x00 : mask;
}
+static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct hpt_info *info = pci_get_drvdata(hwif->pci_dev);
+
+ switch (info->chip_type) {
+ case HPT372 :
+ case HPT372A:
+ case HPT372N:
+ case HPT374 :
+ if (ide_dev_is_sata(drive->id))
+ return 0x00;
+ /* Fall thru */
+ default:
+ return 0x07;
+ }
+}
+
static u32 get_speed_setting(u8 speed, struct hpt_info *info)
{
int i;
@@ -578,20 +600,15 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
return (*info->settings)[i];
}
-static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
+static int hpt36x_tune_chipset(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 speed = ide_rate_filter(drive, xferspeed);
u8 itr_addr = drive->dn ? 0x44 : 0x40;
u32 old_itr = 0;
u32 itr_mask, new_itr;
- /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
- if (drive->media != ide_disk)
- speed = min_t(u8, speed, XFER_PIO_4);
-
itr_mask = speed < XFER_MW_DMA_0 ? 0x30070000 :
(speed < XFER_UDMA_0 ? 0xc0070000 : 0xc03800ff);
@@ -610,20 +627,15 @@ static int hpt36x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
return ide_config_drive_speed(drive, speed);
}
-static int hpt37x_tune_chipset(ide_drive_t *drive, u8 xferspeed)
+static int hpt37x_tune_chipset(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 speed = ide_rate_filter(drive, xferspeed);
u8 itr_addr = 0x40 + (drive->dn * 4);
u32 old_itr = 0;
u32 itr_mask, new_itr;
- /* TODO: move this to ide_rate_filter() [ check ->atapi_dma ] */
- if (drive->media != ide_disk)
- speed = min_t(u8, speed, XFER_PIO_4);
-
itr_mask = speed < XFER_MW_DMA_0 ? 0x303c0000 :
(speed < XFER_UDMA_0 ? 0xc03c0000 : 0xc1c001ff);
@@ -650,9 +662,8 @@ static int hpt3xx_tune_chipset(ide_drive_t *drive, u8 speed)
return hpt36x_tune_chipset(drive, speed);
}
-static void hpt3xx_tune_drive(ide_drive_t *drive, u8 pio)
+static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void) hpt3xx_tune_chipset (drive, XFER_PIO_0 + pio);
}
@@ -714,7 +725,7 @@ static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- hpt3xx_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -981,6 +992,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
unsigned long io_base = pci_resource_start(dev, 4);
u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */
+ u8 chip_type;
enum ata_clock clock;
if (info == NULL) {
@@ -992,15 +1004,8 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
* Copy everything from a static "template" structure
* to just allocated per-chip hpt_info structure.
*/
- *info = *(struct hpt_info *)pci_get_drvdata(dev);
-
- /*
- * FIXME: Not portable. Also, why do we enable the ROM in the first place?
- * We don't seem to be using it.
- */
- if (dev->resource[PCI_ROM_RESOURCE].start)
- pci_write_config_dword(dev, PCI_ROM_ADDRESS,
- dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+ memcpy(info, pci_get_drvdata(dev), sizeof(struct hpt_info));
+ chip_type = info->chip_type;
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
@@ -1010,7 +1015,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
/*
* First, try to estimate the PCI clock frequency...
*/
- if (info->chip_type >= HPT370) {
+ if (chip_type >= HPT370) {
u8 scr1 = 0;
u16 f_cnt = 0;
u32 temp = 0;
@@ -1024,7 +1029,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
* HighPoint does this for HPT372A.
* NOTE: This register is only writeable via I/O space.
*/
- if (info->chip_type == HPT372A)
+ if (chip_type == HPT372A)
outb(0x0e, io_base + 0x9c);
/*
@@ -1042,13 +1047,28 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
* First try reading the register in which the HighPoint BIOS
* saves f_CNT value before reprogramming the DPLL from its
* default setting (which differs for the various chips).
- * NOTE: This register is only accessible via I/O space.
*
- * In case the signature check fails, we'll have to resort to
- * reading the f_CNT register itself in hopes that nobody has
- * touched the DPLL yet...
+ * NOTE: This register is only accessible via I/O space;
+ * HPT374 BIOS only saves it for the function 0, so we have to
+ * always read it from there -- no need to check the result of
+ * pci_get_slot() for the function 0 as the whole device has
+ * been already "pinned" (via function 1) in init_setup_hpt374()
+ */
+ if (chip_type == HPT374 && (PCI_FUNC(dev->devfn) & 1)) {
+ struct pci_dev *dev1 = pci_get_slot(dev->bus,
+ dev->devfn - 1);
+ unsigned long io_base = pci_resource_start(dev1, 4);
+
+ temp = inl(io_base + 0x90);
+ pci_dev_put(dev1);
+ } else
+ temp = inl(io_base + 0x90);
+
+ /*
+ * In case the signature check fails, we'll have to
+ * resort to reading the f_CNT register itself in hopes
+ * that nobody has touched the DPLL yet...
*/
- temp = inl(io_base + 0x90);
if ((temp & 0xFFFFF000) != 0xABCDE000) {
int i;
@@ -1128,7 +1148,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 (info->chip_type >= HPT374 || info->settings[clock] == NULL) {
+ if (chip_type >= HPT374 || info->settings[clock] == NULL) {
u16 f_low, delta = pci_clk < 50 ? 2 : 4;
int adjust;
@@ -1198,7 +1218,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
/* Point to this chip's own instance of the hpt_info structure. */
pci_set_drvdata(dev, info);
- if (info->chip_type >= HPT370) {
+ if (chip_type >= HPT370) {
u8 mcr1, mcr4;
/*
@@ -1217,7 +1237,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
* the MISC. register to stretch the UltraDMA Tss timing.
* NOTE: This register is only writeable via I/O space.
*/
- if (info->chip_type == HPT371N && clock == ATA_CLOCK_66MHZ)
+ if (chip_type == HPT371N && clock == ATA_CLOCK_66MHZ)
outb(inb(io_base + 0x9c) | 0x04, io_base + 0x9c);
@@ -1226,25 +1246,25 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha
static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
{
- struct pci_dev *dev = hwif->pci_dev;
- struct hpt_info *info = pci_get_drvdata(dev);
- int serialize = HPT_SERIALIZE_IO;
- u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02;
- u8 chip_type = info->chip_type;
- u8 new_mcr, old_mcr = 0;
+ struct pci_dev *dev = hwif->pci_dev;
+ struct hpt_info *info = pci_get_drvdata(dev);
+ int serialize = HPT_SERIALIZE_IO;
+ u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02;
+ u8 chip_type = info->chip_type;
+ u8 new_mcr, old_mcr = 0;
/* Cache the channel's MISC. control registers' offset */
- hwif->select_data = hwif->channel ? 0x54 : 0x50;
+ hwif->select_data = hwif->channel ? 0x54 : 0x50;
- hwif->tuneproc = &hpt3xx_tune_drive;
- hwif->speedproc = &hpt3xx_tune_chipset;
- hwif->quirkproc = &hpt3xx_quirkproc;
- hwif->intrproc = &hpt3xx_intrproc;
- hwif->maskproc = &hpt3xx_maskproc;
- hwif->busproc = &hpt3xx_busproc;
+ hwif->set_pio_mode = &hpt3xx_set_pio_mode;
+ hwif->speedproc = &hpt3xx_tune_chipset;
+ hwif->quirkproc = &hpt3xx_quirkproc;
+ hwif->intrproc = &hpt3xx_intrproc;
+ hwif->maskproc = &hpt3xx_maskproc;
+ hwif->busproc = &hpt3xx_busproc;
- if (chip_type <= HPT370A)
- hwif->udma_filter = &hpt3xx_udma_filter;
+ hwif->udma_filter = &hpt3xx_udma_filter;
+ hwif->mdma_filter = &hpt3xx_mdma_filter;
/*
* HPT3xxN chips have some complications:
@@ -1491,22 +1511,22 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d)
* to both functions -- really stupid design decision... :-(
* Bit 4 is for the primary channel, bit 5 for the secondary.
*/
- d->channels = 1;
+ d->host_flags |= IDE_HFLAG_SINGLE;
d->enablebits[0].mask = d->enablebits[0].val = 0x10;
- d->udma_mask = HPT366_ALLOW_ATA66_3 ?
- (HPT366_ALLOW_ATA66_4 ? 0x1f : 0x0f) : 0x07;
+ d->udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ?
+ ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2;
break;
case 3:
case 4:
- d->udma_mask = HPT370_ALLOW_ATA100_5 ? 0x3f : 0x1f;
+ d->udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4;
break;
default:
rev = 6;
/* fall thru */
case 5:
case 6:
- d->udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f;
+ d->udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5;
break;
}
@@ -1554,71 +1574,71 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
.bootable = OFF_BOARD,
- .extra = 240
+ .extra = 240,
+ .pio_mask = ATA_PIO4,
},{ /* 1 */
.name = "HPT372A",
.init_setup = init_setup_hpt372a,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f,
+ .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.bootable = OFF_BOARD,
- .extra = 240
+ .extra = 240,
+ .pio_mask = ATA_PIO4,
},{ /* 2 */
.name = "HPT302",
.init_setup = init_setup_hpt302,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT302_ALLOW_ATA133_6 ? 0x7f : 0x3f,
+ .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.bootable = OFF_BOARD,
- .extra = 240
+ .extra = 240,
+ .pio_mask = ATA_PIO4,
},{ /* 3 */
.name = "HPT371",
.init_setup = init_setup_hpt371,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT371_ALLOW_ATA133_6 ? 0x7f : 0x3f,
+ .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.bootable = OFF_BOARD,
- .extra = 240
+ .extra = 240,
+ .pio_mask = ATA_PIO4,
},{ /* 4 */
.name = "HPT374",
.init_setup = init_setup_hpt374,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .channels = 2, /* 4 */
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = 0x3f,
+ .udma_mask = ATA_UDMA5,
.bootable = OFF_BOARD,
- .extra = 240
+ .extra = 240,
+ .pio_mask = ATA_PIO4,
},{ /* 5 */
.name = "HPT372N",
.init_setup = init_setup_hpt372n,
.init_chipset = init_chipset_hpt366,
.init_hwif = init_hwif_hpt366,
.init_dma = init_dma_hpt366,
- .channels = 2, /* 4 */
.autodma = AUTODMA,
.enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}},
- .udma_mask = HPT372_ALLOW_ATA133_6 ? 0x7f : 0x3f,
+ .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
.bootable = OFF_BOARD,
- .extra = 240
+ .extra = 240,
+ .pio_mask = ATA_PIO4,
}
};
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index ff48c23e571e..76e91ff9420b 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -21,7 +21,7 @@
* it8213_dma_2_pio - return the PIO mode matching DMA
* @xfer_rate: transfer speed
*
- * Returns the nearest equivalent PIO timing for the PIO or DMA
+ * Returns the nearest equivalent PIO timing for the DMA
* mode requested by the controller.
*/
@@ -35,34 +35,28 @@ static u8 it8213_dma_2_pio (u8 xfer_rate) {
case XFER_UDMA_1:
case XFER_UDMA_0:
case XFER_MW_DMA_2:
- case XFER_PIO_4:
return 4;
case XFER_MW_DMA_1:
- case XFER_PIO_3:
return 3;
case XFER_SW_DMA_2:
- case XFER_PIO_2:
return 2;
case XFER_MW_DMA_0:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
- case XFER_PIO_1:
- case XFER_PIO_0:
- case XFER_PIO_SLOW:
default:
return 0;
}
}
/*
- * it8213_tuneproc - tune a drive
+ * it8213_tune_pio - tune a drive
* @drive: drive to tune
* @pio: desired PIO mode
*
* Set the interface PIO mode.
*/
-static void it8213_tuneproc (ide_drive_t *drive, u8 pio)
+static void it8213_tune_pio(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -82,8 +76,6 @@ static void it8213_tuneproc (ide_drive_t *drive, u8 pio)
{ 2, 1 },
{ 2, 3 }, };
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
-
spin_lock_irqsave(&tune_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
@@ -113,23 +105,25 @@ static void it8213_tuneproc (ide_drive_t *drive, u8 pio)
spin_unlock_irqrestore(&tune_lock, flags);
}
+static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ it8213_tune_pio(drive, pio);
+ ide_config_drive_speed(drive, XFER_PIO_0 + pio);
+}
+
/**
* it8213_tune_chipset - set controller timings
* @drive: Drive to set up
- * @xferspeed: speed we want to achieve
+ * @speed: speed we want to achieve
*
- * Tune the ITE chipset for the desired mode. If we can't achieve
- * the desired mode then tune for a lower one, but ultimately
- * make the thing work.
+ * Tune the ITE chipset for the desired mode.
*/
-static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int it8213_tune_chipset(ide_drive_t *drive, const u8 speed)
{
-
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 maslave = 0x40;
- u8 speed = ide_rate_filter(drive, xferspeed);
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int v_flag = 0x01 << drive->dn;
@@ -157,12 +151,6 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_MW_DMA_1:
case XFER_SW_DMA_2:
break;
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- break;
default:
return -1;
}
@@ -193,7 +181,9 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
if (reg55 & w_flag)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
}
- it8213_tuneproc(drive, it8213_dma_2_pio(speed));
+
+ it8213_tune_pio(drive, it8213_dma_2_pio(speed));
+
return ide_config_drive_speed(drive, speed);
}
@@ -209,13 +199,10 @@ static int it8213_tune_chipset (ide_drive_t *drive, u8 xferspeed)
static int it8213_config_drive_for_dma (ide_drive_t *drive)
{
- u8 pio;
-
if (ide_tune_dma(drive))
return 0;
- pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
- it8213_tune_chipset(drive, XFER_PIO_0 + pio);
+ ide_set_max_pio(drive);
return -1;
}
@@ -234,7 +221,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
u8 reg42h = 0;
hwif->speedproc = &it8213_tune_chipset;
- hwif->tuneproc = &it8213_tuneproc;
+ hwif->set_pio_mode = &it8213_set_pio_mode;
hwif->autodma = 0;
@@ -272,10 +259,11 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
{ \
.name = name_str, \
.init_hwif = init_hwif_it8213, \
- .channels = 1, \
.autodma = AUTODMA, \
.enablebits = {{0x41,0x80,0x80}}, \
.bootable = ON_BOARD, \
+ .host_flags = IDE_HFLAG_SINGLE, \
+ .pio_mask = ATA_PIO4, \
}
static ide_pci_device_t it8213_chipsets[] __devinitdata = {
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index 8197b653ba1e..758a98230cc5 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -255,7 +255,7 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
* on the cable.
*/
if (pair) {
- u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4, NULL);
+ u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
/* trim PIO to the slowest of the master/slave */
if (pair_pio < set_pio)
set_pio = pair_pio;
@@ -274,9 +274,8 @@ static int it821x_tunepio(ide_drive_t *drive, u8 set_pio)
return ide_config_drive_speed(drive, XFER_PIO_0 + set_pio);
}
-static void it821x_tuneproc(ide_drive_t *drive, u8 pio)
+static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void)it821x_tunepio(drive, pio);
}
@@ -405,32 +404,19 @@ static int it821x_dma_end(ide_drive_t *drive)
return ret;
}
-
/**
* it821x_tune_chipset - set controller timings
* @drive: Drive to set up
- * @xferspeed: speed we want to achieve
+ * @speed: speed we want to achieve
*
- * Tune the ITE chipset for the desired mode. If we can't achieve
- * the desired mode then tune for a lower one, but ultimately
- * make the thing work.
+ * Tune the ITE chipset for the desired mode.
*/
-static int it821x_tune_chipset (ide_drive_t *drive, byte xferspeed)
+static int it821x_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
struct it821x_dev *itdev = ide_get_hwifdata(hwif);
- u8 speed = ide_rate_filter(drive, xferspeed);
-
- switch (speed) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- return it821x_tunepio(drive, speed - XFER_PIO_0);
- }
if (itdev->smart == 0) {
switch (speed) {
@@ -477,7 +463,7 @@ static int it821x_config_drive_for_dma (ide_drive_t *drive)
if (ide_tune_dma(drive))
return 0;
- it821x_tuneproc(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -644,7 +630,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
}
hwif->speedproc = &it821x_tune_chipset;
- hwif->tuneproc = &it821x_tuneproc;
+ hwif->set_pio_mode = &it821x_set_pio_mode;
/* MWDMA/PIO clock switching for pass through mode */
if(!idev->smart) {
@@ -718,10 +704,10 @@ 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, \
- .channels = 2, \
.autodma = AUTODMA, \
.bootable = ON_BOARD, \
- .fixup = it821x_fixups \
+ .fixup = it821x_fixups, \
+ .pio_mask = ATA_PIO4, \
}
static ide_pci_device_t it821x_chipsets[] __devinitdata = {
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index a6008f63e71e..d379fbaf6743 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -83,39 +83,22 @@ static u8 __devinit ata66_jmicron(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static void jmicron_tuneproc (ide_drive_t *drive, byte mode_wanted)
+static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- return;
-}
-
-/**
- * config_jmicron_chipset_for_pio - set drive timings
- * @drive: drive to tune
- * @speed we want
- *
- */
-
-static void config_jmicron_chipset_for_pio (ide_drive_t *drive, byte set_speed)
-{
- u8 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
- if (set_speed)
- (void) ide_config_drive_speed(drive, speed);
+ ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
/**
* jmicron_tune_chipset - set controller timings
* @drive: Drive to set up
- * @xferspeed: speed we want to achieve
+ * @speed: speed we want to achieve
*
* As the JMicron snoops for timings all we actually need to do is
- * make sure we don't set an invalid mode. We do need to honour
- * the cable detect here.
+ * set the transfer mode on the device.
*/
-static int jmicron_tune_chipset (ide_drive_t *drive, byte xferspeed)
+static int jmicron_tune_chipset(ide_drive_t *drive, const u8 speed)
{
- u8 speed = ide_rate_filter(drive, xferspeed);
-
return ide_config_drive_speed(drive, speed);
}
@@ -132,7 +115,7 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive)
if (ide_tune_dma(drive))
return 0;
- config_jmicron_chipset_for_pio(drive, 1);
+ ide_set_max_pio(drive);
return -1;
}
@@ -147,7 +130,7 @@ static int jmicron_config_drive_for_dma (ide_drive_t *drive)
static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
{
hwif->speedproc = &jmicron_tune_chipset;
- hwif->tuneproc = &jmicron_tuneproc;
+ hwif->set_pio_mode = &jmicron_set_pio_mode;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
@@ -173,22 +156,13 @@ fallback:
return;
}
-#define DECLARE_JMB_DEV(name_str) \
- { \
- .name = name_str, \
- .init_hwif = init_hwif_jmicron, \
- .channels = 2, \
- .autodma = AUTODMA, \
- .bootable = ON_BOARD, \
- .enablebits = { {0x40, 1, 1}, {0x40, 0x10, 0x10} }, \
- }
-
-static ide_pci_device_t jmicron_chipsets[] __devinitdata = {
- /* 0 */ DECLARE_JMB_DEV("JMB361"),
- /* 1 */ DECLARE_JMB_DEV("JMB363"),
- /* 2 */ DECLARE_JMB_DEV("JMB365"),
- /* 3 */ DECLARE_JMB_DEV("JMB366"),
- /* 4 */ DECLARE_JMB_DEV("JMB368"),
+static ide_pci_device_t jmicron_chipset __devinitdata = {
+ .name = "JMB",
+ .init_hwif = init_hwif_jmicron,
+ .autodma = AUTODMA,
+ .bootable = ON_BOARD,
+ .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
+ .pio_mask = ATA_PIO5,
};
/**
@@ -202,35 +176,29 @@ static ide_pci_device_t jmicron_chipsets[] __devinitdata = {
static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_setup_pci_device(dev, &jmicron_chipsets[id->driver_data]);
+ ide_setup_pci_device(dev, &jmicron_chipset);
return 0;
}
-/* If libata is configured, jmicron PCI quirk will configure it such
- * that the SATA ports are in AHCI function while the PATA ports are
- * in a separate IDE function. In such cases, match device class and
- * attach only to IDE. If libata isn't configured, keep the old
- * behavior for backward compatibility.
+/* All JMB PATA controllers have and will continue to have the same
+ * interface. Matching vendor and device class is enough for all
+ * current and future controllers if the controller is programmed
+ * properly.
+ *
+ * If libata is configured, jmicron PCI quirk programs the controller
+ * into the correct mode. If libata isn't configured, match known
+ * device IDs too to maintain backward compatibility.
*/
-#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
-#define JMB_CLASS PCI_CLASS_STORAGE_IDE << 8
-#define JMB_CLASS_MASK 0xffff00
-#else
-#define JMB_CLASS 0
-#define JMB_CLASS_MASK 0
-#endif
-
static struct pci_device_id jmicron_pci_tbl[] = {
- { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361,
- PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 0},
- { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363,
- PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 1},
- { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365,
- PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 2},
- { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366,
- PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 3},
- { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368,
- PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 4},
+#if !defined(CONFIG_ATA) && !defined(CONFIG_ATA_MODULE)
+ { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361) },
+ { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363) },
+ { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB365) },
+ { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB366) },
+ { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB368) },
+#endif
+ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
{ 0, },
};
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index b310c4f51077..465c935fdf25 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -187,14 +187,6 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive)
return 1;
}
-static int ns87415_ide_dma_check (ide_drive_t *drive)
-{
- if (drive->media != ide_disk)
- return -1;
-
- return __ide_dma_check(drive);
-}
-
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
{
struct pci_dev *dev = hwif->pci_dev;
@@ -266,7 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
outb(0x60, hwif->dma_status);
hwif->dma_setup = &ns87415_ide_dma_setup;
- hwif->ide_dma_check = &ns87415_ide_dma_check;
hwif->ide_dma_end = &ns87415_ide_dma_end;
if (!noautodma)
@@ -281,7 +272,6 @@ static ide_pci_device_t ns87415_chipset __devinitdata = {
.init_iops = init_iops_ns87415,
#endif
.init_hwif = init_hwif_ns87415,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
};
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index aede7eee9246..9fa06393469a 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -47,7 +47,7 @@
* The main problem with OPTi is that some timings for master
* and slave must be the same. For example, if you have master
* PIO 3 and slave PIO 0, driver have to set some timings of
- * master for PIO 0. Second problem is that opti621_tune_drive
+ * master for PIO 0. Second problem is that opti621_set_pio_mode
* got only one drive to set, but have to set both drives.
* This is solved in compute_pios. If you don't set
* the second drive, compute_pios use ide_get_best_pio_mode
@@ -103,7 +103,7 @@
#include <asm/io.h>
-#define OPTI621_MAX_PIO 3
+//#define OPTI621_MAX_PIO 3
/* In fact, I do not have any PIO 4 drive
* (address: 25 ns, data: 70 ns, recovery: 35 ns),
* but OPTi 82C621 is programmable and it can do (minimal values):
@@ -136,8 +136,8 @@ static int reg_base;
#define PIO_NOT_EXIST 254
#define PIO_DONT_KNOW 255
-/* there are stored pio numbers from other calls of opti621_tune_drive */
-static void compute_pios(ide_drive_t *drive, u8 pio)
+/* there are stored pio numbers from other calls of opti621_set_pio_mode */
+static void compute_pios(ide_drive_t *drive, const u8 pio)
/* Store values into drive->drive_data
* second_contr - 0 for primary controller, 1 for secondary
* slave_drive - 0 -> pio is for master, 1 -> pio is for slave
@@ -147,12 +147,13 @@ static void compute_pios(ide_drive_t *drive, u8 pio)
int d;
ide_hwif_t *hwif = HWIF(drive);
- drive->drive_data = ide_get_best_pio_mode(drive, pio, OPTI621_MAX_PIO, NULL);
+ drive->drive_data = pio;
+
for (d = 0; d < 2; ++d) {
drive = &hwif->drives[d];
if (drive->present) {
if (drive->drive_data == PIO_DONT_KNOW)
- drive->drive_data = ide_get_best_pio_mode(drive, 255, OPTI621_MAX_PIO, NULL);
+ drive->drive_data = ide_get_best_pio_mode(drive, 255, 3);
#ifdef OPTI621_DEBUG
printk("%s: Selected PIO mode %d\n",
drive->name, drive->drive_data);
@@ -240,8 +241,7 @@ static void compute_clocks(int pio, pio_clocks_t *clks)
}
-/* Main tune procedure, called from tuneproc. */
-static void opti621_tune_drive (ide_drive_t *drive, u8 pio)
+static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
/* primary and secondary drives share some registers,
* so we have to program both drives
@@ -331,7 +331,8 @@ static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
hwif->autodma = 0;
hwif->drives[0].drive_data = PIO_DONT_KNOW;
hwif->drives[1].drive_data = PIO_DONT_KNOW;
- hwif->tuneproc = &opti621_tune_drive;
+
+ hwif->set_pio_mode = &opti621_set_pio_mode;
if (!(hwif->dma_base))
return;
@@ -350,17 +351,17 @@ static ide_pci_device_t opti621_chipsets[] __devinitdata = {
{ /* 0 */
.name = "OPTI621",
.init_hwif = init_hwif_opti621,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO3,
},{ /* 1 */
.name = "OPTI621X",
.init_hwif = init_hwif_opti621,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO3,
}
};
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index ee5020df005d..5fb1eedc8194 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -9,7 +9,7 @@
* Split from:
* linux/drivers/ide/pdc202xx.c Version 0.35 Mar. 30, 2002
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
- * Copyright (C) 2005-2006 MontaVista Software, Inc.
+ * Copyright (C) 2005-2007 MontaVista Software, Inc.
* Portions Copyright (C) 1999 Promise Technology, Inc.
* Author: Frank Tiernan (frankt@promise.com)
* Released under terms of General Public License
@@ -146,14 +146,12 @@ static struct udma_timing {
{ 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */
};
-static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed)
+static int pdcnew_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
int err;
- speed = ide_rate_filter(drive, speed);
-
/*
* Issue SETFEATURES_XFER to the drive first. PDC202xx hardware will
* automatically set the timing registers based on 100 MHz PLL output.
@@ -217,9 +215,8 @@ static int pdcnew_tune_chipset(ide_drive_t *drive, u8 speed)
return err;
}
-static void pdcnew_tune_drive(ide_drive_t *drive, u8 pio)
+static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void)pdcnew_tune_chipset(drive, XFER_PIO_0 + pio);
}
@@ -239,7 +236,7 @@ static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- pdcnew_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -341,7 +338,7 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base)
*/
usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
(end_time.tv_usec - start_time.tv_usec);
- pll_input = ((start_count - end_count) & 0x3ffffff) / 10 *
+ pll_input = ((start_count - end_count) & 0x3fffffff) / 10 *
(10000000 / usec_elapsed);
DBG("start[%ld] end[%ld]\n", start_count, end_count);
@@ -378,12 +375,8 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha
int f, r;
u8 pll_ctl0, pll_ctl1;
- if (dev->resource[PCI_ROM_RESOURCE].start) {
- pci_write_config_dword(dev, PCI_ROM_ADDRESS,
- dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name,
- (unsigned long)dev->resource[PCI_ROM_RESOURCE].start);
- }
+ if (dma_base == 0)
+ return -EFAULT;
#ifdef CONFIG_PPC_PMAC
apple_kiwi_init(dev);
@@ -496,20 +489,24 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif)
{
hwif->autodma = 0;
- hwif->tuneproc = &pdcnew_tune_drive;
+ hwif->set_pio_mode = &pdcnew_set_pio_mode;
+
hwif->quirkproc = &pdcnew_quirkproc;
hwif->speedproc = &pdcnew_tune_chipset;
hwif->resetproc = &pdcnew_reset;
+ hwif->err_stops_fifo = 1;
+
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->ultra_mask = hwif->cds->udma_mask;
hwif->mwdma_mask = 0x07;
- hwif->err_stops_fifo = 1;
-
hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -525,43 +522,52 @@ static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d)
return ide_setup_pci_device(dev, d);
}
-static int __devinit init_setup_pdc20270(struct pci_dev *dev,
- ide_pci_device_t *d)
+static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d)
{
- struct pci_dev *findev = NULL;
- int ret;
+ struct pci_dev *bridge = dev->bus->self;
+
+ if (bridge != NULL &&
+ bridge->vendor == PCI_VENDOR_ID_DEC &&
+ bridge->device == PCI_DEVICE_ID_DEC_21150) {
+ struct pci_dev *dev2;
- if ((dev->bus->self &&
- dev->bus->self->vendor == PCI_VENDOR_ID_DEC) &&
- (dev->bus->self->device == PCI_DEVICE_ID_DEC_21150)) {
if (PCI_SLOT(dev->devfn) & 2)
return -ENODEV;
- d->extra = 0;
- while ((findev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, findev)) != NULL) {
- if ((findev->vendor == dev->vendor) &&
- (findev->device == dev->device) &&
- (PCI_SLOT(findev->devfn) & 2)) {
- if (findev->irq != dev->irq) {
- findev->irq = dev->irq;
- }
- ret = ide_setup_pci_devices(dev, findev, d);
- pci_dev_put(findev);
- return ret;
+
+ dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2,
+ PCI_FUNC(dev->devfn)));
+ if (dev2 != NULL &&
+ dev2->vendor == dev->vendor &&
+ dev2->device == dev->device) {
+ int ret;
+
+ if (dev2->irq != dev->irq) {
+ dev2->irq = dev->irq;
+
+ printk(KERN_WARNING "%s: PCI config space "
+ "interrupt fixed.\n", d->name);
}
+
+ ret = ide_setup_pci_devices(dev, dev2, d);
+ if (ret < 0)
+ pci_dev_put(dev2);
+ return ret;
}
}
return ide_setup_pci_device(dev, d);
}
-static int __devinit init_setup_pdc20276(struct pci_dev *dev,
- ide_pci_device_t *d)
+static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d)
{
- if ((dev->bus->self) &&
- (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) &&
- ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) ||
- (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) {
- printk(KERN_INFO "ide: Skipping Promise PDC20276 "
- "attached to I2O RAID controller.\n");
+ struct pci_dev *bridge = dev->bus->self;
+
+ if (bridge != NULL &&
+ bridge->vendor == PCI_VENDOR_ID_INTEL &&
+ (bridge->device == PCI_DEVICE_ID_INTEL_I960 ||
+ bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) {
+
+ printk(KERN_INFO "%s: attached to I2O RAID controller, "
+ "skipping.\n", d->name);
return -ENODEV;
}
return ide_setup_pci_device(dev, d);
@@ -573,63 +579,63 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
.init_setup = init_setup_pdcnew,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
},{ /* 1 */
.name = "PDC20269",
.init_setup = init_setup_pdcnew,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
},{ /* 2 */
.name = "PDC20270",
.init_setup = init_setup_pdc20270,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
},{ /* 3 */
.name = "PDC20271",
.init_setup = init_setup_pdcnew,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
},{ /* 4 */
.name = "PDC20275",
.init_setup = init_setup_pdcnew,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
},{ /* 5 */
.name = "PDC20276",
.init_setup = init_setup_pdc20276,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
},{ /* 6 */
.name = "PDC20277",
.init_setup = init_setup_pdcnew,
.init_chipset = init_chipset_pdcnew,
.init_hwif = init_hwif_pdc202new,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x7f, /* udma0-6*/
}
};
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 41ac4a94959f..b578307fad51 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007
+ * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007
*
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc.
@@ -63,12 +63,11 @@ static const char *pdc_quirk_drives[] = {
static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
-static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int pdc202xx_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 drive_pci = 0x60 + (drive->dn << 2);
- u8 speed = ide_rate_filter(drive, xferspeed);
u8 AP = 0, BP = 0, CP = 0;
u8 TA = 0, TB = 0, TC = 0;
@@ -143,9 +142,8 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return ide_config_drive_speed(drive, speed);
}
-static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio)
+static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio);
}
@@ -191,7 +189,7 @@ static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- pdc202xx_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -307,23 +305,16 @@ static void pdc202xx_reset (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
ide_hwif_t *mate = hwif->mate;
-
+
pdc202xx_reset_host(hwif);
pdc202xx_reset_host(mate);
- pdc202xx_tune_drive(drive, 255);
+
+ ide_set_max_pio(drive);
}
static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
const char *name)
{
- /* This doesn't appear needed */
- if (dev->resource[PCI_ROM_RESOURCE].start) {
- pci_write_config_dword(dev, PCI_ROM_ADDRESS,
- dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name,
- (unsigned long)dev->resource[PCI_ROM_RESOURCE].start);
- }
-
return dev->irq;
}
@@ -337,7 +328,9 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
hwif->rqsize = 256;
hwif->autodma = 0;
- hwif->tuneproc = &pdc202xx_tune_drive;
+
+ hwif->set_pio_mode = &pdc202xx_set_pio_mode;
+
hwif->quirkproc = &pdc202xx_quirkproc;
if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
@@ -345,15 +338,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
hwif->speedproc = &pdc202xx_tune_chipset;
+ hwif->err_stops_fifo = 1;
+
hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+ if (hwif->dma_base == 0)
+ return;
+
hwif->ultra_mask = hwif->cds->udma_mask;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
hwif->atapi_dma = 1;
- hwif->err_stops_fifo = 1;
-
hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate;
hwif->dma_lost_irq = &pdc202xx_dma_lost_irq;
hwif->dma_timeout = &pdc202xx_dma_timeout;
@@ -449,10 +445,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_pdc202xx,
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
.extra = 16,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x07, /* udma0-2 */
},{ /* 1 */
.name = "PDC20262",
@@ -460,10 +456,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_pdc202xx,
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
.extra = 48,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x1f, /* udma0-4 */
},{ /* 2 */
.name = "PDC20263",
@@ -471,10 +467,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_pdc202xx,
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
.extra = 48,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x1f, /* udma0-4 */
},{ /* 3 */
.name = "PDC20265",
@@ -482,10 +478,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_pdc202xx,
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
.extra = 48,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
},{ /* 4 */
.name = "PDC20267",
@@ -493,10 +489,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
.init_chipset = init_chipset_pdc202xx,
.init_hwif = init_hwif_pdc202xx,
.init_dma = init_dma_pdc202xx,
- .channels = 2,
.autodma = AUTODMA,
.bootable = OFF_BOARD,
.extra = 48,
+ .pio_mask = ATA_PIO4,
.udma_mask = 0x3f, /* udma0-5 */
}
};
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 1372c35be035..fd8214a7ab98 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/piix.c Version 0.50 Jun 10, 2007
+ * linux/drivers/ide/pci/piix.c Version 0.52 Jul 14, 2007
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
@@ -17,11 +17,11 @@
* 41
* 43
*
- * | PIO 0 | c0 | 80 | 0 | piix_tune_drive(drive, 0);
- * | PIO 2 | SW2 | d0 | 90 | 4 | piix_tune_drive(drive, 2);
- * | PIO 3 | MW1 | e1 | a1 | 9 | piix_tune_drive(drive, 3);
- * | PIO 4 | MW2 | e3 | a3 | b | piix_tune_drive(drive, 4);
- *
+ * | PIO 0 | c0 | 80 | 0 |
+ * | PIO 2 | SW2 | d0 | 90 | 4 |
+ * | PIO 3 | MW1 | e1 | a1 | 9 |
+ * | PIO 4 | MW2 | e3 | a3 | b |
+ *
* sitre = word40 & 0x4000; primary
* sitre = word42 & 0x4000; secondary
*
@@ -109,7 +109,7 @@ static int no_piix_dma;
* piix_dma_2_pio - return the PIO mode matching DMA
* @xfer_rate: transfer speed
*
- * Returns the nearest equivalent PIO timing for the PIO or DMA
+ * Returns the nearest equivalent PIO timing for the DMA
* mode requested by the controller.
*/
@@ -123,20 +123,14 @@ static u8 piix_dma_2_pio (u8 xfer_rate) {
case XFER_UDMA_1:
case XFER_UDMA_0:
case XFER_MW_DMA_2:
- case XFER_PIO_4:
return 4;
case XFER_MW_DMA_1:
- case XFER_PIO_3:
return 3;
case XFER_SW_DMA_2:
- case XFER_PIO_2:
return 2;
case XFER_MW_DMA_0:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
- case XFER_PIO_1:
- case XFER_PIO_0:
- case XFER_PIO_SLOW:
default:
return 0;
}
@@ -210,16 +204,16 @@ static void piix_tune_pio (ide_drive_t *drive, u8 pio)
}
/**
- * piix_tune_drive - tune a drive attached to PIIX
+ * piix_set_pio_mode - set PIO mode
* @drive: drive to tune
* @pio: desired PIO mode
*
* Set the drive's PIO mode (might be useful if drive is not registered
* in CMOS for any reason).
*/
-static void piix_tune_drive (ide_drive_t *drive, u8 pio)
+
+static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
piix_tune_pio(drive, pio);
(void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
@@ -227,19 +221,18 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
/**
* piix_tune_chipset - tune a PIIX interface
* @drive: IDE drive to tune
- * @xferspeed: speed to configure
+ * @speed: speed to configure
*
* Set a PIIX interface channel to the desired speeds. This involves
* requires the right timing data into the PIIX configuration space
* then setting the drive parameters appropriately
*/
-
-static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+
+static int piix_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 maslave = hwif->channel ? 0x42 : 0x40;
- u8 speed = ide_rate_filter(drive, xferspeed);
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int v_flag = 0x01 << drive->dn;
@@ -266,10 +259,6 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_0: break;
default: return -1;
}
@@ -300,6 +289,7 @@ static int piix_tune_chipset (ide_drive_t *drive, u8 xferspeed)
}
piix_tune_pio(drive, piix_dma_2_pio(speed));
+
return ide_config_drive_speed(drive, speed);
}
@@ -319,7 +309,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- piix_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -456,7 +446,8 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
}
hwif->autodma = 0;
- hwif->tuneproc = &piix_tune_drive;
+
+ hwif->set_pio_mode = &piix_set_pio_mode;
hwif->speedproc = &piix_tune_chipset;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
@@ -495,10 +486,10 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
.name = name_str, \
.init_chipset = init_chipset_piix, \
.init_hwif = init_hwif_piix, \
- .channels = 2, \
.autodma = AUTODMA, \
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \
.bootable = ON_BOARD, \
+ .pio_mask = ATA_PIO4, \
.udma_mask = udma, \
}
@@ -514,11 +505,11 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
*/
.name = "MPIIX",
.init_hwif = init_hwif_piix,
- .channels = 2,
.autodma = NODMA,
.enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}},
.bootable = ON_BOARD,
- .flags = IDEPCI_FLAG_ISA_PORTS
+ .host_flags = IDE_HFLAG_ISA_PORTS,
+ .pio_mask = ATA_PIO4,
},
/* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */
diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
index f8c954690142..10e1ae7a4a02 100644
--- a/drivers/ide/pci/rz1000.c
+++ b/drivers/ide/pci/rz1000.c
@@ -52,7 +52,6 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
static ide_pci_device_t rz1000_chipset __devinitdata = {
.name = "RZ100x",
.init_hwif = init_hwif_rz1000,
- .channels = 2,
.autodma = NODMA,
.bootable = ON_BOARD,
};
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 523363c93794..79ecab689489 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/sc1200.c Version 0.94 Mar 10 2007
+ * linux/drivers/ide/pci/sc1200.c Version 0.95 Jun 16 2007
*
* Copyright (C) 2000-2002 Mark Lord <mlord@pobox.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
@@ -138,7 +138,7 @@ out:
return mask;
}
-static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode)
+static int sc1200_tune_chipset(ide_drive_t *drive, const u8 mode)
{
ide_hwif_t *hwif = HWIF(drive);
int unit = drive->select.b.unit;
@@ -146,25 +146,11 @@ static int sc1200_tune_chipset(ide_drive_t *drive, u8 mode)
unsigned short pci_clock;
unsigned int basereg = hwif->channel ? 0x50 : 0x40;
- mode = ide_rate_filter(drive, mode);
-
/*
* Tell the drive to switch to the new mode; abort on failure.
*/
- if (sc1200_set_xfer_mode(drive, mode)) {
- printk("SC1200: set xfer mode failure\n");
+ if (sc1200_set_xfer_mode(drive, mode))
return 1; /* failure */
- }
-
- switch (mode) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- sc1200_tunepio(drive, mode - XFER_PIO_0);
- return 0;
- }
pci_clock = sc1200_get_pci_clock();
@@ -274,19 +260,20 @@ static int sc1200_ide_dma_end (ide_drive_t *drive)
}
/*
- * sc1200_tuneproc() handles selection/setting of PIO modes
+ * sc1200_set_pio_mode() handles setting of PIO modes
* for both the chipset and drive.
*
* All existing BIOSs for this chipset guarantee that all drives
* will have valid default PIO timings set up before we get here.
*/
-static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "autotune" */
+
+static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
int mode = -1;
/*
- * bad abuse of ->tuneproc interface
+ * bad abuse of ->set_pio_mode interface
*/
switch (pio) {
case 200: mode = XFER_UDMA_0; break;
@@ -304,9 +291,6 @@ static void sc1200_tuneproc (ide_drive_t *drive, byte pio) /* mode=255 means "au
return;
}
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
- printk("SC1200: %s: setting PIO mode%d\n", drive->name, pio);
-
if (sc1200_set_xfer_mode(drive, XFER_PIO_0 + pio) == 0)
sc1200_tunepio(drive, pio);
}
@@ -390,7 +374,7 @@ static int sc1200_resume (struct pci_dev *dev)
// loop over all interfaces that are part of this pci device:
//
while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) {
- unsigned int basereg, r, d, format;
+ unsigned int basereg, r;
sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data;
//
@@ -402,41 +386,6 @@ static int sc1200_resume (struct pci_dev *dev)
pci_write_config_dword(hwif->pci_dev, basereg + (r<<2), ss->regs[r]);
}
}
- //
- // Re-program drive PIO modes
- //
- pci_read_config_dword(hwif->pci_dev, basereg+4, &format);
- format = (format >> 31) & 1;
- if (format)
- format += sc1200_get_pci_clock();
- for (d = 0; d < 2; ++d) {
- ide_drive_t *drive = &(hwif->drives[d]);
- if (drive->present) {
- unsigned int pio, timings;
- pci_read_config_dword(hwif->pci_dev, basereg+(drive->select.b.unit << 3), &timings);
- for (pio = 0; pio <= 4; ++pio) {
- if (sc1200_pio_timings[format][pio] == timings)
- break;
- }
- if (pio > 4)
- pio = 255; /* autotune */
- (void)sc1200_tuneproc(drive, pio);
- }
- }
- //
- // Re-program drive DMA modes
- //
- for (d = 0; d < MAX_DRIVES; ++d) {
- ide_drive_t *drive = &(hwif->drives[d]);
- if (drive->present && !__ide_dma_bad_drive(drive)) {
- int enable_dma = drive->using_dma;
- hwif->dma_off_quietly(drive);
- if (sc1200_config_dma(drive))
- enable_dma = 0;
- if (enable_dma)
- hwif->dma_host_on(drive);
- }
- }
}
return 0;
}
@@ -457,7 +406,8 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
hwif->ide_dma_end = &sc1200_ide_dma_end;
if (!noautodma)
hwif->autodma = 1;
- hwif->tuneproc = &sc1200_tuneproc;
+
+ hwif->set_pio_mode = &sc1200_set_pio_mode;
hwif->speedproc = &sc1200_tune_chipset;
}
hwif->atapi_dma = 1;
@@ -471,9 +421,10 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
static ide_pci_device_t sc1200_chipset __devinitdata = {
.name = "SC1200",
.init_hwif = init_hwif_sc1200,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_ABUSE_DMA_MODES,
+ .pio_mask = ATA_PIO4,
};
static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 7b87488e3daa..66a526e0ece4 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -165,9 +165,9 @@ scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
ide_hwif_t *hwif = HWIF(drive);
out_be32((void*)port, addr);
- __asm__ __volatile__("eieio":::"memory");
+ eieio();
in_be32((void*)(hwif->dma_base + 0x01c));
- __asm__ __volatile__("eieio":::"memory");
+ eieio();
}
static void
@@ -190,7 +190,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
}
/**
- * scc_tuneproc - tune a drive PIO mode
+ * scc_tune_pio - tune a drive PIO mode
* @drive: drive to tune
* @mode_wanted: the target operating mode
*
@@ -198,7 +198,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
* controller.
*/
-static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted)
+static void scc_tune_pio(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
struct scc_ports *ports = ide_get_hwifdata(hwif);
@@ -207,56 +207,38 @@ static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted)
unsigned long piosht_port = ctl_base + 0x000;
unsigned long pioct_port = ctl_base + 0x004;
unsigned long reg;
- unsigned char speed = XFER_PIO_0;
int offset;
- mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL);
- switch (mode_wanted) {
- case 4:
- speed = XFER_PIO_4;
- break;
- case 3:
- speed = XFER_PIO_3;
- break;
- case 2:
- speed = XFER_PIO_2;
- break;
- case 1:
- speed = XFER_PIO_1;
- break;
- case 0:
- default:
- speed = XFER_PIO_0;
- break;
- }
-
reg = in_be32((void __iomem *)cckctrl_port);
if (reg & CCKCTRL_ATACLKOEN) {
offset = 1; /* 133MHz */
} else {
offset = 0; /* 100MHz */
}
- reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted];
+ reg = JCHSTtbl[offset][pio] << 16 | JCHHTtbl[offset][pio];
out_be32((void __iomem *)piosht_port, reg);
- reg = JCHCTtbl[offset][mode_wanted];
+ reg = JCHCTtbl[offset][pio];
out_be32((void __iomem *)pioct_port, reg);
+}
- ide_config_drive_speed(drive, speed);
+static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ scc_tune_pio(drive, pio);
+ ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
/**
* scc_tune_chipset - tune a drive DMA mode
* @drive: Drive to set up
- * @xferspeed: speed we want to achieve
+ * @speed: speed we want to achieve
*
* Load the timing settings for this device mode into the
* controller.
*/
-static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed)
+static int scc_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
- u8 speed = ide_rate_filter(drive, xferspeed);
struct scc_ports *ports = ide_get_hwifdata(hwif);
unsigned long ctl_base = ports->ctl;
unsigned long cckctrl_port = ctl_base + 0xff0;
@@ -280,25 +262,13 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed)
switch (speed) {
case XFER_UDMA_6:
- idx = 6;
- break;
case XFER_UDMA_5:
- idx = 5;
- break;
case XFER_UDMA_4:
- idx = 4;
- break;
case XFER_UDMA_3:
- idx = 3;
- break;
case XFER_UDMA_2:
- idx = 2;
- break;
case XFER_UDMA_1:
- idx = 1;
- break;
case XFER_UDMA_0:
- idx = 0;
+ idx = speed - XFER_UDMA_0;
break;
default:
return 1;
@@ -329,7 +299,7 @@ static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed)
* required.
* If the drive isn't suitable for DMA or we hit other problems
* then we will drop down to PIO and set up PIO appropriately.
- * (return 1)
+ * (return -1)
*/
static int scc_config_drive_for_dma(ide_drive_t *drive)
@@ -338,7 +308,7 @@ static int scc_config_drive_for_dma(ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- scc_tuneproc(drive, 4);
+ ide_set_max_pio(drive);
return -1;
}
@@ -401,6 +371,33 @@ static int scc_ide_dma_end(ide_drive_t * drive)
ide_hwif_t *hwif = HWIF(drive);
unsigned long intsts_port = hwif->dma_base + 0x014;
u32 reg;
+ int dma_stat, data_loss = 0;
+ static int retry = 0;
+
+ /* errata A308 workaround: Step5 (check data loss) */
+ /* We don't check non ide_disk because it is limited to UDMA4 */
+ if (!(in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT) &&
+ drive->media == ide_disk && drive->current_speed > XFER_UDMA_4) {
+ reg = in_be32((void __iomem *)intsts_port);
+ if (!(reg & INTSTS_ACTEINT)) {
+ printk(KERN_WARNING "%s: operation failed (transfer data loss)\n",
+ drive->name);
+ data_loss = 1;
+ if (retry++) {
+ struct request *rq = HWGROUP(drive)->rq;
+ int unit;
+ /* ERROR_RESET and drive->crc_count are needed
+ * to reduce DMA transfer mode in retry process.
+ */
+ if (rq)
+ rq->errors |= ERROR_RESET;
+ for (unit = 0; unit < MAX_DRIVES; unit++) {
+ ide_drive_t *drive = &hwif->drives[unit];
+ drive->crc_count++;
+ }
+ }
+ }
+ }
while (1) {
reg = in_be32((void __iomem *)intsts_port);
@@ -469,27 +466,25 @@ static int scc_ide_dma_end(ide_drive_t * drive)
break;
}
- return __ide_dma_end(drive);
+ dma_stat = __ide_dma_end(drive);
+ if (data_loss)
+ dma_stat |= 2; /* emulate DMA error (to retry command) */
+ return dma_stat;
}
/* returns 1 if dma irq issued, 0 otherwise */
static int scc_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- u8 dma_stat = hwif->INB(hwif->dma_status);
+ ide_hwif_t *hwif = HWIF(drive);
+ u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014);
- /* return 1 if INTR asserted */
- if ((dma_stat & 4) == 4)
+ /* SCC errata A252,A308 workaround: Step4 */
+ if ((in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT) &&
+ (int_stat & INTSTS_INTRQ))
return 1;
- /* Workaround for PTERADD: emulate DMA_INTR when
- * - IDE_STATUS[ERR] = 1
- * - INT_STATUS[INTRQ] = 1
- * - DMA_STATUS[IORACTA] = 1
- */
- if (in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT &&
- in_be32((void __iomem *)(hwif->dma_base + 0x014)) & INTSTS_INTRQ &&
- dma_stat & 1)
+ /* SCC errata A308 workaround: Step5 (polling IOIRQS) */
+ if (int_stat & INTSTS_IOIRQS)
return 1;
if (!drive->waiting_for_dma)
@@ -498,6 +493,21 @@ static int scc_dma_test_irq(ide_drive_t *drive)
return 0;
}
+static u8 scc_udma_filter(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 mask = hwif->ultra_mask;
+
+ /* errata A308 workaround: limit non ide_disk drive to UDMA4 */
+ if ((drive->media != ide_disk) && (mask & 0xE0)) {
+ printk(KERN_INFO "%s: limit %s to UDMA4\n",
+ SCC_PATA_NAME, drive->name);
+ mask = 0x1F;
+ }
+
+ return mask;
+}
+
/**
* setup_mmio_scc - map CTRL/BMID region
* @dev: PCI device we are configuring
@@ -511,8 +521,8 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name)
unsigned long dma_base = pci_resource_start(dev, 1);
unsigned long ctl_size = pci_resource_len(dev, 0);
unsigned long dma_size = pci_resource_len(dev, 1);
- void *ctl_addr;
- void *dma_addr;
+ void __iomem *ctl_addr;
+ void __iomem *dma_addr;
int i;
for (i = 0; i < MAX_HWIFS; i++) {
@@ -699,9 +709,10 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
hwif->dma_setup = scc_dma_setup;
hwif->ide_dma_end = scc_ide_dma_end;
hwif->speedproc = scc_tune_chipset;
- hwif->tuneproc = scc_tuneproc;
+ hwif->set_pio_mode = scc_set_pio_mode;
hwif->ide_dma_check = scc_config_drive_for_dma;
hwif->ide_dma_test_irq = scc_dma_test_irq;
+ hwif->udma_filter = scc_udma_filter;
hwif->drives[0].autotune = IDE_TUNE_AUTO;
hwif->drives[1].autotune = IDE_TUNE_AUTO;
@@ -731,9 +742,10 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
.init_setup = init_setup_scc, \
.init_iops = init_iops_scc, \
.init_hwif = init_hwif_scc, \
- .channels = 1, \
.autodma = AUTODMA, \
.bootable = ON_BOARD, \
+ .host_flags = IDE_HFLAG_SINGLE, \
+ .pio_mask = ATA_PIO4, \
}
static ide_pci_device_t scc_chipsets[] __devinitdata = {
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ed04e0c8dd4c..0351cf210427 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/serverworks.c Version 0.20 Jun 3 2007
+ * linux/drivers/ide/pci/serverworks.c Version 0.22 Jun 27 2007
*
* Copyright (C) 1998-2000 Michel Aubry
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz
@@ -123,23 +123,39 @@ static u8 svwks_csb_check (struct pci_dev *dev)
}
return 0;
}
-static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+
+static void svwks_tune_pio(ide_drive_t *drive, const u8 pio)
+{
+ static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
+ static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
+
+ struct pci_dev *dev = drive->hwif->pci_dev;
+
+ pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
+
+ if (svwks_csb_check(dev)) {
+ u16 csb_pio = 0;
+
+ pci_read_config_word(dev, 0x4a, &csb_pio);
+
+ csb_pio &= ~(0x0f << (4 * drive->dn));
+ csb_pio |= (pio << (4 * drive->dn));
+
+ pci_write_config_word(dev, 0x4a, csb_pio);
+ }
+}
+
+static int svwks_tune_chipset(ide_drive_t *drive, const u8 speed)
{
static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
static const u8 dma_modes[] = { 0x77, 0x21, 0x20 };
- static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
- static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 };
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- u8 speed = ide_rate_filter(drive, xferspeed);
- u8 pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
u8 unit = (drive->select.b.unit & 0x01);
- u8 csb5 = svwks_csb_check(dev);
- u8 ultra_enable = 0, ultra_timing = 0;
- u8 dma_timing = 0, pio_timing = 0;
- u16 csb5_pio = 0;
+
+ u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0;
/* If we are about to put a disk into UDMA mode we screwed up.
Our code assumes we never _ever_ do this on an OSB4 */
@@ -149,31 +165,15 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
BUG();
pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
- pci_read_config_word(dev, 0x4A, &csb5_pio);
pci_read_config_byte(dev, 0x54, &ultra_enable);
ultra_timing &= ~(0x0F << (4*unit));
ultra_enable &= ~(0x01 << drive->dn);
- csb5_pio &= ~(0x0F << (4*drive->dn));
switch(speed) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- pio_timing |= pio_modes[speed - XFER_PIO_0];
- csb5_pio |= ((speed - XFER_PIO_0) << (4*drive->dn));
- break;
-
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
- /*
- * TODO: always setup PIO mode so this won't be needed
- */
- pio_timing |= pio_modes[pio];
- csb5_pio |= (pio << (4*drive->dn));
dma_timing |= dma_modes[speed - XFER_MW_DMA_0];
break;
@@ -183,11 +183,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_UDMA_2:
case XFER_UDMA_1:
case XFER_UDMA_0:
- /*
- * TODO: always setup PIO mode so this won't be needed
- */
- pio_timing |= pio_modes[pio];
- csb5_pio |= (pio << (4*drive->dn));
dma_timing |= dma_modes[2];
ultra_timing |= ((udma_modes[speed - XFER_UDMA_0]) << (4*unit));
ultra_enable |= (0x01 << drive->dn);
@@ -195,10 +190,6 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
break;
}
- pci_write_config_byte(dev, drive_pci[drive->dn], pio_timing);
- if (csb5)
- pci_write_config_word(dev, 0x4A, csb5_pio);
-
pci_write_config_byte(dev, drive_pci2[drive->dn], dma_timing);
pci_write_config_byte(dev, (0x56|hwif->channel), ultra_timing);
pci_write_config_byte(dev, 0x54, ultra_enable);
@@ -206,10 +197,10 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
return (ide_config_drive_speed(drive, speed));
}
-static void svwks_tune_drive (ide_drive_t *drive, u8 pio)
+static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
- (void)svwks_tune_chipset(drive, XFER_PIO_0 + pio);
+ svwks_tune_pio(drive, pio);
+ (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
@@ -220,7 +211,7 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- svwks_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -389,12 +380,10 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif)
static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
{
- u8 dma_stat = 0;
-
if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14;
- hwif->tuneproc = &svwks_tune_drive;
+ hwif->set_pio_mode = &svwks_set_pio_mode;
hwif->speedproc = &svwks_tune_chipset;
hwif->udma_filter = &svwks_udma_filter;
@@ -407,11 +396,11 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
hwif->autodma = 0;
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+
+ if (!hwif->dma_base)
return;
- }
hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
@@ -421,11 +410,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
if (!noautodma)
hwif->autodma = 1;
- dma_stat = inb(hwif->dma_status);
- hwif->drives[0].autodma = (dma_stat & 0x20);
- hwif->drives[1].autodma = (dma_stat & 0x40);
- hwif->drives[0].autotune = (!(dma_stat & 0x20));
- hwif->drives[1].autotune = (!(dma_stat & 0x40));
+ hwif->drives[0].autodma = hwif->drives[1].autodma = 1;
}
static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
@@ -441,9 +426,12 @@ static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d)
d->bootable = ON_BOARD;
}
- d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE ||
- dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
- (!(PCI_FUNC(dev->devfn) & 1))) ? 1 : 2;
+ if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE ||
+ dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) &&
+ (!(PCI_FUNC(dev->devfn) & 1)))
+ d->host_flags |= IDE_HFLAG_SINGLE;
+ else
+ d->host_flags &= ~IDE_HFLAG_SINGLE;
return ide_setup_pci_device(dev, d);
}
@@ -454,41 +442,43 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
.init_setup = init_setup_svwks,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
},{ /* 1 */
.name = "SvrWks CSB5",
.init_setup = init_setup_svwks,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
},{ /* 2 */
.name = "SvrWks CSB6",
.init_setup = init_setup_csb6,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .channels = 2,
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
},{ /* 3 */
.name = "SvrWks CSB6",
.init_setup = init_setup_csb6,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .channels = 1, /* 2 */
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
},{ /* 4 */
.name = "SvrWks HT1000",
.init_setup = init_setup_svwks,
.init_chipset = init_chipset_svwks,
.init_hwif = init_hwif_svwks,
- .channels = 1, /* 2 */
.autodma = AUTODMA,
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
}
};
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index d396b2929ed8..c292e1de1d56 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -34,6 +34,8 @@
#include <linux/ide.h>
+#define DRV_NAME "SGIIOC4"
+
/* IOC4 Specific Definitions */
#define IOC4_CMD_OFFSET 0x100
#define IOC4_CTRL_OFFSET 0x120
@@ -289,15 +291,26 @@ static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
drive->hwif->dma_host_off(drive);
}
+static int sgiioc4_speedproc(ide_drive_t *drive, const u8 speed)
+{
+ if (speed != XFER_MW_DMA_2)
+ return 1;
+
+ return ide_config_drive_speed(drive, speed);
+}
+
static int sgiioc4_ide_dma_check(ide_drive_t *drive)
{
- /* FIXME: check for available DMA modes */
- if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
- printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
- "using PIO instead\n", drive->name);
- return -1;
- } else
+ if (ide_tune_dma(drive))
return 0;
+
+ /*
+ * ->set_pio_mode is not implemented currently
+ * so this is just for the completness
+ */
+ ide_set_max_pio(drive);
+
+ return -1;
}
/* returns 1 if dma irq issued, 0 otherwise */
@@ -353,7 +366,7 @@ sgiioc4_INB(unsigned long port)
}
/* Creates a dma map for the scatter-gather list entries */
-static void __devinit
+static int __devinit
ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
{
void __iomem *virt_dma_base;
@@ -369,7 +382,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
"ALREADY in use\n",
__FUNCTION__, hwif->name, (void *) dma_base,
(void *) dma_base + num_ports - 1);
- goto dma_alloc_failure;
+ return -1;
}
virt_dma_base = ioremap(dma_base, num_ports);
@@ -395,7 +408,7 @@ ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base)
if (pad) {
ide_set_hwifdata(hwif, pad);
- return;
+ return 0;
}
pci_free_consistent(hwif->pci_dev,
@@ -413,10 +426,7 @@ dma_pci_alloc_failure:
dma_remap_failure:
release_mem_region(dma_base, num_ports);
-dma_alloc_failure:
- /* Disable DMA because we couldnot allocate any DMA maps */
- hwif->autodma = 0;
- hwif->atapi_dma = 0;
+ return -1;
}
/* Initializes the IOC4 DMA Engine */
@@ -581,13 +591,11 @@ static void __devinit
ide_init_sgiioc4(ide_hwif_t * hwif)
{
hwif->mmio = 1;
- hwif->autodma = 1;
hwif->atapi_dma = 1;
- hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
- hwif->mwdma_mask = 0x2; /* Multimode-2 DMA */
- hwif->swdma_mask = 0x2;
- hwif->tuneproc = NULL; /* Sets timing for PIO mode */
- hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */
+ hwif->mwdma_mask = 0x04;
+ hwif->pio_mask = 0x00;
+ hwif->set_pio_mode = NULL; /* Sets timing for PIO mode */
+ hwif->speedproc = &sgiioc4_speedproc;
hwif->selectproc = NULL;/* Use the default routine to select drive */
hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */
hwif->pre_reset = NULL; /* No HBA specific pre_set needed */
@@ -614,7 +622,7 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
}
static int __devinit
-sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
+sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
{
unsigned long cmd_base, dma_base, irqport;
unsigned long bar0, cmd_phys_base, ctl;
@@ -631,7 +639,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
break;
}
if (h == MAX_HWIFS) {
- printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name);
+ printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
+ DRV_NAME);
return -ENOMEM;
}
@@ -640,7 +649,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
virt_base = ioremap(bar0, pci_resource_len(dev, 0));
if (virt_base == NULL) {
printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n",
- d->name, bar0);
+ DRV_NAME, bar0);
return -ENOMEM;
}
cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
@@ -671,7 +680,6 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
hwif->chipset = ide_pci;
hwif->pci_dev = dev;
hwif->channel = 0; /* Single Channel chip */
- hwif->cds = (struct ide_pci_device_s *) d;
hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */
/* The IOC4 uses MMIO rather than Port IO. */
@@ -682,11 +690,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
ide_init_sgiioc4(hwif);
- if (dma_base)
- ide_dma_sgiioc4(hwif, dma_base);
- else
+ hwif->autodma = 0;
+
+ if (dma_base && ide_dma_sgiioc4(hwif, dma_base) == 0) {
+ hwif->autodma = 1;
+ hwif->drives[1].autodma = hwif->drives[0].autodma = 1;
+ } else
printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n",
- hwif->name, d->name);
+ hwif->name, DRV_NAME);
if (probe_hwif_init(hwif))
return -EIO;
@@ -698,7 +709,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
}
static unsigned int __devinit
-pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
+pci_init_sgiioc4(struct pci_dev *dev)
{
unsigned int class_rev;
int ret;
@@ -706,30 +717,20 @@ pci_init_sgiioc4(struct pci_dev *dev, ide_pci_device_t * d)
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xff;
printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
- d->name, pci_name(dev), class_rev);
+ DRV_NAME, pci_name(dev), class_rev);
if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) {
printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
- "firmware is obsolete - please upgrade to revision"
- "46 or higher\n", d->name, pci_name(dev));
+ "firmware is obsolete - please upgrade to "
+ "revision46 or higher\n",
+ DRV_NAME, pci_name(dev));
ret = -EAGAIN;
goto out;
}
- ret = sgiioc4_ide_setup_pci_device(dev, d);
+ ret = sgiioc4_ide_setup_pci_device(dev);
out:
return ret;
}
-static ide_pci_device_t sgiioc4_chipset __devinitdata = {
- /* Channel 0 */
- .name = "SGIIOC4",
- .init_hwif = ide_init_sgiioc4,
- .init_dma = ide_dma_sgiioc4,
- .channels = 1,
- .autodma = AUTODMA,
- /* SGI IOC4 doesn't have enablebits. */
- .bootable = ON_BOARD,
-};
-
int
ioc4_ide_attach_one(struct ioc4_driver_data *idd)
{
@@ -739,7 +740,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd)
if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
return 0;
- return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset);
+ return pci_init_sgiioc4(idd->idd_pdev);
}
static struct ioc4_submodule ioc4_ide_submodule = {
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 1c3e35487893..5d1e5e52a044 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1,9 +1,10 @@
/*
- * linux/drivers/ide/pci/siimage.c Version 1.12 Mar 10 2007
+ * linux/drivers/ide/pci/siimage.c Version 1.16 Jul 13 2007
*
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
* Copyright (C) 2007 MontaVista Software, Inc.
+ * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -31,6 +32,10 @@
* unplugging/replugging the virtual CD interface when the DRAC is reset.
* This often causes drivers/ide/siimage to panic but is ok with the rather
* smarter code in libata.
+ *
+ * TODO:
+ * - IORDY fixes
+ * - VDMA support
*/
#include <linux/types.h>
@@ -160,140 +165,90 @@ out:
}
/**
- * siimage_taskfile_timing - turn timing data to a mode
- * @hwif: interface to query
- *
- * Read the timing data for the interface and return the
- * mode that is being used.
- */
-
-static byte siimage_taskfile_timing (ide_hwif_t *hwif)
-{
- u16 timing = 0x328a;
- unsigned long addr = siimage_selreg(hwif, 2);
-
- if (hwif->mmio)
- timing = hwif->INW(addr);
- else
- pci_read_config_word(hwif->pci_dev, addr, &timing);
-
- switch (timing) {
- case 0x10c1: return 4;
- case 0x10c3: return 3;
- case 0x1104:
- case 0x1281: return 2;
- case 0x2283: return 1;
- case 0x328a:
- default: return 0;
- }
-}
-
-/**
- * simmage_tuneproc - tune a drive
+ * sil_tune_pio - tune a drive
* @drive: drive to tune
- * @mode_wanted: the target operating mode
+ * @pio: the desired PIO mode
*
* Load the timing settings for this device mode into the
* controller. If we are in PIO mode 3 or 4 turn on IORDY
* monitoring (bit 9). The TF timing is bits 31:16
*/
-
-static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
+
+static void sil_tune_pio(ide_drive_t *drive, u8 pio)
{
+ const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
+ const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
+
ide_hwif_t *hwif = HWIF(drive);
+ ide_drive_t *pair = &hwif->drives[drive->dn ^ 1];
u32 speedt = 0;
u16 speedp = 0;
unsigned long addr = siimage_seldev(drive, 0x04);
unsigned long tfaddr = siimage_selreg(hwif, 0x02);
-
- /* cheat for now and use the docs */
- switch (mode_wanted) {
- case 4:
- speedp = 0x10c1;
- speedt = 0x10c1;
- break;
- case 3:
- speedp = 0x10c3;
- speedt = 0x10c3;
- break;
- case 2:
- speedp = 0x1104;
- speedt = 0x1281;
- break;
- case 1:
- speedp = 0x2283;
- speedt = 0x2283;
- break;
- case 0:
- default:
- speedp = 0x328a;
- speedt = 0x328a;
- break;
+ unsigned long base = (unsigned long)hwif->hwif_data;
+ u8 tf_pio = pio;
+ u8 addr_mask = hwif->channel ? (hwif->mmio ? 0xF4 : 0x84)
+ : (hwif->mmio ? 0xB4 : 0x80);
+ u8 mode = 0;
+ u8 unit = drive->select.b.unit;
+
+ /* trim *taskfile* PIO to the slowest of the master/slave */
+ if (pair->present) {
+ u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
+
+ if (pair_pio < tf_pio)
+ tf_pio = pair_pio;
}
+ /* cheat for now and use the docs */
+ speedp = data_speed[pio];
+ speedt = tf_speed[tf_pio];
+
if (hwif->mmio) {
hwif->OUTW(speedp, addr);
hwif->OUTW(speedt, tfaddr);
/* Now set up IORDY */
- if(mode_wanted == 3 || mode_wanted == 4)
+ if (pio > 2)
hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
else
hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
+
+ mode = hwif->INB(base + addr_mask);
+ mode &= ~(unit ? 0x30 : 0x03);
+ mode |= (unit ? 0x10 : 0x01);
+ hwif->OUTB(mode, base + addr_mask);
} else {
pci_write_config_word(hwif->pci_dev, addr, speedp);
pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
speedp &= ~0x200;
/* Set IORDY for mode 3 or 4 */
- if(mode_wanted == 3 || mode_wanted == 4)
+ if (pio > 2)
speedp |= 0x200;
pci_write_config_word(hwif->pci_dev, tfaddr-2, speedp);
+
+ pci_read_config_byte(hwif->pci_dev, addr_mask, &mode);
+ mode &= ~(unit ? 0x30 : 0x03);
+ mode |= (unit ? 0x10 : 0x01);
+ pci_write_config_byte(hwif->pci_dev, addr_mask, mode);
}
}
-/**
- * config_siimage_chipset_for_pio - set drive timings
- * @drive: drive to tune
- * @speed we want
- *
- * Compute the best pio mode we can for a given device. Also honour
- * the timings for the driver when dealing with mixed devices. Some
- * of this is ugly but its all wrapped up here
- *
- * The SI680 can also do VDMA - we need to start using that
- *
- * FIXME: we use the BIOS channel timings to avoid driving the task
- * files too fast at the disk. We need to compute the master/slave
- * drive PIO mode properly so that we can up the speed on a hotplug
- * system.
- */
-
-static void config_siimage_chipset_for_pio (ide_drive_t *drive, byte set_speed)
+static void sil_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- u8 channel_timings = siimage_taskfile_timing(HWIF(drive));
- u8 speed = 0, set_pio = ide_get_best_pio_mode(drive, 4, 5, NULL);
-
- /* WARNING PIO timing mess is going to happen b/w devices, argh */
- if ((channel_timings != set_pio) && (set_pio > channel_timings))
- set_pio = channel_timings;
-
- siimage_tuneproc(drive, set_pio);
- speed = XFER_PIO_0 + set_pio;
- if (set_speed)
- (void) ide_config_drive_speed(drive, speed);
+ sil_tune_pio(drive, pio);
+ (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
/**
* siimage_tune_chipset - set controller timings
* @drive: Drive to set up
- * @xferspeed: speed we want to achieve
+ * @speed: speed we want to achieve
*
- * Tune the SII chipset for the desired mode. If we can't achieve
- * the desired mode then tune for a lower one, but ultimately
- * make the thing work.
+ * Tune the SII chipset for the desired mode.
*/
-
-static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
+
+static int siimage_tune_chipset(ide_drive_t *drive, const u8 speed)
{
u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
@@ -302,7 +257,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
ide_hwif_t *hwif = HWIF(drive);
u16 ultra = 0, multi = 0;
u8 mode = 0, unit = drive->select.b.unit;
- u8 speed = ide_rate_filter(drive, xferspeed);
unsigned long base = (unsigned long)hwif->hwif_data;
u8 scsc = 0, addr_mask = ((hwif->channel) ?
((hwif->mmio) ? 0xF4 : 0x84) :
@@ -330,20 +284,11 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
scsc = is_sata(hwif) ? 1 : scsc;
switch(speed) {
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- siimage_tuneproc(drive, (speed - XFER_PIO_0));
- mode |= ((unit) ? 0x10 : 0x01);
- break;
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);
- config_siimage_chipset_for_pio(drive, 0);
break;
case XFER_UDMA_6:
case XFER_UDMA_5:
@@ -356,7 +301,6 @@ static int siimage_tune_chipset (ide_drive_t *drive, byte xferspeed)
ultra |= ((scsc) ? (ultra6[speed - XFER_UDMA_0]) :
(ultra5[speed - XFER_UDMA_0]));
mode |= ((unit) ? 0x30 : 0x03);
- config_siimage_chipset_for_pio(drive, 0);
break;
default:
return 1;
@@ -390,7 +334,7 @@ static int siimage_config_drive_for_dma (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- config_siimage_chipset_for_pio(drive, 1);
+ ide_set_max_pio(drive);
return -1;
}
@@ -961,7 +905,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
hwif->resetproc = &siimage_reset;
hwif->speedproc = &siimage_tune_chipset;
- hwif->tuneproc = &siimage_tuneproc;
+ hwif->set_pio_mode = &sil_set_pio_mode;
hwif->reset_poll = &siimage_reset_poll;
hwif->pre_reset = &siimage_pre_reset;
hwif->udma_filter = &sil_udma_filter;
@@ -976,11 +920,11 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
first = 0;
}
}
- if (!hwif->dma_base) {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
+
+ hwif->drives[0].autotune = hwif->drives[1].autotune = 1;
+
+ if (hwif->dma_base == 0)
return;
- }
hwif->ultra_mask = 0x7f;
hwif->mwdma_mask = 0x07;
@@ -1016,9 +960,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
.init_iops = init_iops_siimage, \
.init_hwif = init_hwif_siimage, \
.fixup = siimage_fixup, \
- .channels = 2, \
.autodma = AUTODMA, \
.bootable = ON_BOARD, \
+ .pio_mask = ATA_PIO4, \
}
static ide_pci_device_t siimage_chipsets[] __devinitdata = {
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 756a9b6eb462..3e18899de631 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/sis5513.c Version 0.25 Jun 10, 2007
+ * linux/drivers/ide/pci/sis5513.c Version 0.27 Jul 14, 2007
*
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
@@ -519,27 +519,18 @@ static void config_art_rwp_pio (ide_drive_t *drive, u8 pio)
}
}
-static int sis5513_tune_drive(ide_drive_t *drive, u8 pio)
+static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
config_art_rwp_pio(drive, pio);
- return ide_config_drive_speed(drive, XFER_PIO_0 + pio);
+ (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
-static void sis5513_tuneproc(ide_drive_t *drive, u8 pio)
-{
- (void)sis5513_tune_drive(drive, pio);
-}
-
-static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int sis5513_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
-
- u8 drive_pci, reg, speed;
u32 regdw;
-
- speed = ide_rate_filter(drive, xferspeed);
+ u8 drive_pci, reg;
/* See config_art_rwp_pio for drive pci config registers */
drive_pci = 0x40;
@@ -582,9 +573,6 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
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 {
- /* if ATA133 disable, we should not set speed above UDMA5 */
- if (speed > XFER_UDMA_5)
- speed = XFER_UDMA_5;
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;
}
@@ -608,12 +596,6 @@ static int sis5513_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
break;
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- return sis5513_tune_drive(drive, speed - XFER_PIO_0);
default:
BUG();
break;
@@ -627,7 +609,7 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive)
/*
* TODO: always set PIO mode and remove this
*/
- sis5513_tuneproc(drive, 255);
+ ide_set_max_pio(drive);
drive->init_speed = 0;
@@ -635,11 +617,25 @@ static int sis5513_config_xfer_rate(ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- sis5513_tuneproc(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
+static u8 sis5513_ata133_udma_filter(ide_drive_t *drive)
+{
+ struct pci_dev *dev = drive->hwif->pci_dev;
+ int drive_pci;
+ u32 reg54 = 0, regdw = 0;
+
+ pci_read_config_dword(dev, 0x54, &reg54);
+ drive_pci = ((reg54 & 0x40000000) ? 0x70 : 0x40) + drive->dn * 4;
+ pci_read_config_dword(dev, drive_pci, &regdw);
+
+ /* if ATA133 disable, we should not set speed above UDMA5 */
+ return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5;
+}
+
/* Chip detection and general config */
static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
{
@@ -801,6 +797,7 @@ struct sis_laptop {
static const struct sis_laptop sis_laptop[] = {
/* devid, subvendor, subdev */
{ 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */
+ { 0x5513, 0x1734, 0x105f }, /* FSC Amilo A1630 */
/* end marker */
{ 0, }
};
@@ -843,9 +840,12 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14;
- hwif->tuneproc = &sis5513_tuneproc;
+ hwif->set_pio_mode = &sis_set_pio_mode;
hwif->speedproc = &sis5513_tune_chipset;
+ if (chipset_family >= ATA_133)
+ hwif->udma_filter = sis5513_ata133_udma_filter;
+
if (!(hwif->dma_base)) {
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
@@ -878,10 +878,10 @@ static ide_pci_device_t sis5513_chipset __devinitdata = {
.name = "SIS5513",
.init_chipset = init_chipset_sis5513,
.init_hwif = init_hwif_sis5513,
- .channels = 2,
.autodma = NOAUTODMA,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
};
static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index a7323d278c49..f492318ba797 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -52,12 +52,13 @@
* Convert a PIO mode and cycle time to the required on/off times
* for the interface. This has protection against runaway timings.
*/
-static unsigned int get_pio_timings(ide_pio_data_t *p)
+static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
{
unsigned int cmd_on, cmd_off;
+ u8 iordy = 0;
- cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30;
- cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30;
+ cmd_on = (ide_pio_timings[pio].active_time + 29) / 30;
+ cmd_off = (ide_pio_cycle_time(drive, pio) - 30 * cmd_on + 29) / 30;
if (cmd_on == 0)
cmd_on = 1;
@@ -65,24 +66,22 @@ static unsigned int get_pio_timings(ide_pio_data_t *p)
if (cmd_off == 0)
cmd_off = 1;
- return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00);
+ if (pio > 2 || ide_dev_has_iordy(drive->id))
+ iordy = 0x40;
+
+ return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
}
/*
* Configure the chipset for PIO mode.
*/
-static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio)
+static void sl82c105_tune_pio(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
int reg = 0x44 + drive->dn * 4;
- ide_pio_data_t p;
u16 drv_ctrl;
- DBG(("sl82c105_tune_pio(drive:%s, pio:%u)\n", drive->name, pio));
-
- pio = ide_get_best_pio_mode(drive, pio, 5, &p);
-
- drv_ctrl = get_pio_timings(&p);
+ drv_ctrl = get_pio_timings(drive, pio);
/*
* Store the PIO timings so that we can restore them
@@ -101,15 +100,14 @@ static u8 sl82c105_tune_pio(ide_drive_t *drive, u8 pio)
}
printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name,
- ide_xfer_verbose(pio + XFER_PIO_0), p.cycle_time, drv_ctrl);
-
- return pio;
+ ide_xfer_verbose(pio + XFER_PIO_0),
+ ide_pio_cycle_time(drive, pio), drv_ctrl);
}
/*
* Configure the drive and chipset for a new transfer speed.
*/
-static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed)
+static int sl82c105_tune_chipset(ide_drive_t *drive, const u8 speed)
{
static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
u16 drv_ctrl;
@@ -117,8 +115,6 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed)
DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
drive->name, ide_xfer_verbose(speed)));
- speed = ide_rate_filter(drive, speed);
-
switch (speed) {
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
@@ -143,14 +139,6 @@ static int sl82c105_tune_chipset(ide_drive_t *drive, u8 speed)
pci_write_config_word(dev, reg, drv_ctrl);
}
break;
- case XFER_PIO_5:
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- (void) sl82c105_tune_pio(drive, speed - XFER_PIO_0);
- break;
default:
return -1;
}
@@ -323,11 +311,10 @@ static void sl82c105_resetproc(ide_drive_t *drive)
* We only deal with PIO mode here - DMA mode 'using_dma' is not
* initialised at the point that this function is called.
*/
-static void sl82c105_tune_drive(ide_drive_t *drive, u8 pio)
+static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- DBG(("sl82c105_tune_drive(drive:%s, pio:%u)\n", drive->name, pio));
+ sl82c105_tune_pio(drive, pio);
- pio = sl82c105_tune_pio(drive, pio);
(void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
@@ -395,7 +382,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
- hwif->tuneproc = &sl82c105_tune_drive;
+ hwif->set_pio_mode = &sl82c105_set_pio_mode;
hwif->speedproc = &sl82c105_tune_chipset;
hwif->selectproc = &sl82c105_selectproc;
hwif->resetproc = &sl82c105_resetproc;
@@ -449,10 +436,10 @@ static ide_pci_device_t sl82c105_chipset __devinitdata = {
.name = "W82C105",
.init_chipset = init_chipset_sl82c105,
.init_hwif = init_hwif_sl82c105,
- .channels = 2,
.autodma = NOAUTODMA,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO5,
};
static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 575dbbd8b482..ae8e91324577 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/slc90e66.c Version 0.14 February 8, 2007
+ * linux/drivers/ide/pci/slc90e66.c Version 0.16 Jul 14, 2007
*
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
@@ -29,20 +29,14 @@ static u8 slc90e66_dma_2_pio (u8 xfer_rate) {
case XFER_UDMA_1:
case XFER_UDMA_0:
case XFER_MW_DMA_2:
- case XFER_PIO_4:
return 4;
case XFER_MW_DMA_1:
- case XFER_PIO_3:
return 3;
case XFER_SW_DMA_2:
- case XFER_PIO_2:
return 2;
case XFER_MW_DMA_0:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
- case XFER_PIO_1:
- case XFER_PIO_0:
- case XFER_PIO_SLOW:
default:
return 0;
}
@@ -101,19 +95,17 @@ static void slc90e66_tune_pio (ide_drive_t *drive, u8 pio)
spin_unlock_irqrestore(&ide_lock, flags);
}
-static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio)
+static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
slc90e66_tune_pio(drive, pio);
(void) ide_config_drive_speed(drive, XFER_PIO_0 + pio);
}
-static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
+static int slc90e66_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
u8 maslave = hwif->channel ? 0x42 : 0x40;
- u8 speed = ide_rate_filter(drive, xferspeed);
int sitre = 0, a_speed = 7 << (drive->dn * 4);
int u_speed = 0, u_flag = 1 << drive->dn;
u16 reg4042, reg44, reg48, reg4a;
@@ -133,10 +125,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_0: break;
default: return -1;
}
@@ -157,6 +145,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed)
}
slc90e66_tune_pio(drive, slc90e66_dma_2_pio(speed));
+
return ide_config_drive_speed(drive, speed);
}
@@ -168,7 +157,7 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- slc90e66_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -184,7 +173,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
hwif->irq = hwif->channel ? 15 : 14;
hwif->speedproc = &slc90e66_tune_chipset;
- hwif->tuneproc = &slc90e66_tune_drive;
+ hwif->set_pio_mode = &slc90e66_set_pio_mode;
pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
@@ -214,10 +203,10 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
static ide_pci_device_t slc90e66_chipset __devinitdata = {
.name = "SLC90E66",
.init_hwif = init_hwif_slc90e66,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
};
static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 8de1f8e22494..e23b9cfb6eb4 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -13,14 +13,12 @@
#include <linux/pci.h>
#include <linux/ide.h>
-static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
+static int tc86c001_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
u16 mode, scr = hwif->INW(scr_port);
- speed = ide_rate_filter(drive, speed);
-
switch (speed) {
case XFER_UDMA_4: mode = 0x00c0; break;
case XFER_UDMA_3: mode = 0x00b0; break;
@@ -45,9 +43,8 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
return ide_config_drive_speed(drive, speed);
}
-static void tc86c001_tune_drive(ide_drive_t *drive, u8 pio)
+static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
(void) tc86c001_tune_chipset(drive, XFER_PIO_0 + pio);
}
@@ -173,7 +170,7 @@ static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
return 0;
if (ide_use_fast_pio(drive))
- tc86c001_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
@@ -195,7 +192,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
/* Store the system control register base for convenience... */
hwif->config_data = sc_base;
- hwif->tuneproc = &tc86c001_tune_drive;
+ hwif->set_pio_mode = &tc86c001_set_pio_mode;
hwif->speedproc = &tc86c001_tune_chipset;
hwif->busproc = &tc86c001_busproc;
@@ -248,9 +245,10 @@ static ide_pci_device_t tc86c001_chipset __devinitdata = {
.name = "TC86C001",
.init_chipset = init_chipset_tc86c001,
.init_hwif = init_hwif_tc86c001,
- .channels = 1,
.autodma = AUTODMA,
- .bootable = OFF_BOARD
+ .bootable = OFF_BOARD,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4,
};
static int __devinit tc86c001_init_one(struct pci_dev *dev,
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index 35e8c612638f..c3ff066eea5a 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -40,7 +40,7 @@
#include <linux/ide.h>
#include <linux/init.h>
-static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed)
+static int triflex_tune_chipset(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
@@ -48,7 +48,6 @@ static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed)
u16 timing = 0;
u32 triflex_timings = 0;
u8 unit = (drive->select.b.unit & 0x01);
- u8 speed = ide_rate_filter(drive, xferspeed);
pci_read_config_dword(dev, channel_offset, &triflex_timings);
@@ -94,10 +93,9 @@ static int triflex_tune_chipset(ide_drive_t *drive, u8 xferspeed)
return (ide_config_drive_speed(drive, speed));
}
-static void triflex_tune_drive(ide_drive_t *drive, u8 pio)
+static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- int use_pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
- (void) triflex_tune_chipset(drive, (XFER_PIO_0 + use_pio));
+ (void)triflex_tune_chipset(drive, XFER_PIO_0 + pio);
}
static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
@@ -105,16 +103,19 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
if (ide_tune_dma(drive))
return 0;
- triflex_tune_drive(drive, 255);
+ ide_set_max_pio(drive);
return -1;
}
static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
{
- hwif->tuneproc = &triflex_tune_drive;
+ hwif->set_pio_mode = &triflex_set_pio_mode;
hwif->speedproc = &triflex_tune_chipset;
+ if (hwif->dma_base == 0)
+ return;
+
hwif->atapi_dma = 1;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask = 0x07;
@@ -129,10 +130,10 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
static ide_pci_device_t triflex_device __devinitdata = {
.name = "TRIFLEX",
.init_hwif = init_hwif_triflex,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
.bootable = ON_BOARD,
+ .pio_mask = ATA_PIO4,
};
static int __devinit triflex_init_one(struct pci_dev *dev,
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index cbb1b11119a5..dc4f4e298e00 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -327,7 +327,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
static ide_pci_device_t trm290_chipset __devinitdata = {
.name = "TRM290",
.init_hwif = init_hwif_trm290,
- .channels = 2,
.autodma = NOAUTODMA,
.bootable = ON_BOARD,
};
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 27e92fb9f95e..378feb491ec4 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -1,6 +1,6 @@
/*
*
- * Version 3.45
+ * Version 3.48
*
* VIA IDE driver for Linux. Supported southbridges:
*
@@ -74,6 +74,7 @@ static struct via_isa_bridge {
u8 udma_mask;
u8 flags;
} via_isa_bridges[] = {
+ { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@@ -157,7 +158,7 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
* by upper layers.
*/
-static int via_set_drive(ide_drive_t *drive, u8 speed)
+static int via_set_drive(ide_drive_t *drive, const u8 speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct via82cxxx_dev *vdev = pci_get_drvdata(drive->hwif->pci_dev);
@@ -194,21 +195,16 @@ static int via_set_drive(ide_drive_t *drive, u8 speed)
}
/**
- * via82cxxx_tune_drive - PIO setup
- * @drive: drive to set up
- * @pio: mode to use (255 for 'best possible')
+ * via_set_pio_mode - PIO setup
+ * @drive: drive
+ * @pio: PIO mode number
*
* A callback from the upper layers for PIO-only tuning.
*/
-static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
+static void via_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- if (pio == 255) {
- via_set_drive(drive, ide_find_best_pio_mode(drive));
- return;
- }
-
- via_set_drive(drive, XFER_PIO_0 + min_t(u8, pio, 5));
+ via_set_drive(drive, XFER_PIO_0 + pio);
}
/**
@@ -221,16 +217,11 @@ static void via82cxxx_tune_drive(ide_drive_t *drive, u8 pio)
static int via82cxxx_ide_dma_check (ide_drive_t *drive)
{
- u8 speed = ide_max_dma_mode(drive);
-
- if (speed == 0)
- speed = ide_find_best_pio_mode(drive);
-
- via_set_drive(drive, speed);
-
- if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
+ if (ide_tune_dma(drive))
return 0;
+ ide_set_max_pio(drive);
+
return -1;
}
@@ -418,7 +409,7 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const
* Cable special cases
*/
-static struct dmi_system_id cable_dmi_table[] = {
+static const struct dmi_system_id cable_dmi_table[] = {
{
.ident = "Acer Ferrari 3400",
.matches = {
@@ -429,19 +420,26 @@ static struct dmi_system_id cable_dmi_table[] = {
{ }
};
-static int via_cable_override(void)
+static int via_cable_override(struct pci_dev *pdev)
{
/* Systems by DMI */
if (dmi_check_system(cable_dmi_table))
return 1;
+
+ /* Arima W730-K8/Targa Visionary 811/... */
+ if (pdev->subsystem_vendor == 0x161F &&
+ pdev->subsystem_device == 0x2032)
+ return 1;
+
return 0;
}
static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
{
- struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
+ struct pci_dev *pdev = hwif->pci_dev;
+ struct via82cxxx_dev *vdev = pci_get_drvdata(pdev);
- if (via_cable_override())
+ if (via_cable_override(pdev))
return ATA_CBL_PATA40_SHORT;
if ((vdev->via_80w >> hwif->channel) & 1)
@@ -457,7 +455,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
hwif->autodma = 0;
- hwif->tuneproc = &via82cxxx_tune_drive;
+ hwif->set_pio_mode = &via_set_pio_mode;
hwif->speedproc = &via_set_drive;
@@ -498,18 +496,22 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
.name = "VP_IDE",
.init_chipset = init_chipset_via82cxxx,
.init_hwif = init_hwif_via82cxxx,
- .channels = 2,
.autodma = NOAUTODMA,
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
- .bootable = ON_BOARD
+ .bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST
+ | IDE_HFLAG_PIO_NO_DOWNGRADE,
+ .pio_mask = ATA_PIO5,
},{ /* 1 */
.name = "VP_IDE",
.init_chipset = init_chipset_via82cxxx,
.init_hwif = init_hwif_via82cxxx,
- .channels = 2,
.autodma = AUTODMA,
.enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
.bootable = ON_BOARD,
+ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST
+ | IDE_HFLAG_PIO_NO_DOWNGRADE,
+ .pio_mask = ATA_PIO5,
}
};