summaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 01:05:20 +0000
commit546db14ee74118296f425f3b91634fb767d67290 (patch)
tree22b613a3da8d4bf663eec5e155af01b87fdf9094 /drivers/block
parent1e25e41c4f5474e14452094492dbc169b800e4c8 (diff)
Merge with Linux 2.3.23. The new bootmem stuff has broken various
platforms. At this time I've only verified that IP22 support compiles and IP27 actually works.
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/Config.in31
-rw-r--r--drivers/block/Makefile5
-rw-r--r--drivers/block/aec6210.c9
-rw-r--r--drivers/block/alim15x3.c735
-rw-r--r--drivers/block/cy82c693.c28
-rw-r--r--drivers/block/genhd.c2
-rw-r--r--drivers/block/hpt34x.c176
-rw-r--r--drivers/block/hpt366.c263
-rw-r--r--drivers/block/icside.c4
-rw-r--r--drivers/block/ide-cd.c352
-rw-r--r--drivers/block/ide-cd.h86
-rw-r--r--drivers/block/ide-disk.c13
-rw-r--r--drivers/block/ide-dma.c12
-rw-r--r--drivers/block/ide-floppy.c9
-rw-r--r--drivers/block/ide-geometry.c3
-rw-r--r--drivers/block/ide-pci.c205
-rw-r--r--drivers/block/ide-pmac.c3
-rw-r--r--drivers/block/ide-probe.c35
-rw-r--r--drivers/block/ide-proc.c73
-rw-r--r--drivers/block/ide-tape.c9
-rw-r--r--drivers/block/ide.c214
-rw-r--r--drivers/block/ll_rw_blk.c13
-rw-r--r--drivers/block/paride/pcd.c210
-rw-r--r--drivers/block/pdc202xx.c343
-rw-r--r--drivers/block/pdc4030.c23
-rw-r--r--drivers/block/piix.c55
-rw-r--r--drivers/block/rd.c3
-rw-r--r--drivers/block/sis5513.c299
-rw-r--r--drivers/block/sl82c105.c2
-rw-r--r--drivers/block/trm290.c3
-rw-r--r--drivers/block/via82cxxx.c (renamed from drivers/block/via82c586.c)220
31 files changed, 2033 insertions, 1405 deletions
diff --git a/drivers/block/Config.in b/drivers/block/Config.in
index c23b8d094..7f70e32ee 100644
--- a/drivers/block/Config.in
+++ b/drivers/block/Config.in
@@ -62,17 +62,15 @@ else
fi
if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X
- if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a \
- "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then
- bool ' HPT34X DMA support (DANGEROUS)' CONFIG_BLK_DEV_HPT34X_DMA
+ if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a "$CONFIG_BLK_DEV_HPT34X" = "y" ]; then
+ bool ' HPT34X DMA support (EXPERIMENTAL)' CONFIG_BLK_DEV_HPT34X_DMA
fi
bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366
fi
if [ "$CONFIG_X86" = "y" ]; then
bool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX
- if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" -a \
- "$CONFIG_BLK_DEV_PIIX" = "y" ]; then
- bool ' PIIXn Tuning support (EXPERIMENTAL)' CONFIG_BLK_DEV_PIIX_TUNING
+ if [ "$CONFIG_BLK_DEV_PIIX" = "y" ]; then
+ bool ' PIIXn Tuning support' CONFIG_BLK_DEV_PIIX_TUNING
fi
fi
if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
@@ -83,19 +81,20 @@ else
fi
if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" ]; then
bool ' PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX
- if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
- "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then
- bool ' Special UDMA Feature (EXPERIMENTAL)' CONFIG_PDC202XX_FORCE_BURST_BIT
- bool ' Special Mode Feature (DANGEROUS)' CONFIG_PDC202XX_FORCE_MASTER_MODE
+ if [ "$CONFIG_BLK_DEV_PDC202XX" = "y" ]; then
+ bool ' Special UDMA Feature' CONFIG_PDC202XX_FORCE_BURST_BIT
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool ' Special Mode Feature (EXPERIMENTAL)' CONFIG_PDC202XX_FORCE_MASTER_MODE
+ fi
+ fi
+ if [ "$CONFIG_X86" = "y" ]; then
+ bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513
fi
- fi
- if [ "$CONFIG_X86" = "y" ]; then
- bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513
fi
if [ "$CONFIG_IDEDMA_PCI_EXPERIMENTAL" = "y" ]; then
bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290
if [ "$CONFIG_X86" = "y" ]; then
- bool ' VIA82C586 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82C586
+ bool ' VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX
fi
fi
fi
@@ -139,8 +138,7 @@ else
bool ' ALI M14xx support' CONFIG_BLK_DEV_ALI14XX
bool ' DTC-2278 support' CONFIG_BLK_DEV_DTC2278
bool ' Holtek HT6560B support' CONFIG_BLK_DEV_HT6560B
- if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a \
- "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
fi
bool ' QDI QD6580 support' CONFIG_BLK_DEV_QD6580
@@ -225,6 +223,7 @@ if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \
"$CONFIG_BLK_DEV_HPT366" = "y" -o \
"$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \
"$CONFIG_BLK_DEV_OPTI621" = "y" -o \
+ "$CONFIG_BLK_DEV_PDC202XX" = "y" -o \
"$CONFIG_BLK_DEV_PIIX" = "y" -o \
"$CONFIG_BLK_DEV_SIS5513" = "y" -o \
"$CONFIG_BLK_DEV_SL82C105" = "y" ]; then
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 8519318d9..1de4fa581 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -230,8 +230,8 @@ ifeq ($(CONFIG_BLK_DEV_UMC8672),y)
IDE_OBJS += umc8672.o
endif
-ifeq ($(CONFIG_BLK_DEV_VIA82C586),y)
-IDE_OBJS += via82c586.o
+ifeq ($(CONFIG_BLK_DEV_VIA82CXXX),y)
+IDE_OBJS += via82cxxx.o
endif
### if CONFIG_BLK_DEV_IDE is n, IDE_OBJS will be ignored
@@ -379,4 +379,3 @@ ide-mod.o: ide.o $(IDE_OBJS)
ide-probe-mod.o: ide-probe.o ide-geometry.o
$(LD) $(LD_RFLAG) -r -o $@ ide-probe.o ide-geometry.o
-
diff --git a/drivers/block/aec6210.c b/drivers/block/aec6210.c
index c52d8450d..75bb8657f 100644
--- a/drivers/block/aec6210.c
+++ b/drivers/block/aec6210.c
@@ -1,7 +1,8 @@
/*
- * linux/drivers/block/aec6210.c Version 0.01 Nov 17, 1998
+ * linux/drivers/block/aec6210.c Version 0.02 Sept. 3, 1999
*
- * Copyright (C) 1998-99 Andre Hedrick
+ * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
* pio 0 :: 40: 00 07 00 00 00 00 00 00 02 07 a6 04 00 02 00 02
* pio 1 :: 40: 0a 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02
@@ -50,6 +51,10 @@
#include <asm/io.h>
#include <asm/irq.h>
+/*
+ * TO DO: active tuning and correction of cards without a bios.
+ */
+
unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name)
{
if (dev->resource[PCI_ROM_RESOURCE].start) {
diff --git a/drivers/block/alim15x3.c b/drivers/block/alim15x3.c
index b7a0a5c4f..545361052 100644
--- a/drivers/block/alim15x3.c
+++ b/drivers/block/alim15x3.c
@@ -1,21 +1,28 @@
/*
- * linux/drivers/block/alim15x3.c Version 0.05 Jun. 29, 1999
+ * linux/drivers/block/alim15x3.c Version 0.06 Sept. 3, 1999
*
* Copyright (C) 1998-99 Michel Aubry, Maintainer
* Copyright (C) 1998-99 Andrzej Krzysztofowicz, Maintainer
- * Copyright (C) 1998-99 Andre Hedrick, Integrater and Maintainer
*
- * (U)DMA capable version of ali 1533/1543(C)
+ * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
- * Default disable (U)DMA on all devices execpt hard disks.
- * This measure of overkill is needed to stablize the chipset code.
+ * (U)DMA capable version of ali 1533/1543(C), 1535(D)
*
+ * version: 1.0 beta2 (Sep. 2, 1999)
+ * e-mail your problems to cjtsai@ali.com.tw
+ *
+ **********************************************************************
+ * 9/7/99 --Parts from the above author are included and need to be
+ * converted into standard interface, once I finish the thought.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/hdreg.h>
#include <linux/ide.h>
#include <asm/io.h>
@@ -59,188 +66,7 @@ char *channel_status[8] = {
"error DRQ ",
"error DRQ busy"
};
-#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
-
-static void ali15x3_tune_drive (ide_drive_t *drive, byte 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;
- byte s_clc, a_clc, r_clc;
- unsigned long flags;
- int bus_speed = ide_system_bus_speed();
- int port = hwif->index ? 0x5c : 0x58;
-
- 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)
- s_clc = 0;
- if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
- a_clc = 0;
- c_time = ide_pio_timings[pio].cycle_time;
-
-#if 0
- if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16)
- r_clc = 0;
-#endif
- if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
- r_clc = 1;
- } else {
- if (r_clc >= 16)
- r_clc = 0;
- }
- save_flags(flags);
- cli();
- pci_write_config_byte(dev, port, s_clc);
- pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
- restore_flags(flags);
-
- /*
- * setup active rec
- * { 70, 165, 365 }, PIO Mode 0
- * { 50, 125, 208 }, PIO Mode 1
- * { 30, 100, 110 }, PIO Mode 2
- * { 30, 80, 70 }, PIO Mode 3 with IORDY
- * { 25, 70, 25 }, PIO Mode 4 with IORDY ns
- * { 20, 50, 30 } PIO Mode 5 with IORDY (nonstandard)
- */
-
-}
-
-unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
-{
- byte confreg0 = 0, confreg1 =0, progif = 0;
- int errors = 0;
-
- if (pci_read_config_byte(dev, 0x50, &confreg1))
- goto veryspecialsettingserror;
- if (!(confreg1 & 0x02))
- if (pci_write_config_byte(dev, 0x50, confreg1 | 0x02))
- goto veryspecialsettingserror;
-
- if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif))
- goto veryspecialsettingserror;
- if (!(progif & 0x40)) {
- /*
- * The way to enable them is to set progif
- * writable at 0x4Dh register, and set bit 6
- * of progif to 1:
- */
- if (pci_read_config_byte(dev, 0x4d, &confreg0))
- goto veryspecialsettingserror;
- if (confreg0 & 0x80)
- if (pci_write_config_byte(dev, 0x4d, confreg0 & ~0x80))
- goto veryspecialsettingserror;
- if (pci_write_config_byte(dev, PCI_CLASS_PROG, progif | 0x40))
- goto veryspecialsettingserror;
- if (confreg0 & 0x80)
- if (pci_write_config_byte(dev, 0x4d, confreg0))
- errors++;
- }
-
- if ((pci_read_config_byte(dev, PCI_CLASS_PROG, &progif)) || (!(progif & 0x40)))
- goto veryspecialsettingserror;
-
- printk("%s: enabled read of IDE channels state (en/dis-abled) %s.\n",
- name, errors ? "with Error(s)" : "Succeeded" );
- return 0;
-
-veryspecialsettingserror:
- printk("%s: impossible to enable read of IDE channels state (en/dis-abled)!\n", name);
- return 0;
-}
-
-int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
-{
- switch (func) {
- case ide_dma_check:
- if (drive->media == ide_cdrom) {
- ide_hwif_t *hwif = HWIF(drive);
- struct pci_dev *dev = hwif->pci_dev;
- struct hd_driveid *id = drive->id;
- byte cd_dma_fifo = 0;
-
- pci_read_config_byte(dev, 0x53, &cd_dma_fifo);
-
- if (((id->field_valid & 4) || (id->field_valid & 2)) &&
- (id->capability & 1) && hwif->autodma) {
- unsigned long dma_set_bit = hwif->dma_base + 2;
-#if 0
- if (cd_dma_fifo & 0x02)
- pci_write_config_byte(dev, 0x53, cd_dma_fifo & ~0x02);
- pci_write_config_byte(dev, 0x53, cd_dma_fifo|0x01);
-#else
- pci_write_config_byte(dev, 0x53, cd_dma_fifo|0x01|0x02);
-#endif
- if (drive->select.b.unit & 0x01) {
- outb(inb(dma_set_bit)|0x40, dma_set_bit);
- } else {
- outb(inb(dma_set_bit)|0x20, dma_set_bit);
- }
- } else {
- if (cd_dma_fifo & 0x01)
- pci_write_config_byte(dev, 0x53, cd_dma_fifo & ~0x01);
- pci_write_config_byte(dev, 0x53, cd_dma_fifo|0x02);
- }
- } else if (drive->media != ide_disk) {
- return ide_dmaproc(ide_dma_off_quietly, drive);
- }
- default:
- break;
- }
- return ide_dmaproc(func, drive); /* use standard DMA stuff */
-}
-
-void __init ide_init_ali15x3 (ide_hwif_t *hwif)
-{
- struct pci_dev *dev;
- byte ideic, inmir, iderev;
- byte irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
- 1, 11, 0, 12, 0, 14, 0, 15 };
-
- pci_read_config_byte(hwif->pci_dev, PCI_REVISION_ID, &iderev);
-
- hwif->irq = hwif->channel ? 15 : 14;
- for (dev = pci_devices; dev; dev=dev->next) /* look for ISA bridge */
- if (dev->vendor==PCI_VENDOR_ID_AL &&
- dev->device==PCI_DEVICE_ID_AL_M1533)
- break;
- if (dev) {
- pci_read_config_byte(dev, 0x58, &ideic);
- ideic = ideic & 0x03;
- if ((hwif->channel && ideic == 0x03) ||
- (!hwif->channel && !ideic)) {
- pci_read_config_byte(dev, 0x44, &inmir);
- inmir = inmir & 0x0f;
- hwif->irq = irq_routing_table[inmir];
- } else
- if (hwif->channel && !(ideic & 0x01)) {
- pci_read_config_byte(dev, 0x75, &inmir);
- inmir = inmir & 0x0f;
- hwif->irq = irq_routing_table[inmir];
- }
- }
-#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
- bmide_dev = hwif->pci_dev;
- ali_display_info = &ali_get_info;
-#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
-
- hwif->tuneproc = &ali15x3_tune_drive;
- if ((hwif->dma_base) && (iderev >= 0xC1)) {
- /* M1543C or newer for DMAing */
- hwif->dmaproc = &ali15x3_dmaproc;
- } else {
- hwif->autodma = 0;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
- }
- return;
-}
-
-#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int dummy)
{
byte reg53h, reg5xh, reg5yh, reg5xh1, reg5yh1;
@@ -407,3 +233,540 @@ static int ali_get_info(char *buffer, char **addr, off_t offset, int count, int
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+static byte m5229_revision = 0;
+static byte chip_is_1543c_e = 0;
+static byte cable_80_pin[2] = { 0, 0 };
+
+byte ali_proc = 0;
+static struct pci_dev *isa_dev;
+
+static void ali15x3_tune_drive (ide_drive_t *drive, byte 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;
+ byte s_clc, a_clc, r_clc;
+ unsigned long flags;
+ int bus_speed = ide_system_bus_speed();
+ int port = hwif->index ? 0x5c : 0x58;
+
+ 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)
+ s_clc = 0;
+ if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
+ a_clc = 0;
+ c_time = ide_pio_timings[pio].cycle_time;
+
+#if 0
+ if ((r_clc = ((c_time - s_time - a_time) * bus_speed + 999) / 1000) >= 16)
+ r_clc = 0;
+#endif
+
+ if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
+ r_clc = 1;
+ } else {
+ if (r_clc >= 16)
+ r_clc = 0;
+ }
+ save_flags(flags);
+ cli();
+ pci_write_config_byte(dev, port, s_clc);
+ pci_write_config_byte(dev, port+drive->select.b.unit+2, (a_clc << 4) | r_clc);
+ restore_flags(flags);
+
+ /*
+ * setup active rec
+ * { 70, 165, 365 }, PIO Mode 0
+ * { 50, 125, 208 }, PIO Mode 1
+ * { 30, 100, 110 }, PIO Mode 2
+ * { 30, 80, 70 }, PIO Mode 3 with IORDY
+ * { 25, 70, 25 }, PIO Mode 4 with IORDY ns
+ * { 20, 50, 30 } PIO Mode 5 with IORDY (nonstandard)
+ */
+
+}
+
+static __inline__ unsigned char dma2_bits_to_command(unsigned char bits)
+{
+ if (bits & 0x04)
+ return XFER_MW_DMA_2;
+ if (bits & 0x02)
+ return XFER_MW_DMA_1;
+ return XFER_MW_DMA_0;
+}
+
+static __inline__ unsigned char udma2_bits_to_command(unsigned char bits)
+{
+ if (bits & 0x10)
+ return XFER_UDMA_4;
+ if (bits & 0x08)
+ return XFER_UDMA_3;
+ if (bits & 0x04)
+ return XFER_UDMA_2;
+ if (bits & 0x02)
+ return XFER_UDMA_1;
+ return XFER_UDMA_0;
+}
+
+static __inline__ int wait_for_ready(ide_drive_t *drive)
+{
+ int timeout = 20000; /* (old value: 100) */
+ byte stat;
+
+ while (--timeout) {
+ stat = GET_STAT();
+ /*
+ * printk("STAT(%2x) ", stat);
+ */
+ if (!(stat & BUSY_STAT)) {
+ if ((stat & READY_STAT) || (stat & ERR_STAT)) {
+ break;
+ }
+ }
+ /*
+ * (old value: 100)
+ */
+ udelay(150);
+ }
+ if ((stat & ERR_STAT) || timeout <= 0)
+ return 1;
+ return 0;
+}
+
+static void ali15x3_do_setfeature(ide_drive_t *drive, byte command)
+{
+ unsigned long flags;
+ byte old_select;
+
+ save_flags(flags);
+ cli();
+
+ /* save old selected device */
+ old_select = IN_BYTE(IDE_SELECT_REG);
+ /* "SELECT " */
+ OUT_BYTE(drive->select.all, IDE_SELECT_REG);
+ /* "SETXFER " */
+ OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
+ /* "CMND " */
+ OUT_BYTE(command, IDE_NSECTOR_REG);
+
+ if(wait_for_ready(drive)) /* "wait " */
+ goto out;
+
+ /* "SETFEATURE " */
+ OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
+ /* "wait " */
+ (void) wait_for_ready(drive);
+
+out:
+ /*
+ * restore to old "selected device"
+ */
+ OUT_BYTE(old_select, IDE_SELECT_REG);
+ restore_flags(flags);
+}
+
+static void ali15x3_dma2_enable(ide_drive_t *drive, unsigned long dma_base)
+{
+ byte unit = (drive->select.b.unit & 0x01);
+ byte bits = (drive->id->dma_mword | drive->id->dma_1word) & 0x07;
+ byte tmpbyte;
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long flags;
+ int m5229_udma_setting_index = hwif->channel? 0x57 : 0x56;
+
+ ali15x3_do_setfeature(drive, dma2_bits_to_command(bits));
+
+ /*
+ * clear "ultra enable" bit
+ */
+ pci_read_config_byte(hwif->pci_dev, m5229_udma_setting_index, &tmpbyte);
+ if (unit) {
+ tmpbyte &= 0x7f;
+ } else {
+ tmpbyte &= 0xf7;
+ }
+ save_flags(flags);
+ cli();
+ pci_write_config_byte(hwif->pci_dev, m5229_udma_setting_index, tmpbyte);
+ restore_flags(flags);
+ drive->id->dma_ultra = 0x00;
+
+ /*
+ * Enable DMA
+ */
+ outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+ printk("ALI15X3: MultiWord DMA enabled\n");
+}
+
+static void ali15x3_udma_enable(ide_drive_t *drive, unsigned long dma_base)
+{
+ byte unit = (drive->select.b.unit & 0x01);
+ byte bits = drive->id->dma_ultra & 0x1f;
+ byte tmpbyte;
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long flags;
+ unsigned char udma_mode = 0;
+ int m5229_udma_setting_index = hwif->channel? 0x57 : 0x56;
+
+ if (bits & 0x18) {
+ /*
+ * 00011000, disk: ultra66
+ */
+ if (m5229_revision < 0xc2) {
+ /*
+ * controller: ultra33
+ */
+ bits = 0x04;
+ /*
+ * 00000100, use ultra33, mode 2
+ */
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x0004;
+ } else {
+ /*
+ * controller: ultra66
+ *
+ * Try to detect word93 bit13 and
+ * 80-pin cable (from host view)
+ */
+ if (!((drive->id->word93 & 0x2000) &&
+ cable_80_pin[hwif->channel])) {
+ bits = 0x04;
+ /*
+ * 00000100, use ultra33, mode 2
+ */
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x0004;
+ }
+ }
+ }
+
+ /*
+ * set feature regardless
+ */
+ ali15x3_do_setfeature(drive, udma_mode = udma2_bits_to_command(bits));
+ udma_mode &= 0x0f; /* get UDMA mode */
+
+ /*
+ * Enable DMA and UltraDMA
+ */
+ outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+ /*
+ * m5229 ultra
+ */
+ pci_read_config_byte(hwif->pci_dev, m5229_udma_setting_index, &tmpbyte);
+ /*
+ * clear bit0~3 or bit 4~7
+ */
+ tmpbyte &= (0x0f << ((1-unit) << 2));
+ /*
+ * enable ultra dma and set timing
+ */
+ tmpbyte |= ((0x08 | (4-udma_mode)) << (unit << 2));
+ /*
+ * set to m5229
+ */
+ save_flags(flags);
+ cli();
+ pci_write_config_byte(hwif->pci_dev, m5229_udma_setting_index, tmpbyte);
+ restore_flags(flags);
+
+ if (udma_mode >= 3) {
+ /*
+ * ultra 66
+ */
+ pci_read_config_byte(hwif->pci_dev, 0x4b, &tmpbyte);
+ tmpbyte |= 1;
+ save_flags(flags);
+ cli();
+ pci_write_config_byte(hwif->pci_dev, 0x4b, tmpbyte);
+ restore_flags(flags);
+ }
+
+ printk("ALI15X3: Ultra DMA enabled\n");
+}
+
+static int ali15x3_dma_onoff(ide_drive_t *drive, int enable)
+{
+ if (enable) {
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long dma_base = hwif->dma_base;
+ struct hd_driveid *id = drive->id;
+
+ if ((id->field_valid & 0x0004) &&
+ (id->dma_ultra & 0x001f)) {
+ /*
+ * 1543C_E, in ultra mode, WDC "harddisk"
+ * will cause "CRC" errors (even if no CRC problem),
+ * so we try to use "DMA" here
+ */
+ if (m5229_revision <= 0x20) {
+ /*
+ * Normal MultiWord DMA modes.
+ */
+ ali15x3_dma2_enable(drive, dma_base);
+ } else if ((m5229_revision < 0xC2) &&
+ ((drive->media!=ide_disk) ||
+ (chip_is_1543c_e &&
+ strstr(id->model, "WDC ")))) {
+ /*
+ * Normal MultiWord DMA modes.
+ */
+ ali15x3_dma2_enable(drive, dma_base);
+ } else {
+ /*
+ * m5229_revision >= 0xC2 for UltraDMA modes.
+ */
+ ali15x3_udma_enable(drive, dma_base);
+ }
+ } else {
+ /*
+ * Normal MultiWord DMA modes.
+ */
+ ali15x3_dma2_enable(drive, dma_base);
+ }
+ }
+
+ drive->using_dma = enable; /* on, off */
+ return 0;
+}
+
+static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
+{
+ struct hd_driveid *id = drive->id;
+ ide_hwif_t *hwif = HWIF(drive);
+
+ if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
+ return hwif->dmaproc(ide_dma_off_quietly, drive);
+ /*
+ * Even if the drive is not _currently_ in a DMA
+ * mode, we succeed, and we'll enable it manually
+ * below in alim15x3_dma_onoff
+ */
+ if ((id != NULL) && (id->capability & 1) && hwif->autodma) {
+ if (id->field_valid & 0x0004) {
+ if (id->dma_ultra & 0x001F)
+ return hwif->dmaproc(ide_dma_on, drive);
+ }
+ if (id->field_valid & 0x0002) {
+ if ((id->dma_mword & 0x0007) || (id->dma_1word & 0x0007))
+ return hwif->dmaproc(ide_dma_on, drive);
+ }
+ }
+ return hwif->dmaproc(ide_dma_off_quietly, drive);
+}
+
+static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+ switch(func) {
+ case ide_dma_check:
+ return ali15x3_config_drive_for_dma(drive);
+ case ide_dma_on:
+ case ide_dma_off:
+ case ide_dma_off_quietly:
+ return ali15x3_dma_onoff(drive, (func == ide_dma_on));
+ case ide_dma_write:
+ if ((m5229_revision < 0xC2) && (drive->media != ide_disk))
+ return 1; /* try PIO instead of DMA */
+ break;
+ default:
+ break;
+ }
+
+ return ide_dmaproc(func, drive); /* use standard DMA stuff */
+}
+
+unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
+{
+ struct pci_dev *isa;
+ unsigned long fixdma_base = dev->resource[4].start;
+ byte tmpbyte;
+
+ pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision);
+
+ for (isa = pci_devices; isa; isa=isa->next) {
+ /*
+ * look for ISA bridge
+ */
+ if (isa->vendor == PCI_VENDOR_ID_AL &&
+ isa->device == PCI_DEVICE_ID_AL_M1533) {
+ isa_dev = isa;
+ break;
+ }
+ }
+
+ if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) {
+ /*
+ *
+ */
+ } else {
+ /*
+ * enable DMA capable bit, and "not" simplex only
+ */
+ outb(inb(fixdma_base+2) & 0x60, fixdma_base+2);
+
+ if (inb(fixdma_base+2) & 0x80)
+ printk("%s: simplex device: DMA will fail!!\n", name);
+ }
+
+ /*
+ * FIXME !!! This detection needs to be in "ata66_ali15x3()"
+ * below as a standard detection return.
+ */
+
+ if (m5229_revision >= 0xC2) {
+ unsigned long flags;
+ /*
+ * 1543C-B?, 1535, 1535D, 1553
+ * Note 1: not all "motherboard" support this detection
+ * Note 2: if no udma 66 device, the detection may "error".
+ * but in this case, we will not set the device to
+ * ultra 66, the detection result is not important
+ */
+ save_flags(flags);
+ cli();
+
+ /*
+ * enable "Cable Detection", m5229, 0x4b, bit3
+ */
+ pci_read_config_byte(dev, 0x4b, &tmpbyte);
+ pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08);
+
+ /*
+ * set south-bridge's enable bit, m1533, 0x79
+ */
+ pci_read_config_byte(isa_dev, 0x79, &tmpbyte);
+ if (m5229_revision == 0xC2) {
+ /*
+ * 1543C-B0 (m1533, 0x79, bit 2)
+ */
+ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04);
+ } else if (m5229_revision == 0xC3) {
+ /*
+ * 1553/1535 (m1533, 0x79, bit 1)
+ */
+ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
+ }
+ restore_flags(flags);
+ /*
+ * Ultra66 cable detection (from Host View)
+ * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin
+ */
+ pci_read_config_byte(dev, 0x4a, &tmpbyte);
+ /*
+ * 0x4a, bit0 is 0 => primary channel
+ * has 80-pin (from host view)
+ */
+ if (!(tmpbyte & 0x01))
+ cable_80_pin[0] = 1;
+ /*
+ * 0x4a, bit1 is 0 => secondary channel
+ * has 80-pin (from host view)
+ */
+ if (!(tmpbyte & 0x02))
+ cable_80_pin[1] = 1;
+ } else {
+ unsigned long flags;
+ /*
+ * revision 0x20 (1543-E, 1543-F)
+ * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
+ * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7
+ */
+ pci_read_config_byte(dev, 0x4b, &tmpbyte);
+ save_flags(flags);
+ cli();
+ /*
+ * clear bit 7
+ */
+ pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
+ restore_flags(flags);
+
+ /*
+ * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
+ */
+ pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
+ chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
+ }
+
+ return 0;
+}
+
+unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
+{
+ /*
+ * FIXME !!!!
+ * {0x4a,0x01,0x01}, {0x4a,0x02,0x02}
+ */
+ return 0;
+}
+
+void __init ide_init_ali15x3 (ide_hwif_t *hwif)
+{
+ byte ideic, inmir;
+ byte irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
+ 1, 11, 0, 12, 0, 14, 0, 15 };
+
+ hwif->irq = hwif->channel ? 15 : 14;
+
+ if (isa_dev) {
+ /*
+ * read IDE interface control
+ */
+ pci_read_config_byte(isa_dev, 0x58, &ideic);
+
+ /* bit0, bit1 */
+ ideic = ideic & 0x03;
+
+ /* get IRQ for IDE Controller */
+ if ((hwif->channel && ideic == 0x03) ||
+ (!hwif->channel && !ideic)) {
+ /*
+ * get SIRQ1 routing table
+ */
+ pci_read_config_byte(isa_dev, 0x44, &inmir);
+ inmir = inmir & 0x0f;
+ hwif->irq = irq_routing_table[inmir];
+ } else if (hwif->channel && !(ideic & 0x01)) {
+ /*
+ * get SIRQ2 routing table
+ */
+ pci_read_config_byte(isa_dev, 0x75, &inmir);
+ inmir = inmir & 0x0f;
+ hwif->irq = irq_routing_table[inmir];
+ }
+ }
+
+ hwif->tuneproc = &ali15x3_tune_drive;
+ if ((hwif->dma_base) && (m5229_revision >= 0xC1)) {
+ /*
+ * M1543C or newer for DMAing
+ */
+ hwif->dmaproc = &ali15x3_dmaproc;
+ hwif->autodma = 1;
+ } else {
+ hwif->autodma = 0;
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+ }
+
+#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
+ ali_proc = 1;
+ bmide_dev = hwif->pci_dev;
+ ali_display_info = &ali_get_info;
+#endif /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+ return;
+}
+
+void ide_dmacapable_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
+{
+ if ((dmabase) && (m5229_revision < 0x20)) {
+ return;
+ }
+ ide_setup_dma(hwif, dmabase, 8);
+}
diff --git a/drivers/block/cy82c693.c b/drivers/block/cy82c693.c
index e204bc0e6..77fdf0821 100644
--- a/drivers/block/cy82c693.c
+++ b/drivers/block/cy82c693.c
@@ -1,8 +1,8 @@
/*
- * linux/drivers/block/cy82c693.c Version 0.33 Jan. 23, 1999
+ * linux/drivers/block/cy82c693.c Version 0.34 Sept 3, 1999
*
- * Copyright (C) 1998, 1999 Andreas S. Krebs (akrebs@altavista.net), Maintainer
- * Copyright (C) 1998 Andre Hedrick, Integrater
+ * Copyright (C) 1998-99 Andreas S. Krebs (akrebs@altavista.net), Maintainer
+ * Copyright (C) 1998-99 Andre Hedrick, Integrater
*
* CYPRESS CY82C693 chipset IDE controller
*
@@ -31,6 +31,7 @@
*
*
* History:
+ * AMH@1999-08-24: v0.34 init_cy82c693_chip moved to pci_init_cy82c693
* ASK@1999-01-23: v0.33 made a few minor code clean ups
* removed DMA clock speed setting by default
* added boot message
@@ -53,7 +54,7 @@
#include "ide_modes.h"
/* the current version */
-#define CY82_VERSION "CY82C693U driver v0.33 99-01-23 Andreas S. Krebs (akrebs@altavista.net)"
+#define CY82_VERSION "CY82C693U driver v0.34 99-09-03 Andreas S. Krebs (akrebs@altavista.net)"
/*
* The following are used to debug the driver.
@@ -377,20 +378,10 @@ static void cy82c693_tune_drive (ide_drive_t *drive, byte pio)
unsigned int __init pci_init_cy82c693(struct pci_dev *dev, const char *name)
{
- return 0;
-}
-
-static void init_cy82c693_chip (struct pci_dev *dev)
-{
- static int initDone = 0;
#ifdef CY82C693_SETDMA_CLOCK
byte data;
#endif /* CY82C693_SETDMA_CLOCK */
- if (initDone != 0) /* only perform setup once */
- return;
- initDone = 1;
-
/* write info about this verion of the driver */
printk (KERN_INFO CY82_VERSION "\n");
@@ -401,7 +392,7 @@ static void init_cy82c693_chip (struct pci_dev *dev)
data = IN_BYTE(CY82_DATA_PORT);
#if CY82C693_DEBUG_INFO
- printk (KERN_INFO "CY82U693: Peripheral Configuration Register: 0x%X\n", data);
+ printk (KERN_INFO "%s: Peripheral Configuration Register: 0x%X\n", name, data);
#endif /* CY82C693_DEBUG_INFO */
/*
@@ -422,10 +413,11 @@ static void init_cy82c693_chip (struct pci_dev *dev)
OUT_BYTE(data, CY82_DATA_PORT);
#if CY82C693_DEBUG_INFO
- printk (KERN_INFO "CY82U693: New Peripheral Configuration Register: 0x%X\n", data);
+ printk (KERN_INFO "%s: New Peripheral Configuration Register: 0x%X\n", name, data);
#endif /* CY82C693_DEBUG_INFO */
-#endif /* CY82C693_SETDMA_CLOCK */
+#endif /* CY82C693_SETDMA_CLOCK */
+ return 0;
}
/*
@@ -437,7 +429,5 @@ void __init ide_init_cy82c693(ide_hwif_t *hwif)
if (hwif->dma_base)
hwif->dmaproc = &cy82c693_dmaproc;
hwif->tuneproc = &cy82c693_tune_drive;
-
- init_cy82c693_chip(hwif->pci_dev);
}
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index aece0447d..3c9a35b97 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -26,6 +26,8 @@ extern int net_dev_init(void);
extern void console_map_init(void);
extern int soc_probe(void);
extern int atmdev_init(void);
+extern int i2o_init(void);
+extern int cpqarray_init(void);
void __init device_init(void)
{
diff --git a/drivers/block/hpt34x.c b/drivers/block/hpt34x.c
index 284bf40bc..816b4b805 100644
--- a/drivers/block/hpt34x.c
+++ b/drivers/block/hpt34x.c
@@ -1,7 +1,9 @@
/*
- * linux/drivers/block/hpt34x.c Version 0.25 July 11, 1999
+ * linux/drivers/block/hpt34x.c Version 0.27 Sept 03, 1999
+ *
+ * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
- * Copyright (C) 1998-99 Andre Hedrick
*
* 00:12.0 Unknown mass storage controller:
* Triones Technologies, Inc.
@@ -14,9 +16,6 @@
* hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070)
* hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0)
*
- * drive_number
- * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
- * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
*/
#include <linux/config.h>
@@ -58,7 +57,7 @@ static void hpt34x_clear_chipset (ide_drive_t *drive)
pci_read_config_dword(HWIF(drive)->pci_dev, 0x44, &reg1);
pci_read_config_dword(HWIF(drive)->pci_dev, 0x48, &reg2);
tmp1 = ((0x00 << (3*drive_number)) | (reg1 & ~(7 << (3*drive_number))));
- tmp2 = ((0x00 << drive_number) | reg2);
+ tmp2 = (reg2 & ~(0x11 << drive_number));
pci_write_config_dword(HWIF(drive)->pci_dev, 0x44, tmp1);
pci_write_config_dword(HWIF(drive)->pci_dev, 0x48, tmp2);
}
@@ -105,7 +104,7 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, byte speed)
* after the drive is reported by the OS. Initally for designed for
* HPT343 UDMA chipset by HighPoint|Triones Technologies, Inc.
*/
-static int config_chipset_for_dma (ide_drive_t *drive)
+static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
{
struct hd_driveid *id = drive->id;
byte speed = 0x00;
@@ -117,76 +116,29 @@ static int config_chipset_for_dma (ide_drive_t *drive)
return ((int) ide_dma_off_quietly);
#endif /* HPT343_DISABLE_ALL_DMAING */
- if (id->dma_ultra & 0x0010) {
- goto backspeed;
- } else if (id->dma_ultra & 0x0008) {
- goto backspeed;
- } else if (id->dma_ultra & 0x0004) {
-backspeed:
- if (!((id->dma_ultra >> 8) & 4)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
+ hpt34x_clear_chipset(drive);
+
+ if ((id->dma_ultra & 0x0010) && ultra) {
speed = XFER_UDMA_2;
- } else if (id->dma_ultra & 0x0002) {
- if (!((id->dma_ultra >> 8) & 2)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
+ } else if ((id->dma_ultra & 0x0008) && ultra) {
+ speed = XFER_UDMA_2;
+ } else if ((id->dma_ultra & 0x0004) && ultra) {
+ speed = XFER_UDMA_2;
+ } else if ((id->dma_ultra & 0x0002) && ultra) {
speed = XFER_UDMA_1;
- } else if (id->dma_ultra & 0x0001) {
- if (!((id->dma_ultra >> 8) & 1)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
+ } else if ((id->dma_ultra & 0x0001) && ultra) {
speed = XFER_UDMA_0;
} else if (id->dma_mword & 0x0004) {
- if (!((id->dma_mword >> 8) & 4)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0404;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_2;
} else if (id->dma_mword & 0x0002) {
- if (!((id->dma_mword >> 8) & 2)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0202;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_1;
} else if (id->dma_mword & 0x0001) {
- if (!((id->dma_mword >> 8) & 1)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0101;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_0;
} else if (id->dma_1word & 0x0004) {
- if (!((id->dma_1word >> 8) & 4)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_2;
} else if (id->dma_1word & 0x0002) {
- if (!((id->dma_1word >> 8) & 2)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_1;
} else if (id->dma_1word & 0x0001) {
- if (!((id->dma_1word >> 8) & 1)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_0;
} else {
return ((int) ide_dma_off_quietly);
@@ -242,7 +194,6 @@ static void hpt34x_tune_drive (ide_drive_t *drive, byte pio)
{
byte speed;
- hpt34x_clear_chipset(drive);
switch(pio) {
case 4: speed = XFER_PIO_4;break;
case 3: speed = XFER_PIO_3;break;
@@ -250,6 +201,7 @@ static void hpt34x_tune_drive (ide_drive_t *drive, byte pio)
case 1: speed = XFER_PIO_1;break;
default: speed = XFER_PIO_0;break;
}
+ hpt34x_clear_chipset(drive);
(void) hpt34x_tune_chipset(drive, speed);
}
@@ -268,7 +220,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (id->field_valid & 4) {
if (id->dma_ultra & 0x0007) {
/* Force if Capable UltraDMA */
- dma_func = config_chipset_for_dma(drive);
+ dma_func = config_chipset_for_dma(drive, 1);
if ((id->field_valid & 2) &&
(dma_func != ide_dma_on))
goto try_dma_modes;
@@ -278,7 +230,7 @@ try_dma_modes:
if ((id->dma_mword & 0x0007) ||
(id->dma_1word & 0x0007)) {
/* Force if Capable regular DMA modes */
- dma_func = config_chipset_for_dma(drive);
+ dma_func = config_chipset_for_dma(drive, 0);
if (dma_func != ide_dma_on)
goto no_dma_set;
}
@@ -287,7 +239,7 @@ try_dma_modes:
goto no_dma_set;
}
/* Consult the list of known "good" drives */
- dma_func = config_chipset_for_dma(drive);
+ dma_func = config_chipset_for_dma(drive, 0);
if (dma_func != ide_dma_on)
goto no_dma_set;
} else {
@@ -300,6 +252,12 @@ no_dma_set:
config_chipset_for_pio(drive);
}
+
+#if 0
+ if (dma_func == ide_dma_on)
+ dma_func = ide_dma_off;
+#endif
+
return HWIF(drive)->dmaproc(dma_func, drive);
}
@@ -313,22 +271,44 @@ no_dma_set:
int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
+ ide_hwif_t *hwif = HWIF(drive);
+ unsigned long dma_base = hwif->dma_base;
+ byte unit = (drive->select.b.unit & 0x01);
+ unsigned int count, reading = 0;
+ byte dma_stat;
+
switch (func) {
- case ide_dma_check:
- hpt34x_clear_chipset(drive);
- return config_drive_xfer_rate(drive);
-#if 0
case ide_dma_off:
case ide_dma_off_quietly:
+ outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+ break;
case ide_dma_on:
+ outb(inb(dma_base+2)|(1<<(5+unit)), dma_base+2);
+ break;
case ide_dma_check:
return config_drive_xfer_rate(drive);
case ide_dma_read:
+ reading = 1 << 3;
case ide_dma_write:
- case ide_dma_begin:
- case ide_dma_end:
- case ide_dma_test_irq:
-#endif
+ if (!(count = ide_build_dmatable(drive, func)))
+ return 1; /* try PIO instead of DMA */
+ outl(virt_to_bus(hwif->dmatable), dma_base + 4); /* PRD table */
+ reading |= 0x01;
+ outb(reading, dma_base); /* specify r/w */
+ outb(inb(dma_base+2)|6, dma_base+2); /* clear INTR & ERROR flags */
+ drive->waiting_for_dma = 1;
+ if (drive->media != ide_disk)
+ return 0;
+ drive->timeout = WAIT_CMD;
+ ide_set_handler(drive, &ide_dma_intr); /* issue cmd to drive */
+ OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+ return 0;
+ case ide_dma_end: /* returns 1 on error, 0 otherwise */
+ drive->waiting_for_dma = 0;
+ outb(inb(dma_base)&~1, dma_base); /* stop DMA */
+ dma_stat = inb(dma_base+2); /* get DMA status */
+ outb(dma_stat|6, dma_base+2); /* clear the INTR & ERROR bits */
+ return (dma_stat & 7) != 4; /* verify good DMA status */
default:
break;
}
@@ -342,10 +322,17 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name)
{
+ int i = 0;
+ unsigned long hpt34xIoBase = dev->resource[4].start;
unsigned short cmd;
+ unsigned long flags;
+
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
+
if (cmd & PCI_COMMAND_MEMORY) {
if (dev->resource[PCI_ROM_RESOURCE].start) {
pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
@@ -353,27 +340,28 @@ unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name)
}
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
} else {
- int i = 0;
- unsigned long hpt34xIoBase = dev->resource[4].start;
-
- pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO);
- dev->resource[0].start = (hpt34xIoBase + 0x20);
- dev->resource[1].start = (hpt34xIoBase + 0x34);
- dev->resource[2].start = (hpt34xIoBase + 0x28);
- dev->resource[3].start = (hpt34xIoBase + 0x3c);
- for(i=0; i<4; i++)
- dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
- /*
- * Since 20-23 can be assigned and are R/W, we correct them.
- */
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, dev->resource[0].start);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start);
-
- pci_write_config_word(dev, PCI_COMMAND, cmd);
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
}
+
+ pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO);
+ dev->resource[0].start = (hpt34xIoBase + 0x20);
+ dev->resource[1].start = (hpt34xIoBase + 0x34);
+ dev->resource[2].start = (hpt34xIoBase + 0x28);
+ dev->resource[3].start = (hpt34xIoBase + 0x3c);
+ for(i=0; i<4; i++)
+ dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
+ /*
+ * Since 20-23 can be assigned and are R/W, we correct them.
+ */
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, dev->resource[0].start);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, dev->resource[1].start);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, dev->resource[2].start);
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, dev->resource[3].start);
+
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+
+ __restore_flags(flags); /* local CPU only */
+
return dev->irq;
}
diff --git a/drivers/block/hpt366.c b/drivers/block/hpt366.c
index b61f71687..d45b5f719 100644
--- a/drivers/block/hpt366.c
+++ b/drivers/block/hpt366.c
@@ -1,11 +1,13 @@
/*
- * linux/drivers/block/hpt366.c Version 0.12 August 16, 1999
+ * linux/drivers/block/hpt366.c Version 0.13 Sept. 3, 1999
*
* Copyright (C) 1999 Andre Hedrick <andre@suse.com>
+ * May be copied or modified under the terms of the GNU General Public License
*
- * drive_number
- * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
- * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
+ * Thanks to HighPoint Technologies for their assistance, and hardware.
+ * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
+ * donation of an ABit BP6 mainboard, processor, and memory acellerated
+ * development and support.
*/
#include <linux/types.h>
@@ -114,17 +116,18 @@ struct chipset_bus_clock_list_entry twenty_five_base [] = {
};
#define HPT366_DEBUG_DRIVE_INFO 0
-#define HPT366_ALLOW_ATA66_4 0
+#define HPT366_ALLOW_ATA66_4 1
#define HPT366_ALLOW_ATA66_3 1
-#define HPT366_ALLOW_ATA33_2 1
-#define HPT366_ALLOW_ATA33_1 1
-#define HPT366_ALLOW_ATA33_0 1
extern char *ide_xfer_verbose (byte xfer_rate);
+byte hpt363_shared_irq = 0;
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("check_in_drive_lists(%s, %p)\n", drive->name, list);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
while (*list) {
if (!strcmp(*list++,id->model)) {
@@ -139,50 +142,62 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
{
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("pci_bus_clock_list(speed=0x%02x, table=%p)\n", speed, chipset_table);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
for ( ; chipset_table->xfer_speed ; chipset_table++)
- if (chipset_table->xfer_speed == speed)
+ if (chipset_table->xfer_speed == speed) {
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("pci_bus_clock_list: found match: 0x%08x\n", chipset_table->chipset_settings);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
return chipset_table->chipset_settings;
+ }
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("pci_bus_clock_list: using default: 0x%08x\n", 0x01208585);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
return 0x01208585;
}
static int hpt366_tune_chipset (ide_drive_t *drive, byte speed)
{
int err;
- byte busclock;
-
#if HPT366_DEBUG_DRIVE_INFO
int drive_number = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
#endif /* HPT366_DEBUG_DRIVE_INFO */
- byte regtime = (drive->select.b.unit & 0x01) ? 0x43 : 0x40;
+ byte regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
unsigned int reg1 = 0;
unsigned int reg2 = 0;
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("hpt366_tune_chipset(%s, speed=0x%02x)\n", drive->name, speed);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
+
pci_read_config_dword(HWIF(drive)->pci_dev, regtime, &reg1);
- pci_read_config_byte(HWIF(drive)->pci_dev, regtime|0x01, &busclock);
- switch(busclock) {
- case 0xd9:
+ /* detect bus speed by looking at control reg timing: */
+ switch((reg1 >> 8) & 7) {
+ case 5:
reg2 = pci_bus_clock_list(speed, forty_base);
break;
- case 0x85:
+ case 9:
reg2 = pci_bus_clock_list(speed, twenty_five_base);
break;
- case 0xa7:
default:
+ printk("hpt366: assuming 33Mhz PCI bus\n");
+ case 7:
reg2 = pci_bus_clock_list(speed, thirty_three_base);
break;
}
-
- if (drive->id->dword_io & 1)
- reg2 |= 0x80000000;
- else
- reg2 &= ~0x80000000;
+ /*
+ * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later)
+ */
+ reg2 &= ~0x80000000;
pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2);
err = ide_config_drive_speed(drive, speed);
#if HPT366_DEBUG_DRIVE_INFO
- printk("%s: %s drive%d (0x%08x 0x%08x) 0x%04x\n",
- drive->name, ide_xfer_verbose(speed),
+ printk("%s: speed=0x%02x(%s), drive%d, old=0x%08x, new=0x%08x, err=0x%04x\n",
+ drive->name, speed, ide_xfer_verbose(speed),
drive_number, reg1, reg2, err);
#endif /* HPT366_DEBUG_DRIVE_INFO */
return(err);
@@ -203,127 +218,89 @@ static int config_chipset_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
byte speed = 0x00;
+ unsigned int reg40 = 0;
+ int rval;
if ((id->dma_ultra & 0x0010) &&
(!check_in_drive_lists(drive, bad_ata66_4)) &&
(HPT366_ALLOW_ATA66_4) &&
(HWIF(drive)->udma_four)) {
- if (!((id->dma_ultra >> 8) & 16)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x1010;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_UDMA_4;
} else if ((id->dma_ultra & 0x0008) &&
(!check_in_drive_lists(drive, bad_ata66_3)) &&
(HPT366_ALLOW_ATA66_3) &&
(HWIF(drive)->udma_four)) {
- if (!((id->dma_ultra >> 8) & 8)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0808;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_UDMA_3;
- } else if ((id->dma_ultra & 0x0004) &&
- (HPT366_ALLOW_ATA33_2) &&
- (!check_in_drive_lists(drive, bad_ata33))) {
- if (!((id->dma_ultra >> 8) & 4)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
- speed = XFER_UDMA_2;
- } else if ((id->dma_ultra & 0x0002) &&
- (HPT366_ALLOW_ATA33_1) &&
- (!check_in_drive_lists(drive, bad_ata33))) {
- if (!((id->dma_ultra >> 8) & 2)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
+ } else if (id->dma_ultra && (!check_in_drive_lists(drive, bad_ata33))) {
+ if (id->dma_ultra & 0x0004) {
+ speed = XFER_UDMA_2;
+ } else if (id->dma_ultra & 0x0002) {
+ speed = XFER_UDMA_1;
+ } else if (id->dma_ultra & 0x0001) {
+ speed = XFER_UDMA_0;
}
- speed = XFER_UDMA_1;
- } else if ((id->dma_ultra & 0x0001) &&
- (HPT366_ALLOW_ATA33_0) &&
- (!check_in_drive_lists(drive, bad_ata33))) {
- if (!((id->dma_ultra >> 8) & 1)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
- speed = XFER_UDMA_0;
} else if (id->dma_mword & 0x0004) {
- drive->id->dma_ultra &= ~0xFF00;
- if (!((id->dma_mword >> 8) & 4)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0404;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_2;
} else if (id->dma_mword & 0x0002) {
- drive->id->dma_ultra &= ~0xFF00;
- if (!((id->dma_mword >> 8) & 2)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0202;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_1;
} else if (id->dma_mword & 0x0001) {
- drive->id->dma_ultra &= ~0xFF00;
- if (!((id->dma_mword >> 8) & 1)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0101;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_0;
} else if (id->dma_1word & 0x0004) {
- drive->id->dma_ultra &= ~0xFF00;
- if (!((id->dma_1word >> 8) & 4)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_2;
} else if (id->dma_1word & 0x0002) {
- drive->id->dma_ultra &= ~0xFF00;
- if (!((id->dma_1word >> 8) & 2)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_1;
} else if (id->dma_1word & 0x0001) {
- drive->id->dma_ultra &= ~0xFF00;
- if (!((id->dma_1word >> 8) & 1)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_0;
} else {
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("%s: config_chipset_for_dma: returning 'ide_dma_off_quietly'\n", drive->name);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
return ((int) ide_dma_off_quietly);
}
+ /* Disable the "fast interrupt" prediction.
+ * Instead, always wait for the real interrupt from the drive!
+ */
+ {
+ byte reg51h = 0;
+ pci_read_config_byte(HWIF(drive)->pci_dev, 0x51, &reg51h);
+ if (reg51h & 0x80)
+ pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h & ~0x80);
+ }
+
+ /*
+ * Preserve existing PIO settings:
+ */
+ pci_read_config_dword(HWIF(drive)->pci_dev, 0x40, &reg40);
+ speed = (speed & ~0xc0000000) | (reg40 & 0xc0000000);
+
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("%s: config_chipset_for_dma: speed=0x%04x\n", drive->name, speed);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
(void) hpt366_tune_chipset(drive, speed);
- return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_1word >> 8) & 7) ? ide_dma_on :
ide_dma_off_quietly);
+
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("%s: config_chipset_for_dma: returning %d (%s)\n", drive->name, rval, rval == ide_dma_on ? "dma_on" : "dma_off");
+#endif /* HPT366_DEBUG_DRIVE_INFO */
+ return rval;
}
static void config_chipset_for_pio (ide_drive_t *drive)
{
unsigned short eide_pio_timing[6] = {960, 480, 240, 180, 120, 90};
unsigned short xfer_pio = drive->id->eide_pio_modes;
-
byte timing, speed, pio;
+ unsigned int reg40 = 0;
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("%s: config_chipset_for_pio\n", drive->name);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
pio = ide_get_best_pio_mode(drive, 255, 5, NULL);
if (xfer_pio> 4)
@@ -353,6 +330,14 @@ static void config_chipset_for_pio (ide_drive_t *drive)
speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW;
break;
}
+ /*
+ * Preserve existing DMA settings:
+ */
+ pci_read_config_dword(HWIF(drive)->pci_dev, 0x40, &reg40);
+ speed = (speed & ~0x30070000) | (reg40 & 0x30070000);
+#if HPT366_DEBUG_DRIVE_INFO
+ printk("%s: config_chipset_for_pio: speed=0x%04x\n", drive->name, speed);
+#endif /* HPT366_DEBUG_DRIVE_INFO */
(void) hpt366_tune_chipset(drive, speed);
}
@@ -428,8 +413,9 @@ no_dma_set:
int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
+#if 0
byte reg50h = 0, reg52h = 0;
-
+#endif
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
@@ -463,28 +449,81 @@ int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name)
{
- byte ata66 = 0;
+ byte test = 0;
- pci_read_config_byte(dev, 0x5a, &ata66);
if (dev->resource[PCI_ROM_RESOURCE].start)
pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk("%s: reg5ah=0x%02x ATA-%s Cable Port%d\n", name, ata66, (ata66 & 0x02) ? "33" : "66", PCI_FUNC(dev->devfn));
+
+ pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &test);
+ if (test != 0x08)
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x08);
+
+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &test);
+ if (test != 0x78)
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
+
+ pci_read_config_byte(dev, PCI_MIN_GNT, &test);
+ if (test != 0x08)
+ pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
+
+ pci_read_config_byte(dev, PCI_MAX_LAT, &test);
+ if (test != 0x08)
+ pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
+
return dev->irq;
}
+unsigned int __init ata66_hpt366 (ide_hwif_t *hwif)
+{
+ byte ata66 = 0;
+
+ pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);
+#ifdef DEBUG
+ printk("HPT366: reg5ah=0x%02x ATA-%s Cable Port%d\n",
+ ata66, (ata66 & 0x02) ? "33" : "66",
+ PCI_FUNC(hwif->pci_dev->devfn));
+#endif /* DEBUG */
+ return ((ata66 & 0x02) ? 0 : 1);
+}
+
void __init ide_init_hpt366 (ide_hwif_t *hwif)
{
+#if 0
+ if ((PCI_FUNC(hwif->pci_dev->devfn) & 1) && (hpt363_shared_irq)) {
+ hwif->mate = &ide_hwifs[hwif->index-1];
+ hwif->mate->mate = hwif;
+ hwif->serialized = hwif->mate->serialized = 1;
+ }
+#endif
+
hwif->tuneproc = &hpt366_tune_drive;
if (hwif->dma_base) {
- byte ata66 = 0;
-
hwif->dmaproc = &hpt366_dmaproc;
- pci_read_config_byte(hwif->pci_dev, 0x5a, &ata66);
- hwif->udma_four = (ata66 & 0x02) ? 0 : 1;
} else {
- hwif->udma_four = 0;
hwif->autodma = 0;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
}
}
+
+void ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
+{
+ byte masterdma = 0, slavedma = 0;
+ byte dma_new = 0, dma_old = inb(dmabase+2);
+ unsigned long flags;
+
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
+
+ dma_new = dma_old;
+ pci_read_config_byte(hwif->pci_dev, 0x43, &masterdma);
+ pci_read_config_byte(hwif->pci_dev, 0x47, &slavedma);
+
+ if (masterdma & 0x30) dma_new |= 0x20;
+ if (slavedma & 0x30) dma_new |= 0x40;
+ if (dma_new != dma_old) outb(dma_new, dmabase+2);
+
+ __restore_flags(flags); /* local CPU only */
+
+ ide_setup_dma(hwif, dmabase, 8);
+}
diff --git a/drivers/block/icside.c b/drivers/block/icside.c
index 629ad927d..5d007fce3 100644
--- a/drivers/block/icside.c
+++ b/drivers/block/icside.c
@@ -288,7 +288,6 @@ icside_build_dmatable(ide_drive_t *drive, int reading)
static int
icside_config_drive(ide_drive_t *drive, int mode)
{
- ide_hwif_t *hwif = HWIF(drive);
int speed, err;
if (mode == 2) {
@@ -382,7 +381,8 @@ icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
if (drive->media != ide_disk)
return 0;
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
+ drive->timeout = WAIT_CMD;
+ ide_set_handler(drive, &ide_dma_intr);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
IDE_COMMAND_REG);
diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c
index b3ba03562..19fe18fe0 100644
--- a/drivers/block/ide-cd.c
+++ b/drivers/block/ide-cd.c
@@ -339,14 +339,15 @@ void cdrom_analyze_sense_data (ide_drive_t *drive,
failed_command->c[0] == GPCMD_READ_SUBCHANNEL)
return;
}
+
if (reqbuf->error_code == 0x70 && reqbuf->sense_key == 0x02
&& ((reqbuf->asc == 0x3a && reqbuf->ascq == 0x00) ||
(reqbuf->asc == 0x04 && reqbuf->ascq == 0x01)))
{
/*
* Suppress the following errors:
- * "Medium not present", and "in progress of becoming ready",
- * to keep the noise level down to a dull roar.
+ * "Medium not present", "in progress of becoming ready",
+ * and "writing" to keep the noise level down to a dull roar.
*/
return;
}
@@ -431,6 +432,19 @@ void cdrom_analyze_sense_data (ide_drive_t *drive,
printk ("\"\n");
}
+ /* The SKSV bit specifies validity of the sense_key_specific
+ * in the next two commands. It is bit 7 of the first byte.
+ * In the case of NOT_READY, if SKSV is set the drive can
+ * give us nice ETA readings.
+ */
+ if (reqbuf->sense_key == NOT_READY &&
+ (reqbuf->sense_key_specific[0] & 0x80)) {
+ int progress = (reqbuf->sense_key_specific[1] << 8 |
+ reqbuf->sense_key_specific[2]) * 100;
+ printk(" Command is %02d%% complete\n", progress / 0xffff);
+
+ }
+
if (reqbuf->sense_key == ILLEGAL_REQUEST &&
(reqbuf->sense_key_specific[0] & 0x80) != 0) {
printk (" Error in %s byte %d",
@@ -466,21 +480,6 @@ void cdrom_analyze_sense_data (ide_drive_t *drive,
#endif /* not VERBOSE_IDE_CD_ERRORS */
}
-
-/* Fix up a possibly partially-processed request so that we can
- start it over entirely, or even put it back on the request queue. */
-static void restore_request (struct request *rq)
-{
- if (rq->buffer != rq->bh->b_data) {
- int n = (rq->buffer - rq->bh->b_data) / SECTOR_SIZE;
- rq->buffer = rq->bh->b_data;
- rq->nr_sectors += n;
- rq->sector -= n;
- }
- rq->current_nr_sectors = rq->bh->b_size >> SECTOR_BITS;
-}
-
-
static void cdrom_queue_request_sense (ide_drive_t *drive,
struct semaphore *sem,
struct atapi_request_sense *reqbuf,
@@ -533,10 +532,8 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive)
struct packet_command *pc = (struct packet_command *)
rq->buffer;
cdrom_analyze_sense_data (drive,
- (struct atapi_request_sense *)
- (pc->buffer - pc->c[4]),
- (struct packet_command *)
- pc->sense_data);
+ (struct atapi_request_sense *) (pc->buffer - pc->c[4]),
+ (struct packet_command *) pc->sense_data);
}
if (rq->cmd == READ && !rq->current_nr_sectors)
uptodate = 1;
@@ -680,7 +677,7 @@ static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
struct cdrom_info *info = drive->driver_data;
/* Wait for the controller to be idle. */
- if (ide_wait_stat (drive, 0, BUSY_STAT, WAIT_READY)) return 1;
+ if (ide_wait_stat(drive, 0, BUSY_STAT, WAIT_READY)) return 1;
if (info->dma)
info->dma = !HWIF(drive)->dmaproc(ide_dma_read, drive);
@@ -699,7 +696,7 @@ static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
- ide_set_handler (drive, handler, WAIT_CMD);
+ ide_set_handler (drive, handler);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
@@ -716,9 +713,14 @@ static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
HANDLER is the interrupt handler to call when the command completes
or there's data ready. */
static int cdrom_transfer_packet_command (ide_drive_t *drive,
- char *cmd_buf, int cmd_len,
+ unsigned char *cmd_buf, int cmd_len,
ide_handler_t *handler)
{
+ /* don't timeout for blank and format commands. they may take
+ * a _very_ long time. */
+ if (cmd_buf[0] == GPCMD_BLANK || cmd_buf[0] == GPCMD_FORMAT_UNIT)
+ drive->timeout = 0;
+
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
/* Here we should have been called after receiving an interrupt
from the device. DRQ should how be set. */
@@ -734,7 +736,7 @@ static int cdrom_transfer_packet_command (ide_drive_t *drive,
}
/* Arm the interrupt handler. */
- ide_set_handler (drive, handler, WAIT_CMD);
+ ide_set_handler (drive, handler);
/* Send the command to the device. */
atapi_output_bytes (drive, cmd_buf, cmd_len);
@@ -770,13 +772,12 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
/* If we don't yet have a sector buffer, try to allocate one.
If we can't get one atomically, it's not fatal -- we'll just throw
the data away rather than caching it. */
- if (info->sector_buffer == NULL) {
- info->sector_buffer = (char *) kmalloc (SECTOR_BUFFER_SIZE,
- GFP_ATOMIC);
+ if (info->buffer == NULL) {
+ info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_ATOMIC);
/* If we couldn't get a buffer,
don't try to buffer anything... */
- if (info->sector_buffer == NULL)
+ if (info->buffer == NULL)
sectors_to_buffer = 0;
}
@@ -785,7 +786,7 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
info->sector_buffered = sector;
/* Read the data into the buffer. */
- dest = info->sector_buffer + info->nsectors_buffered * SECTOR_SIZE;
+ dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
while (sectors_to_buffer > 0) {
atapi_input_bytes (drive, dest, SECTOR_SIZE);
--sectors_to_buffer;
@@ -802,7 +803,6 @@ static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
}
}
-
/*
* Check the contents of the interrupt reason register from the cdrom
* and attempt to recover if there are problems. Returns 0 if everything's
@@ -827,6 +827,12 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
atapi_output_bytes (drive, &dum, sizeof (dum));
len -= sizeof (dum);
}
+ } else if (ireason == 1) {
+ /* Some drives (ASUS) seem to tell us that status
+ * info is available. just get it and ignore.
+ */
+ GET_STAT();
+ return 0;
} else {
/* Drive wants a command packet, or invalid ireason... */
printk ("%s: cdrom_read_intr: bad interrupt reason %d\n",
@@ -837,7 +843,6 @@ int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
return -1;
}
-
/*
* Interrupt routine. Called when a read request has completed.
*/
@@ -912,8 +917,7 @@ static void cdrom_read_intr (ide_drive_t *drive)
/* First, figure out if we need to bit-bucket
any of the leading sectors. */
- nskip = MIN ((int)(rq->current_nr_sectors -
- (rq->bh->b_size >> SECTOR_BITS)),
+ nskip = MIN ((int)(rq->current_nr_sectors - (rq->bh->b_size >> SECTOR_BITS)),
sectors_to_transfer);
while (nskip > 0) {
@@ -939,8 +943,7 @@ static void cdrom_read_intr (ide_drive_t *drive)
/* If the buffers are full, cache the rest of the data in our
internal buffer. */
if (rq->current_nr_sectors == 0) {
- cdrom_buffer_sectors (drive,
- rq->sector, sectors_to_transfer);
+ cdrom_buffer_sectors(drive, rq->sector, sectors_to_transfer);
sectors_to_transfer = 0;
} else {
/* Transfer data to the buffers.
@@ -952,8 +955,7 @@ static void cdrom_read_intr (ide_drive_t *drive)
/* Read this_transfer sectors
into the current buffer. */
while (this_transfer > 0) {
- atapi_input_bytes (drive,
- rq->buffer, SECTOR_SIZE);
+ atapi_input_bytes(drive, rq->buffer, SECTOR_SIZE);
rq->buffer += SECTOR_SIZE;
--rq->nr_sectors;
--rq->current_nr_sectors;
@@ -966,10 +968,9 @@ static void cdrom_read_intr (ide_drive_t *drive)
/* Done moving data!
Wait for another interrupt. */
- ide_set_handler (drive, &cdrom_read_intr, WAIT_CMD);
+ ide_set_handler(drive, &cdrom_read_intr);
}
-
/*
* Try to satisfy some of the current read request from our cached data.
* Returns nonzero if the request has been completed, zero otherwise.
@@ -980,7 +981,7 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq;
/* Can't do anything if there's no buffer. */
- if (info->sector_buffer == NULL) return 0;
+ if (info->buffer == NULL) return 0;
/* Loop while this request needs data and the next block is present
in our cache. */
@@ -991,7 +992,7 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
cdrom_end_request (1, drive);
memcpy (rq->buffer,
- info->sector_buffer +
+ info->buffer +
(rq->sector - info->sector_buffered) * SECTOR_SIZE,
SECTOR_SIZE);
rq->buffer += SECTOR_SIZE;
@@ -1026,8 +1027,6 @@ static int cdrom_read_from_buffer (ide_drive_t *drive)
return 0;
}
-
-
/*
* Routine to send a read packet command to the drive.
* This is usually called directly from cdrom_start_read.
@@ -1056,14 +1055,13 @@ static void cdrom_start_read_continuation (ide_drive_t *drive)
nskip = (sector % SECTORS_PER_FRAME);
if (nskip > 0) {
/* Sanity check... */
- if (rq->current_nr_sectors !=
- (rq->bh->b_size >> SECTOR_BITS)) {
- printk ("%s: cdrom_start_read_continuation: buffer botch (%ld)\n",
+ if (rq->current_nr_sectors != (rq->bh->b_size >> SECTOR_BITS) &&
+ (rq->sector % CD_FRAMESIZE != 0)) {
+ printk ("%s: cdrom_start_read_continuation: buffer botch (%lu)\n",
drive->name, rq->current_nr_sectors);
cdrom_end_request (0, drive);
return;
}
-
sector -= nskip;
nsect += nskip;
rq->current_nr_sectors += nskip;
@@ -1091,9 +1089,10 @@ static void cdrom_start_read_continuation (ide_drive_t *drive)
&cdrom_read_intr);
}
+
#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */
-#define IDECD_SEEK_TIMER (2 * WAIT_MIN_SLEEP) /* 40 ms */
-#define IDECD_SEEK_TIMEOUT WAIT_CMD /* 10 sec */
+#define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */
+#define IDECD_SEEK_TIMEOUT WAIT_CMD /* 10 sec */
static void cdrom_seek_intr (ide_drive_t *drive)
{
@@ -1107,7 +1106,7 @@ static void cdrom_seek_intr (ide_drive_t *drive)
if (retry && jiffies - info->start_seek > IDECD_SEEK_TIMER) {
if (--retry == 0) {
- printk ("%s: disabled DSC seek overlap\n", drive->name);
+ printk("%s: disabled DSC seek overlap\n", drive->name);
drive->dsc_overlap = 0;
}
}
@@ -1127,7 +1126,7 @@ static void cdrom_start_seek_continuation (ide_drive_t *drive)
memset (&pc.c, 0, sizeof (pc.c));
pc.c[0] = GPCMD_SEEK;
- put_unaligned(htonl (frame), (unsigned int *) &pc.c[2]);
+ put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]);
(void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c), &cdrom_seek_intr);
}
@@ -1140,6 +1139,19 @@ static void cdrom_start_seek (ide_drive_t *drive, unsigned int block)
cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation);
}
+/* Fix up a possibly partially-processed request so that we can
+ start it over entirely, or even put it back on the request queue. */
+static void restore_request (struct request *rq)
+{
+ if (rq->buffer != rq->bh->b_data) {
+ int n = (rq->buffer - rq->bh->b_data) / SECTOR_SIZE;
+ rq->buffer = rq->bh->b_data;
+ rq->nr_sectors += n;
+ rq->sector -= n;
+ }
+ rq->current_nr_sectors = rq->bh->b_size >> SECTOR_BITS;
+}
+
/*
* Start a read request from the CD-ROM.
*/
@@ -1162,25 +1174,22 @@ static void cdrom_start_read (ide_drive_t *drive, unsigned int block)
restore_request (rq);
/* Satisfy whatever we can of this request from our cached sector. */
- if (cdrom_read_from_buffer (drive))
+ if (cdrom_read_from_buffer(drive))
return;
- /* Clear the local sector buffer. */
info->nsectors_buffered = 0;
- if (drive->using_dma && (rq->sector % SECTORS_PER_FRAME == 0) && (rq->nr_sectors % SECTORS_PER_FRAME == 0))
+ /* use dma, if possible. */
+ if (drive->using_dma && (rq->sector % SECTORS_PER_FRAME == 0) &&
+ (rq->nr_sectors % SECTORS_PER_FRAME == 0))
info->dma = 1;
else
info->dma = 0;
/* Start sending the read request to the drive. */
- cdrom_start_packet_command (drive, 32768,
- cdrom_start_read_continuation);
+ cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
}
-
-
-
/****************************************************************************
* Execute all other packet commands.
*/
@@ -1197,6 +1206,9 @@ static void cdrom_pc_intr (ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq;
struct packet_command *pc = (struct packet_command *)rq->buffer;
+ /* restore timeout after blank or format command */
+ drive->timeout = WAIT_CMD;
+
/* Check for errors. */
if (cdrom_decode_status (drive, 0, &stat))
return;
@@ -1282,7 +1294,7 @@ static void cdrom_pc_intr (ide_drive_t *drive)
}
/* Now we wait for another interrupt. */
- ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD);
+ ide_set_handler (drive, &cdrom_pc_intr);
}
@@ -1334,6 +1346,7 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
if (pc->sense_data == NULL)
pc->sense_data = &my_reqbuf;
pc->sense_data->sense_key = 0;
+
/* Start of retry loop. */
do {
ide_init_drive_cmd (&req);
@@ -1353,7 +1366,7 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
if (reqbuf->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change (drive);
else if (reqbuf->sense_key == NOT_READY &&
- reqbuf->asc == 4) {
+ reqbuf->asc == 4 && reqbuf->ascq != 4) {
/* The drive is in the process of loading
a disk. Retry, but wait a little to give
the drive time to complete the load. */
@@ -1368,7 +1381,6 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
/* End of retry loop. */
} while (pc->stat != 0 && retries >= 0);
-
/* Return an error if the command failed. */
if (pc->stat != 0)
return -EIO;
@@ -1397,25 +1409,17 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
static
void ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long block)
{
- if (rq -> cmd == PACKET_COMMAND || rq -> cmd == REQUEST_SENSE_COMMAND)
- cdrom_do_packet_command (drive);
- else if (rq -> cmd == RESET_DRIVE_COMMAND) {
- cdrom_end_request (1, drive);
- ide_do_reset (drive);
- return;
- } else if (rq -> cmd != READ) {
- printk ("ide-cd: bad cmd %d\n", rq -> cmd);
- cdrom_end_request (0, drive);
- } else {
- struct cdrom_info *info = drive->driver_data;
+ struct cdrom_info *info = drive->driver_data;
+ switch (rq->cmd) {
+ case READ: {
if (CDROM_CONFIG_FLAGS(drive)->seeking) {
unsigned long elpased = jiffies - info->start_seek;
int stat = GET_STAT();
if ((stat & SEEK_STAT) != SEEK_STAT) {
if (elpased < IDECD_SEEK_TIMEOUT) {
- ide_stall_queue (drive, IDECD_SEEK_TIMER);
+ ide_stall_queue(drive, IDECD_SEEK_TIMER);
return;
}
printk ("%s: DSC timeout\n", drive->name);
@@ -1427,6 +1431,26 @@ void ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long bloc
else
cdrom_start_read (drive, block);
info->last_block = block;
+ break;
+ }
+
+ case PACKET_COMMAND:
+ case REQUEST_SENSE_COMMAND: {
+ cdrom_do_packet_command(drive);
+ break;
+ }
+
+ case RESET_DRIVE_COMMAND: {
+ cdrom_end_request(1, drive);
+ ide_do_reset(drive);
+ break;
+ }
+
+ default: {
+ printk("ide-cd: bad cmd %d\n", rq -> cmd);
+ cdrom_end_request(0, drive);
+ break;
+ }
}
}
@@ -1600,7 +1624,7 @@ cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity,
stat = cdrom_queue_packet_command (drive, &pc);
if (stat == 0)
- *capacity = ntohl (capbuf.lba);
+ *capacity = be32_to_cpu(capbuf.lba);
return stat;
}
@@ -1879,64 +1903,7 @@ int cdrom_get_toc_entry (ide_drive_t *drive, int track,
-/* This gets the mechanism status per ATAPI draft spec 2.6 */
-static int
-cdrom_read_mech_status (ide_drive_t *drive, char *buf, int buflen,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.buffer = buf;
- pc.buflen = buflen;
- pc.c[0] = GPCMD_MECHANISM_STATUS;
- pc.c[8] = (buflen >> 8);
- pc.c[9] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-/* Read the drive mechanism status and slot table into our internal buffer.
- If the buffer does not yet exist, allocate it. */
-static int
-cdrom_read_changer_info (ide_drive_t *drive)
-{
- int nslots;
- struct cdrom_info *info = drive->driver_data;
-
- if (info->changer_info)
- nslots = info->changer_info->hdr.nslots;
-
- else {
- struct atapi_mechstat_header mechbuf;
- int stat;
-
- stat = cdrom_read_mech_status (drive,
- (char *)&mechbuf,
- sizeof (mechbuf),
- NULL);
- if (stat)
- return stat;
-
- nslots = mechbuf.nslots;
- info->changer_info =
- (struct atapi_changer_info *)
- kmalloc (sizeof (struct atapi_changer_info) +
- nslots * sizeof (struct atapi_slot),
- GFP_KERNEL);
-
- if (info->changer_info == NULL)
- return -ENOMEM;
- }
- return cdrom_read_mech_status
- (drive,
- (char *)&info->changer_info->hdr,
- sizeof (struct atapi_mechstat_header) +
- nslots * sizeof (struct atapi_slot),
- NULL);
-}
/* the generic packet interface to cdrom.c */
static int ide_cdrom_packet(struct cdrom_device_info *cdi,
@@ -1952,8 +1919,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
memcpy(pc.c, cgc->cmd, CDROM_PACKET_SIZE);
pc.buffer = cgc->buffer;
pc.buflen = cgc->buflen;
- cgc->stat = cdrom_queue_packet_command(drive, &pc);
- return cgc->stat;
+ return cgc->stat = cdrom_queue_packet_command(drive, &pc);
}
static
@@ -2130,16 +2096,19 @@ static
int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
- struct cdrom_info *info = drive->driver_data;
if (slot_nr == CDSL_CURRENT) {
- struct atapi_request_sense my_reqbuf;
- int stat = cdrom_check_status (drive, &my_reqbuf);
- if (stat == 0 || my_reqbuf.sense_key == UNIT_ATTENTION)
+ struct atapi_request_sense sense;
+ int stat = cdrom_check_status (drive, &sense);
+ if (stat == 0 || sense.sense_key == UNIT_ATTENTION)
+ return CDS_DISC_OK;
+
+ if (sense.sense_key == NOT_READY && sense.asc == 0x04 &&
+ sense.ascq == 0x04)
return CDS_DISC_OK;
- if (my_reqbuf.sense_key == NOT_READY) {
+ if (sense.sense_key == NOT_READY) {
/* ATAPI doesn't have anything that can help
us decide whether the drive is really
emtpy or the tray is just open. irk. */
@@ -2147,24 +2116,8 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
}
return CDS_DRIVE_NOT_READY;
- }
-
-#if ! STANDARD_ATAPI
- else if (cdi->sanyo_slot > 0)
- return CDS_NO_INFO;
-#endif /* not STANDARD_ATAPI */
-
- else {
- struct atapi_changer_info *ci;
- int stat = cdrom_read_changer_info (drive);
- if (stat < 0)
- return stat;
- ci = info->changer_info;
-
- if (ci->slots[slot_nr].disc_present)
- return CDS_DISC_OK;
- else
- return CDS_NO_DISC;
+ } else {
+ return -EINVAL;
}
}
@@ -2215,47 +2168,14 @@ int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
int slot_nr)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
- struct cdrom_info *info = drive->driver_data;
- struct atapi_request_sense reqbuf;
- int retval;
if (slot_nr == CDSL_CURRENT) {
(void) cdrom_check_status (drive, NULL);
- retval = CDROM_STATE_FLAGS (drive)->media_changed;
CDROM_STATE_FLAGS (drive)->media_changed = 0;
+ return CDROM_STATE_FLAGS (drive)->media_changed;
+ } else {
+ return -EINVAL;
}
-
-#if ! STANDARD_ATAPI
- else if (cdi->sanyo_slot > 0) {
- retval = 0;
- }
-#endif /* not STANDARD_ATAPI */
-
- else {
- struct atapi_changer_info *ci;
- int stat = cdrom_read_changer_info (drive);
- if (stat < 0)
- return stat;
- ci = info->changer_info;
-
- /* This test may be redundant with cdrom.c. */
- if (slot_nr < 0 || slot_nr >= ci->hdr.nslots)
- return -EINVAL;
-
- retval = ci->slots[slot_nr].change;
- }
-
- /* if the media has changed, check if a disc is in the drive
- and read the toc info. */
- if (retval || !CDROM_STATE_FLAGS (drive)->toc_valid) {
- /* if cdrom_read_toc fails, return 1 to indicate
- that a disc change has occured. there might not
- be a disc in the drive. */
- if ((retval = cdrom_read_toc (drive, &reqbuf)))
- return 1;
- }
-
- return retval;
}
@@ -2361,11 +2281,12 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
* be queued with ide_cdrom_packet(), which extracts the
* drive from cdi->handle. Since this device hasn't been
* registered with the Uniform layer yet, it can't do this.
- * Same goes cdi->ops.
+ * Same goes for cdi->ops.
*/
cdi->handle = (ide_drive_t *) drive;
cdi->ops = &ide_cdrom_dops;
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
+ /* we seem to get stat=0x01,err=0x00 the first time (??) */
+ do {
if (attempts-- <= 0)
return 0;
stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
@@ -2402,14 +2323,9 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
#endif /* not STANDARD_ATAPI */
if (buf.cap.mechtype == mechtype_individual_changer ||
buf.cap.mechtype == mechtype_cartridge_changer) {
- struct atapi_mechstat_header mechbuf;
-
- stat = cdrom_read_mech_status (drive, (char*)&mechbuf,
- sizeof (mechbuf), NULL);
- if (!stat) {
+ if ((nslots = cdrom_number_of_slots(cdi)) > 1) {
CDROM_CONFIG_FLAGS (drive)->is_changer = 1;
CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 1;
- nslots = mechbuf.nslots;
}
}
@@ -2445,7 +2361,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
else
printk (" drive");
- printk (", %dkB Cache", ntohs(buf.cap.buffer_size));
+ printk (", %dkB Cache", be16_to_cpu(buf.cap.buffer_size));
if (drive->using_dma) {
if ((drive->id->field_valid & 4) &&
@@ -2473,7 +2389,6 @@ static void ide_cdrom_add_settings(ide_drive_t *drive)
ide_add_setting(drive, "dsc_overlap", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
}
-
static
int ide_cdrom_setup (ide_drive_t *drive)
{
@@ -2482,13 +2397,12 @@ int ide_cdrom_setup (ide_drive_t *drive)
int minor = drive->select.b.unit << PARTN_BITS;
int nslots;
- kdev_t dev = MKDEV(HWIF(drive)->major, minor);
-
- set_device_ro (dev, 1);
+ set_device_ro(MKDEV(HWIF(drive)->major, minor), 1);
blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
- drive->special.all = 0;
- drive->ready_stat = 0;
+ drive->special.all = 0;
+ drive->ready_stat = 0;
+ drive->timeout = WAIT_CMD;
CDROM_STATE_FLAGS (drive)->media_changed = 1;
CDROM_STATE_FLAGS (drive)->toc_valid = 0;
@@ -2589,11 +2503,13 @@ int ide_cdrom_setup (ide_drive_t *drive)
}
#endif /* not STANDARD_ATAPI */
- info->toc = NULL;
- info->sector_buffer = NULL;
- info->sector_buffered = 0;
- info->nsectors_buffered = 0;
+ info->toc = NULL;
+ info->buffer = NULL;
+ info->sector_buffered = 0;
+ info->nsectors_buffered = 0;
info->changer_info = NULL;
+ info->last_block = 0;
+ info->start_seek = 0;
nslots = ide_cdrom_probe_capabilities (drive);
@@ -2653,15 +2569,15 @@ int ide_cdrom_cleanup(ide_drive_t *drive)
if (ide_unregister_subdriver (drive))
return 1;
- if (info->sector_buffer != NULL)
- kfree (info->sector_buffer);
+ if (info->buffer != NULL)
+ kfree(info->buffer);
if (info->toc != NULL)
- kfree (info->toc);
+ kfree(info->toc);
if (info->changer_info != NULL)
- kfree (info->changer_info);
+ kfree(info->changer_info);
if (devinfo->handle == drive && unregister_cdrom (devinfo))
printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
- kfree (info);
+ kfree(info);
drive->driver_data = NULL;
return 0;
}
diff --git a/drivers/block/ide-cd.h b/drivers/block/ide-cd.h
index ae1a252ed..b65baa5fe 100644
--- a/drivers/block/ide-cd.h
+++ b/drivers/block/ide-cd.h
@@ -34,19 +34,13 @@
#define NO_DOOR_LOCKING 0
#endif
-
-/* Size of buffer to allocate, in blocks, for audio reads. */
-
-#ifndef CDROM_NBLOCKS_BUFFER
-#define CDROM_NBLOCKS_BUFFER 8
-#endif
-
-
/************************************************************************/
-#define SECTOR_SIZE 512
-#define SECTOR_BITS 9
-#define SECTORS_PER_FRAME (CD_FRAMESIZE / SECTOR_SIZE)
+#define SECTOR_SIZE 512
+#define SECTOR_BITS 9
+#define SECTORS_PER_FRAME (CD_FRAMESIZE / SECTOR_SIZE)
+#define SECTOR_BUFFER_SIZE (CD_FRAMESIZE * 32)
+#define SECTORS_BUFFER (SECTOR_BUFFER_SIZE / SECTOR_SIZE)
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -84,7 +78,8 @@ struct ide_cd_config_flags {
__u8 seeking : 1; /* Seeking in progress */
__u8 audio_play : 1; /* can do audio related commands */
__u8 close_tray : 1; /* can close the tray */
- __u8 reserved : 4;
+ __u8 writing : 1; /* pseudo write in progress */
+ __u8 reserved : 3;
byte max_speed; /* Max speed of the drive */
};
#define CDROM_CONFIG_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->config_flags))
@@ -96,7 +91,8 @@ struct ide_cd_state_flags {
__u8 media_changed : 1; /* Driver has noticed a media change. */
__u8 toc_valid : 1; /* Saved TOC information is current. */
__u8 door_locked : 1; /* We think that the drive door is locked. */
- __u8 reserved : 5;
+ __u8 writing : 1; /* the drive is currently writing */
+ __u8 reserved : 4;
byte current_speed; /* Current speed of the drive */
};
#define CDROM_STATE_FLAGS(drive) (&(((struct cdrom_info *)(drive->driver_data))->state_flags))
@@ -487,13 +483,11 @@ struct atapi_slot {
byte reserved2[3];
};
-
struct atapi_changer_info {
struct atapi_mechstat_header hdr;
struct atapi_slot slots[0];
};
-
/* Extra per-device info for cdrom drives. */
struct cdrom_info {
@@ -502,17 +496,9 @@ struct cdrom_info {
struct atapi_toc *toc;
- /* Sector buffer. If a read request wants only the first part
- of a cdrom block, we cache the rest of the block here,
- in the expectation that the data is going to be wanted soon.
- SECTOR_BUFFERED is the number of the first buffered sector,
- and NSECTORS_BUFFERED is the number of sectors in the buffer.
- Before the buffer is allocated, we should have
- SECTOR_BUFFER == NULL and NSECTORS_BUFFERED == 0. */
-
- unsigned long sector_buffered;
- unsigned long nsectors_buffered;
- char *sector_buffer;
+ unsigned long sector_buffered;
+ unsigned long nsectors_buffered;
+ unsigned char *buffer;
/* The result of the last successful request sense command
on this device. */
@@ -533,10 +519,6 @@ struct cdrom_info {
struct cdrom_device_info devinfo;
};
-
-#define SECTOR_BUFFER_SIZE CD_FRAMESIZE
-
-
/****************************************************************************
* Descriptions of ATAPI error codes.
*/
@@ -652,6 +634,7 @@ const struct {
{ 0x000013, "Play operation successfully completed" },
{ 0x000014, "Play operation stopped due to error" },
{ 0x000015, "No current audio status to return" },
+ { 0x010c0a, "Write error - padding blocks added" },
{ 0x011700, "Recovered data with no error correction applied" },
{ 0x011701, "Recovered data with retries" },
{ 0x011702, "Recovered data with positive head offset" },
@@ -668,6 +651,7 @@ const struct {
{ 0x015d01,
"Failure prediction threshold exceeded - Predicted media failure" },
{ 0x015dff, "Failure prediction threshold exceeded - False" },
+ { 0x017301, "Power calibration area almost full" },
{ 0x020400, "Logical unit not ready - cause not reportable" },
/* Following is misspelled in ATAPI 2.6, _and_ in Mt. Fuji */
{ 0x020401,
@@ -680,9 +664,35 @@ const struct {
{ 0x023a00, "Medium not present" },
{ 0x025300, "Media load or eject failed" },
{ 0x025700, "Unable to recover table of contents" },
+ { 0x030300, "Peripheral device write fault" },
+ { 0x030301, "No write current" },
+ { 0x030302, "Excessive write errors" },
+ { 0x030c00, "Write error" },
+ { 0x030c01, "Write error - Recovered with auto reallocation" },
+ { 0x030c02, "Write error - auto reallocation failed" },
+ { 0x030c03, "Write error - recommend reassignment" },
+ { 0x030c04, "Compression check miscompare error" },
+ { 0x030c05, "Data expansion occurred during compress" },
+ { 0x030c06, "Block not compressible" },
+ { 0x030c07, "Write error - recovery needed" },
+ { 0x030c08, "Write error - recovery failed" },
+ { 0x030c09, "Write error - loss of streaming" },
{ 0x031100, "Unrecovered read error" },
{ 0x031106, "CIRC unrecovered error" },
{ 0x033101, "Format command failed" },
+ { 0x033200, "No defect spare location available" },
+ { 0x033201, "Defect list update failure" },
+ { 0x035100, "Erase failure" },
+ { 0x037200, "Session fixation error" },
+ { 0x037201, "Session fixation error writin lead-in" },
+ { 0x037202, "Session fixation error writin lead-out" },
+ { 0x037300, "CD control error" },
+ { 0x037302, "Power calibration area is full" },
+ { 0x037303, "Power calibration area error" },
+ { 0x037304, "Program memory area / RMA update failure" },
+ { 0x037305, "Program memory area / RMA is full" },
+ { 0x037306, "Program memory area / RMA is (almost) full" },
+
{ 0x040200, "No seek complete" },
{ 0x040300, "Write fault" },
{ 0x040900, "Track following error" },
@@ -700,11 +710,15 @@ const struct {
{ 0x052000, "Invalid command operation code" },
{ 0x052c00, "Command sequence error" },
{ 0x052100, "Logical block address out of range" },
+ { 0x052102, "Invalid address for write" },
{ 0x052400, "Invalid field in command packet" },
{ 0x052600, "Invalid field in parameter list" },
{ 0x052601, "Parameter not supported" },
{ 0x052602, "Parameter value invalid" },
{ 0x052700, "Write protected media" },
+ { 0x052c00, "Command sequence error" },
+ { 0x052c03, "Current program area is not empty" },
+ { 0x052c04, "Current program area is empty" },
{ 0x053001, "Cannot read medium - unknown format" },
{ 0x053002, "Cannot read medium - incompatible format" },
{ 0x053900, "Saving parameters not supported" },
@@ -713,11 +727,15 @@ const struct {
{ 0x055500, "System resource failure" },
{ 0x056300, "End of user area encountered on this track" },
{ 0x056400, "Illegal mode for this track or incompatible medium" },
- { 0x056f00,
- "Copy protection key exchange failure - Authentication failure" },
+ { 0x056f00, "Copy protection key exchange failure - Authentication failure" },
{ 0x056f01, "Copy protection key exchange failure - Key not present" },
- { 0x056f02,
- "Copy protection key exchange failure - Key not established" },
+ { 0x056f02, "Copy protection key exchange failure - Key not established" },
+ { 0x056f03, "Read of scrambled sector without authentication" },
+ { 0x056f04, "Media region code is mismatched to logical unit" },
+ { 0x056f05, "Drive region must be permanent / region reset count error" },
+ { 0x057203, "Session fixation error - incomplete track in session" },
+ { 0x057204, "Empty or partially written reserved track" },
+ { 0x057205, "No more RZONE reservations are allowed" },
{ 0x05bf00, "Loss of streaming" },
{ 0x062800, "Not ready to ready transition, medium may have changed" },
{ 0x062900, "Power on, reset or hardware reset occurred" },
diff --git a/drivers/block/ide-disk.c b/drivers/block/ide-disk.c
index d2941a1ab..8fa7745b4 100644
--- a/drivers/block/ide-disk.c
+++ b/drivers/block/ide-disk.c
@@ -175,7 +175,7 @@ read_next:
if (i > 0) {
if (msect)
goto read_next;
- ide_set_handler (drive, &read_intr, WAIT_CMD);
+ ide_set_handler (drive, &read_intr);
}
}
@@ -206,7 +206,7 @@ static void write_intr (ide_drive_t *drive)
ide_end_request(1, hwgroup);
if (i > 0) {
idedisk_output_data (drive, rq->buffer, SECTOR_WORDS);
- ide_set_handler (drive, &write_intr, WAIT_CMD);
+ ide_set_handler (drive, &write_intr);
}
goto out;
}
@@ -271,7 +271,7 @@ static void multwrite_intr (ide_drive_t *drive)
if (stat & DRQ_STAT) {
if (rq->nr_sectors) {
ide_multwrite(drive, drive->mult_count);
- ide_set_handler (drive, &multwrite_intr, WAIT_CMD);
+ ide_set_handler (drive, &multwrite_intr);
goto out;
}
} else {
@@ -385,7 +385,7 @@ static void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long bl
if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive)))
return;
#endif /* CONFIG_BLK_DEV_IDEDMA */
- ide_set_handler(drive, &read_intr, WAIT_CMD);
+ ide_set_handler(drive, &read_intr);
OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
return;
}
@@ -404,10 +404,10 @@ static void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long bl
__cli(); /* local CPU only */
if (drive->mult_count) {
HWGROUP(drive)->wrq = *rq; /* scratchpad */
- ide_set_handler (drive, &multwrite_intr, WAIT_CMD);
+ ide_set_handler (drive, &multwrite_intr);
ide_multwrite(drive, drive->mult_count);
} else {
- ide_set_handler (drive, &write_intr, WAIT_CMD);
+ ide_set_handler (drive, &write_intr);
idedisk_output_data(drive, rq->buffer, SECTOR_WORDS);
}
return;
@@ -506,6 +506,7 @@ static void idedisk_pre_reset (ide_drive_t *drive)
drive->special.all = 0;
drive->special.b.set_geometry = 1;
drive->special.b.recalibrate = 1;
+ drive->timeout = WAIT_CMD;
if (OK_TO_RESET_CONTROLLER)
drive->mult_count = 0;
if (!drive->keep_settings)
diff --git a/drivers/block/ide-dma.c b/drivers/block/ide-dma.c
index d3c657516..338d51c9a 100644
--- a/drivers/block/ide-dma.c
+++ b/drivers/block/ide-dma.c
@@ -420,7 +420,8 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);/* issue cmd to drive */
+ drive->timeout = WAIT_CMD;
+ ide_set_handler(drive, &ide_dma_intr);/* issue cmd to drive */
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
case ide_dma_begin:
/* Note that this is done *after* the cmd has
@@ -460,7 +461,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
int ide_release_dma (ide_hwif_t *hwif)
{
if (hwif->dmatable) {
- clear_page((unsigned long)hwif->dmatable); /* clear PRD 1st */
+ clear_page((void *)hwif->dmatable); /* clear PRD 1st */
free_page((unsigned long)hwif->dmatable); /* free PRD 2nd */
}
if ((hwif->dma_extra) && (hwif->channel == 0))
@@ -537,14 +538,7 @@ unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const
switch(dev->device) {
case PCI_DEVICE_ID_CMD_643:
-#ifdef CONFIG_BLK_DEV_ALI15X3
case PCI_DEVICE_ID_AL_M5219:
- case PCI_DEVICE_ID_AL_M5229:
- /*
- * Ali 15x3 chipsets know as ALI IV and V report
- * this as simplex, skip this test for them.
- */
-#endif /* CONFIG_BLK_DEV_ALI15X3 */
outb(inb(dma_base+2) & 0x60, dma_base+2);
if (inb(dma_base+2) & 0x80) {
printk("%s: simplex device: DMA forced\n", name);
diff --git a/drivers/block/ide-floppy.c b/drivers/block/ide-floppy.c
index f1c8baef8..3db1c1515 100644
--- a/drivers/block/ide-floppy.c
+++ b/drivers/block/ide-floppy.c
@@ -916,7 +916,7 @@ static void idefloppy_pc_intr (ide_drive_t *drive)
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
idefloppy_discard_data (drive,bcount.all);
- ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD);
+ ide_set_handler (drive,&idefloppy_pc_intr);
return;
}
#if IDEFLOPPY_DEBUG_LOG
@@ -938,7 +938,7 @@ static void idefloppy_pc_intr (ide_drive_t *drive)
pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all;
- ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD); /* And set the interrupt handler again */
+ ide_set_handler (drive,&idefloppy_pc_intr); /* And set the interrupt handler again */
}
static void idefloppy_transfer_pc (ide_drive_t *drive)
@@ -956,7 +956,7 @@ static void idefloppy_transfer_pc (ide_drive_t *drive)
ide_do_reset (drive);
return;
}
- ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD); /* Set the interrupt routine */
+ ide_set_handler (drive, &idefloppy_pc_intr); /* Set the interrupt routine */
atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
}
@@ -1025,7 +1025,7 @@ static void idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc)
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
- ide_set_handler (drive, &idefloppy_transfer_pc, IDEFLOPPY_WAIT_CMD);
+ ide_set_handler (drive, &idefloppy_transfer_pc);
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
} else {
OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -1519,6 +1519,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
*((unsigned short *) &gcw) = drive->id->config;
drive->driver_data = floppy;
drive->ready_stat = 0;
+ drive->timeout = IDEFLOPPY_WAIT_CMD;
memset (floppy, 0, sizeof (idefloppy_floppy_t));
floppy->drive = drive;
floppy->pc = floppy->pc_stack;
diff --git a/drivers/block/ide-geometry.c b/drivers/block/ide-geometry.c
index 974fb24f1..44aa1844d 100644
--- a/drivers/block/ide-geometry.c
+++ b/drivers/block/ide-geometry.c
@@ -5,6 +5,9 @@
#include <asm/io.h>
+extern ide_drive_t * get_info_ptr(kdev_t);
+extern unsigned long current_capacity (ide_drive_t *);
+
/*
* We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
* controller that is BIOS compatible with ST-506, and thus showing up in our
diff --git a/drivers/block/ide-pci.c b/drivers/block/ide-pci.c
index 311bd470b..73ffa67ea 100644
--- a/drivers/block/ide-pci.c
+++ b/drivers/block/ide-pci.c
@@ -57,8 +57,9 @@
#define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693})
#define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013})
#define DEVID_CX5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE})
+#define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, 0x7409})
-#define IDE_IGNORE ((void *)-1)
+#define IDE_IGNORE ((void *)-1)
#ifdef CONFIG_BLK_DEV_TRM290
extern void ide_init_trm290(ide_hwif_t *);
@@ -106,54 +107,66 @@ extern void ide_init_rz1000(ide_hwif_t *);
#define INIT_RZ1000 IDE_IGNORE
#endif
-#ifdef CONFIG_BLK_DEV_VIA82C586
-extern unsigned int pci_init_via82c568(struct pci_dev *, const char *);
-extern void ide_init_via82c586(ide_hwif_t *);
-extern void ide_dmacapable_via82c586(ide_hwif_t *, unsigned long dmabase);
-#define PCI_VIA82C586 &pci_init_via82c568
-#define INIT_VIA82C586 &ide_init_via82c586
-#define DMA_VIA82C586 &ide_dmacapable_via82c586
+#ifdef CONFIG_BLK_DEV_VIA82CXXX
+extern unsigned int pci_init_via82cxxx(struct pci_dev *, const char *);
+extern unsigned int ata66_via82cxxx(ide_hwif_t *);
+extern void ide_init_via82cxxx(ide_hwif_t *);
+extern void ide_dmacapable_via82cxxx(ide_hwif_t *, unsigned long);
+#define PCI_VIA82CXXX &pci_init_via82cxxx
+#define ATA66_VIA82CXXX &ata66_via82cxxx
+#define INIT_VIA82CXXX &ide_init_via82cxxx
+#define DMA_VIA82CXXX &ide_dmacapable_via82cxxx
#else
-#define PCI_VIA82C586 NULL
-#define INIT_VIA82C586 NULL
-#define DMA_VIA82C586 NULL
+#define PCI_VIA82CXXX NULL
+#define ATA66_VIA82CXXX NULL
+#define INIT_VIA82CXXX NULL
+#define DMA_VIA82CXXX NULL
#endif
#ifdef CONFIG_BLK_DEV_ALI15X3
extern unsigned int pci_init_ali15x3(struct pci_dev *, const char *);
+extern unsigned int ata66_ali15x3(ide_hwif_t *);
extern void ide_init_ali15x3(ide_hwif_t *);
+extern void ide_dmacapable_ali15x3(ide_hwif_t *, unsigned long);
#define PCI_ALI15X3 &pci_init_ali15x3
-#define INIT_ALI15X3 &ide_init_ali15x3
+#define ATA66_ALI15X3 &ata66_ali15x3
+#define INIT_ALI15X3 &ide_init_ali15x3
+#define DMA_ALI15X3 &ide_dmacapable_ali15x3
#else
#define PCI_ALI15X3 NULL
-#define INIT_ALI15X3 NULL
+#define ATA66_ALI15X3 NULL
+#define INIT_ALI15X3 NULL
+#define DMA_ALI15X3 NULL
#endif
#ifdef CONFIG_BLK_DEV_CY82C693
extern unsigned int pci_init_cy82c693(struct pci_dev *, const char *);
extern void ide_init_cy82c693(ide_hwif_t *);
#define PCI_CY82C693 &pci_init_cy82c693
-#define INIT_CY82C693 &ide_init_cy82c693
+#define INIT_CY82C693 &ide_init_cy82c693
#else
#define PCI_CY82C693 NULL
-#define INIT_CY82C693 NULL
+#define INIT_CY82C693 NULL
#endif
#ifdef CONFIG_BLK_DEV_PDC202XX
extern unsigned int pci_init_pdc202xx(struct pci_dev *, const char *);
+extern unsigned int ata66_pdc202xx(ide_hwif_t *);
extern void ide_init_pdc202xx(ide_hwif_t *);
#define PCI_PDC202XX &pci_init_pdc202xx
-#define INIT_PDC202XX &ide_init_pdc202xx
+#define ATA66_PDC202XX &ata66_pdc202xx
+#define INIT_PDC202XX &ide_init_pdc202xx
#else
#define PCI_PDC202XX NULL
-#define INIT_PDC202XX NULL
+#define ATA66_PDC202XX NULL
+#define INIT_PDC202XX NULL
#endif
#ifdef CONFIG_BLK_DEV_PIIX
extern void ide_init_piix(ide_hwif_t *);
-#define INIT_PIIX &ide_init_piix
+#define INIT_PIIX &ide_init_piix
#else
-#define INIT_PIIX NULL
+#define INIT_PIIX NULL
#endif
#ifdef CONFIG_BLK_DEV_AEC6210
@@ -167,29 +180,40 @@ extern unsigned int pci_init_aec6210(struct pci_dev *, const char *);
extern unsigned int pci_init_hpt34x(struct pci_dev *, const char *);
extern void ide_init_hpt34x(ide_hwif_t *);
#define PCI_HPT34X &pci_init_hpt34x
-#define INIT_HPT34X &ide_init_hpt34x
+#define INIT_HPT34X &ide_init_hpt34x
#else
#define PCI_HPT34X NULL
-#define INIT_HPT34X NULL
+#define INIT_HPT34X NULL
#endif
#ifdef CONFIG_BLK_DEV_HPT366
+extern byte hpt363_shared_irq;
extern unsigned int pci_init_hpt366(struct pci_dev *, const char *);
+extern unsigned int ata66_hpt366(ide_hwif_t *);
extern void ide_init_hpt366(ide_hwif_t *);
+extern void ide_dmacapable_hpt366(ide_hwif_t *, unsigned long);
#define PCI_HPT366 &pci_init_hpt366
+#define ATA66_HPT366 &ata66_hpt366
#define INIT_HPT366 &ide_init_hpt366
+#define DMA_HPT366 &ide_dmacapable_hpt366
#else
+static byte hpt363_shared_irq = 0;
#define PCI_HPT366 NULL
-#define INIT_HPT366 IDE_IGNORE
+#define ATA66_HPT366 NULL
+#define INIT_HPT366 NULL
+#define DMA_HPT366 NULL
#endif
#ifdef CONFIG_BLK_DEV_SIS5513
extern unsigned int pci_init_sis5513(struct pci_dev *, const char *);
+extern unsigned int ata66_sis5513(ide_hwif_t *);
extern void ide_init_sis5513(ide_hwif_t *);
#define PCI_SIS5513 &pci_init_sis5513
+#define ATA66_SIS5513 &ata66_sis5513
#define INIT_SIS5513 &ide_init_sis5513
#else
#define PCI_SIS5513 NULL
+#define ATA66_SIS5513 NULL
#define INIT_SIS5513 NULL
#endif
@@ -206,49 +230,48 @@ typedef struct ide_pci_device_s {
ide_pci_devid_t devid;
const char *name;
unsigned int (*init_chipset)(struct pci_dev *dev, const char *name);
+ unsigned int (*ata66_check)(ide_hwif_t *hwif);
void (*init_hwif)(ide_hwif_t *hwif);
void (*dma_init)(ide_hwif_t *hwif, unsigned long dmabase);
ide_pci_enablebit_t enablebits[2];
byte bootable;
- byte sixtysix;
unsigned int extra;
} ide_pci_device_t;
static ide_pci_device_t ide_pci_chipsets[] __initdata = {
- {DEVID_PIIXa, "PIIX", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
- {DEVID_PIIXb, "PIIX", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
- {DEVID_PIIX3, "PIIX3", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
- {DEVID_PIIX4, "PIIX4", NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
- {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_VP_IDE, "VP_IDE", PCI_VIA82C586, INIT_VIA82C586, DMA_VIA82C586, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0, 0 },
- {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 0, 16 },
- {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 1, 48 },
- {DEVID_RZ1000, "RZ1000", NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_RZ1001, "RZ1001", NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_SAMURAI, "SAMURAI", NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_CMD640, "CMD640", NULL, IDE_IGNORE, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_NS87410, "NS87410", NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0, 0 },
- {DEVID_SIS5513, "SIS5513", PCI_SIS5513, INIT_SIS5513, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 1, 0 },
- {DEVID_CMD643, "CMD643", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_CMD646, "CMD646", NULL, INIT_CMD646, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0, 0 },
- {DEVID_HT6565, "HT6565", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_OPTI621, "OPTI621", NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_OPTI621X,"OPTI621X", NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_TRM290, "TRM290", NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_NS87415, "NS87415", NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_AEC6210, "AEC6210", PCI_AEC6210, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, 0 },
- {DEVID_W82C105, "W82C105", NULL, INIT_W82C105, NULL, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0, 0 },
- {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_HPT34X, "HPT34X", PCI_HPT34X, INIT_HPT34X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 0, 16 },
- {DEVID_HPT366, "HPT366", PCI_HPT366, INIT_HPT366, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 1, 256 },
- {DEVID_ALI15X3, "ALI15X3", PCI_ALI15X3, INIT_ALI15X3, NULL, {{0x09,0x20,0x20}, {0x09,0x10,0x10}}, ON_BOARD, 0, 0 },
- {DEVID_CY82C693,"CY82C693", PCI_CY82C693, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {DEVID_CX5530, "CX5530", NULL, INIT_CX5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
- {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 }};
-
-static byte hpt363_shared_irq = 0;
+ {DEVID_PIIXa, "PIIX", NULL, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_PIIXb, "PIIX", NULL, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_PIIX3, "PIIX3", NULL, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_PIIX4, "PIIX4", NULL, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 },
+ {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 },
+ {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 },
+ {DEVID_RZ1000, "RZ1000", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_RZ1001, "RZ1001", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_SAMURAI, "SAMURAI", NULL, NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_CMD640, "CMD640", NULL, NULL, IDE_IGNORE, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_NS87410, "NS87410", NULL, NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0 },
+ {DEVID_SIS5513, "SIS5513", PCI_SIS5513, ATA66_SIS5513, INIT_SIS5513, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, ON_BOARD, 0 },
+ {DEVID_CMD643, "CMD643", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_CMD646, "CMD646", NULL, NULL, INIT_CMD646, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 },
+ {DEVID_HT6565, "HT6565", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_OPTI621, "OPTI621", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 },
+ {DEVID_OPTI621X,"OPTI621X", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 },
+ {DEVID_TRM290, "TRM290", NULL, NULL, INIT_TRM290, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_NS87415, "NS87415", NULL, NULL, INIT_NS87415, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_AEC6210, "AEC6210", PCI_AEC6210, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 },
+ {DEVID_W82C105, "W82C105", NULL, NULL, INIT_W82C105, NULL, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 },
+ {DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_UM8886BF,"UM8886BF", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_HPT34X, "HPT34X", PCI_HPT34X, NULL, INIT_HPT34X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 16 },
+ {DEVID_HPT366, "HPT366", PCI_HPT366, ATA66_HPT366, INIT_HPT366, DMA_HPT366, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 256 },
+ {DEVID_ALI15X3, "ALI15X3", PCI_ALI15X3, ATA66_ALI15X3, INIT_ALI15X3, DMA_ALI15X3, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_CX5530, "CX5530", NULL, NULL, INIT_CX5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {DEVID_AMD7409, "AMD7409", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
+ {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }};
/*
* This allows offboard ide-pci cards the enable a BIOS, verify interrupt
@@ -260,24 +283,24 @@ static unsigned int __init ide_special_settings (struct pci_dev *dev, const char
switch(dev->device) {
case PCI_DEVICE_ID_TTI_HPT343:
{
+ int i;
+ unsigned long hpt34xIoBase = dev->resource[4].start;
unsigned short pcicmd = 0;
pci_write_config_byte(dev, 0x80, 0x00);
pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
if (!(pcicmd & PCI_COMMAND_MEMORY)) {
- int i;
- unsigned long hpt34xIoBase = dev->resource[4].start;
-
- dev->resource[0].start = (hpt34xIoBase + 0x20);
- dev->resource[1].start = (hpt34xIoBase + 0x34);
- dev->resource[2].start = (hpt34xIoBase + 0x28);
- dev->resource[3].start = (hpt34xIoBase + 0x3c);
- for(i=0; i<4; i++)
- dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
} else {
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
}
+
+ dev->resource[0].start = (hpt34xIoBase + 0x20);
+ dev->resource[1].start = (hpt34xIoBase + 0x34);
+ dev->resource[2].start = (hpt34xIoBase + 0x28);
+ dev->resource[3].start = (hpt34xIoBase + 0x3c);
+ for(i=0; i<4; i++)
+ dev->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
}
case PCI_DEVICE_ID_TTI_HPT366:
case PCI_DEVICE_ID_PROMISE_20246:
@@ -530,8 +553,7 @@ check_if_enabled:
hwif->irq = hwif->channel ? 15 : 14;
goto bypass_umc_dma;
}
- if ((!d->sixtysix) && (hwif->udma_four))
- hwif->udma_four = 0;
+ hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X))
@@ -582,40 +604,35 @@ bypass_umc_dma:
static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
{
- struct pci_dev *dev2;
+ struct pci_dev *dev2 = NULL, *findev;
ide_pci_device_t *d2;
unsigned char pin1 = 0, pin2 = 0;
- d2 = d;
if (PCI_FUNC(dev->devfn) & 1)
return;
-
- for (dev2=pci_devices; dev2; dev2=dev2->next) {
- if ((dev2->vendor == dev->vendor) &&
- (dev2->device == dev->device) &&
- (PCI_FUNC(dev2->devfn) & 1))
- break;
- }
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1);
- if (dev2) {
- pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
- hpt363_shared_irq = (pin1 != pin2) ? 1 : 0;
- }
-
- if (hpt363_shared_irq) {
- printk("%s: onboard version of chipset, pin1=%d pin2=%d\n",
- d->name, pin1, pin2);
+ for (findev=pci_devices; findev; findev=findev->next) {
+ if ((findev->vendor == dev->vendor) &&
+ (findev->device == dev->device) &&
+ ((findev->devfn - dev->devfn) == 1) &&
+ (PCI_FUNC(findev->devfn) & 1)) {
+ dev2 = findev;
+ pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2);
+ hpt363_shared_irq = (pin1 != pin2) ? 1 : 0;
+ if (hpt363_shared_irq) {
+ d->bootable = ON_BOARD;
+ printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", d->name, pin1, pin2);
+ }
+ break;
+ }
}
-
- printk("%s: IDE controller on PCI bus %02x dev %02x\n",
- d->name, dev->bus->number, dev->devfn);
+ printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
ide_setup_pci_device(dev, d);
-
- if (dev2 && !hpt363_shared_irq) {
- printk("%s: IDE controller on PCI bus %02x dev %02x\n",
- d2->name, dev2->bus->number, dev2->devfn);
- ide_setup_pci_device(dev2, d2);
- }
+ if (!dev2)
+ return;
+ d2 = d;
+ printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn);
+ ide_setup_pci_device(dev2, d2);
}
/*
diff --git a/drivers/block/ide-pmac.c b/drivers/block/ide-pmac.c
index 1ad5b3b96..c3e800249 100644
--- a/drivers/block/ide-pmac.c
+++ b/drivers/block/ide-pmac.c
@@ -363,7 +363,8 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
drive->waiting_for_dma = 1;
if (drive->media != ide_disk)
return 0;
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
+ drive->timeout = WAIT_CMD;
+ ide_set_handler(drive, &ide_dma_intr);
OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
IDE_COMMAND_REG);
case ide_dma_begin:
diff --git a/drivers/block/ide-probe.c b/drivers/block/ide-probe.c
index 62008341e..d430c5b1d 100644
--- a/drivers/block/ide-probe.c
+++ b/drivers/block/ide-probe.c
@@ -42,7 +42,6 @@
#include <linux/delay.h>
#include <linux/ide.h>
-
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
@@ -85,6 +84,9 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap);
+ if (strstr(id->model, "E X A B Y T E N E S T"))
+ return;
+
id->model[sizeof(id->model)-1] = '\0'; /* we depend on this a lot! */
printk("%s: %s, ", drive->name, id->model);
drive->present = 1;
@@ -324,6 +326,35 @@ static int do_probe (ide_drive_t *drive, byte cmd)
}
/*
+ *
+ */
+static void enable_nest (ide_drive_t *drive)
+{
+ unsigned long timeout;
+
+ printk("%s: enabling %s -- ", HWIF(drive)->name, drive->id->model);
+ SELECT_DRIVE(HWIF(drive), drive);
+ ide_delay_50ms();
+ OUT_BYTE(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
+ timeout = jiffies + WAIT_WORSTCASE;
+ do {
+ if (jiffies > timeout) {
+ printk("failed (timeout)\n");
+ return;
+ }
+ ide_delay_50ms();
+ } while (GET_STAT() & BUSY_STAT);
+ ide_delay_50ms();
+ if (!OK_STAT(GET_STAT(), 0, BAD_STAT))
+ printk("failed (status = 0x%02x)\n", GET_STAT());
+ else
+ printk("success\n");
+ if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
+ (void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
+ }
+}
+
+/*
* probe_for_drive() tests for existence of a given drive using do_probe().
*
* Returns: 0 no device was found
@@ -336,6 +367,8 @@ static inline byte probe_for_drive (ide_drive_t *drive)
if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
(void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
}
+ if (drive->id && strstr(drive->id->model, "E X A B Y T E N E S T"))
+ enable_nest(drive);
if (!drive->present)
return 0; /* drive not found */
if (drive->id == NULL) { /* identification failed? */
diff --git a/drivers/block/ide-proc.c b/drivers/block/ide-proc.c
index 8afe1568f..48d77c160 100644
--- a/drivers/block/ide-proc.c
+++ b/drivers/block/ide-proc.c
@@ -73,14 +73,21 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
-#ifdef CONFIG_BLK_DEV_VIA82C586
-int (*via_display_info)(char *, char **, off_t, int, int) = NULL;
-#endif /* CONFIG_BLK_DEV_VIA82C586 */
-
#ifdef CONFIG_BLK_DEV_ALI15X3
+extern byte ali_proc;
int (*ali_display_info)(char *, char **, off_t, int, int) = NULL;
#endif /* CONFIG_BLK_DEV_ALI15X3 */
+#ifdef CONFIG_BLK_DEV_SIS5513
+extern byte sis_proc;
+int (*sis_display_info)(char *, char **, off_t, int, int) = NULL;
+#endif /* CONFIG_BLK_DEV_SIS5513 */
+
+#ifdef CONFIG_BLK_DEV_VIA82CXXX
+extern byte via_proc;
+int (*via_display_info)(char *, char **, off_t, int, int) = NULL;
+#endif /* CONFIG_BLK_DEV_VIA82CXXX */
+
static int ide_getxdigit(char c)
{
int digit;
@@ -243,7 +250,27 @@ static int proc_ide_write_config
}
#endif /* CONFIG_BLK_DEV_IDEPCI */
} else { /* not pci */
-#ifndef CONFIG_Q40
+#if !defined(__mc68000__) && !defined(CONFIG_APUS)
+
+/*
+ * Geert Uytterhoeven
+ *
+ * unless you can explain me what it really does.
+ * On m68k, we don't have outw() and outl() yet,
+ * and I need a good reason to implement it.
+ *
+ * BTW, IMHO the main remaining portability problem with the IDE driver
+ * is that it mixes IO (ioport) and MMIO (iomem) access on different platforms.
+ *
+ * I think all accesses should be done using
+ *
+ * ide_in[bwl](ide_device_instance, offset)
+ * ide_out[bwl](ide_device_instance, value, offset)
+ *
+ * so the architecture specific code can #define ide_{in,out}[bwl] to the
+ * appropriate function.
+ *
+ */
switch (digits) {
case 2: outb(val, reg);
break;
@@ -252,7 +279,7 @@ static int proc_ide_write_config
case 8: outl(val, reg);
break;
}
-#endif /* CONFIG_Q40 */
+#endif /* !__mc68000__ && !CONFIG_APUS */
}
}
}
@@ -750,18 +777,24 @@ void proc_ide_create(void)
ent = create_proc_entry("drivers", 0, proc_ide_root);
if (!ent) return;
ent->read_proc = proc_ide_read_drivers;
-#ifdef CONFIG_BLK_DEV_VIA82C586
- if (via_display_info) {
- ent = create_proc_entry("via", 0, proc_ide_root);
- ent->get_info = via_display_info;
- }
-#endif /* CONFIG_BLK_DEV_VIA82C586 */
#ifdef CONFIG_BLK_DEV_ALI15X3
- if (ali_display_info) {
+ if ((ali_display_info) && (ali_proc)) {
ent = create_proc_entry("ali", 0, proc_ide_root);
ent->get_info = ali_display_info;
}
#endif /* CONFIG_BLK_DEV_ALI15X3 */
+#ifdef CONFIG_BLK_DEV_SIS5513
+ if ((sis_display_info) && (sis_proc)) {
+ ent = create_proc_entry("sis", 0, proc_ide_root);
+ ent->get_info = sis_display_info;
+ }
+#endif /* CONFIG_BLK_DEV_SIS5513 */
+#ifdef CONFIG_BLK_DEV_VIA82CXXX
+ if ((via_display_info) && (via_proc)) {
+ ent = create_proc_entry("via", 0, proc_ide_root);
+ ent->get_info = via_display_info;
+ }
+#endif /* CONFIG_BLK_DEV_VIA82CXXX */
}
void proc_ide_destroy(void)
@@ -770,14 +803,18 @@ void proc_ide_destroy(void)
* Mmmm.. does this free up all resources,
* or do we need to do a more proper cleanup here ??
*/
-#ifdef CONFIG_BLK_DEV_VIA82C586
- if (via_display_info)
- remove_proc_entry("ide/via",0);
-#endif /* CONFIG_BLK_DEV_VIA82C586 */
#ifdef CONFIG_BLK_DEV_ALI15X3
- if (ali_display_info)
+ if ((ali_display_info) && (ali_proc))
remove_proc_entry("ide/ali",0);
#endif /* CONFIG_BLK_DEV_ALI15X3 */
+#ifdef CONFIG_BLK_DEV_SIS5513
+ if ((sis_display_info) && (sis_proc))
+ remove_proc_entry("ide/sis", 0);
+#endif /* CONFIG_BLK_DEV_SIS5513 */
+#ifdef CONFIG_BLK_DEV_VIA82CXXX
+ if ((via_display_info) && (via_proc))
+ remove_proc_entry("ide/via",0);
+#endif /* CONFIG_BLK_DEV_VIA82CXXX */
remove_proc_entry("ide/drivers", 0);
destroy_proc_ide_interfaces();
remove_proc_entry("ide", 0);
diff --git a/drivers/block/ide-tape.c b/drivers/block/ide-tape.c
index 6e8313733..bbf222338 100644
--- a/drivers/block/ide-tape.c
+++ b/drivers/block/ide-tape.c
@@ -1833,7 +1833,7 @@ static void idetape_pc_intr (ide_drive_t *drive)
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
idetape_discard_data (drive,bcount.all);
- ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD);
+ ide_set_handler (drive,&idetape_pc_intr);
return;
}
#if IDETAPE_DEBUG_LOG
@@ -1855,7 +1855,7 @@ static void idetape_pc_intr (ide_drive_t *drive)
pc->actually_transferred+=bcount.all; /* Update the current position */
pc->current_position+=bcount.all;
- ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD); /* And set the interrupt handler again */
+ ide_set_handler (drive,&idetape_pc_intr); /* And set the interrupt handler again */
}
/*
@@ -1928,7 +1928,7 @@ static void idetape_transfer_pc(ide_drive_t *drive)
ide_do_reset (drive);
return;
}
- ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD); /* Set the interrupt routine */
+ ide_set_handler(drive, &idetape_pc_intr); /* Set the interrupt routine */
atapi_output_bytes (drive,pc->c,12); /* Send the actual packet */
}
@@ -1995,7 +1995,7 @@ static void idetape_issue_packet_command (ide_drive_t *drive, idetape_pc_t *pc)
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
- ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD);
+ ide_set_handler(drive, &idetape_transfer_pc);
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
} else {
OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -3579,6 +3579,7 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
spin_lock_init(&tape->spinlock);
drive->driver_data = tape;
drive->ready_stat = 0; /* An ATAPI device ignores DRDY */
+ drive->timeout = IDETAPE_WAIT_CMD;
#ifdef CONFIG_BLK_DEV_IDEPCI
/*
* These two ide-pci host adapters appear to need this disabled.
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index d2cb4b34b..f0c9d58da 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -149,9 +149,9 @@
#include <linux/kmod.h>
#endif /* CONFIG_KMOD */
-#ifdef CONFIG_BLK_DEV_VIA82C586
-extern byte fifoconfig; /* defined in via82c586.c used by ide_setup()*/
-#endif
+#ifdef CONFIG_BLK_DEV_VIA82CXXX
+extern byte fifoconfig; /* defined in via82cxxx.c used by ide_setup() */
+#endif /* CONFIG_BLK_DEV_VIA82CXXX */
static const byte ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
IDE2_MAJOR, IDE3_MAJOR,
@@ -498,13 +498,25 @@ void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup)
}
/*
+ * The below two are helpers used when modifying the drive timeout.
+ */
+static inline unsigned long set_timeout(ide_drive_t *drive, unsigned long timeout)
+{
+ unsigned long foo = drive->timeout;
+ drive->timeout = timeout;
+ return foo;
+}
+
+#define restore_timeout(drive, old) (drive->timeout = old)
+
+/*
* This should get invoked any time we exit the driver to
* wait for an interrupt response from a drive. handler() points
* at the appropriate code to handle the next interrupt, and a
* timer is started to prevent us from waiting forever in case
* something goes wrong (see the ide_timer_expiry() handler later on).
*/
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout)
+void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
@@ -517,8 +529,11 @@ void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int t
}
#endif
hwgroup->handler = handler;
- hwgroup->timer.expires = jiffies + timeout;
- add_timer(&(hwgroup->timer));
+ /* 0 means don't timeout */
+ if (drive->timeout && !timer_pending(&hwgroup->timer)) {
+ hwgroup->timer.expires = jiffies + drive->timeout;
+ add_timer(&(hwgroup->timer));
+ }
spin_unlock_irqrestore(&hwgroup->spinlock, flags);
}
@@ -565,6 +580,7 @@ static void do_reset1 (ide_drive_t *, int); /* needed below */
static void atapi_reset_pollfunc (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
+ unsigned long old_timeout;
byte stat;
SELECT_DRIVE(HWIF(drive),drive);
@@ -574,7 +590,9 @@ static void atapi_reset_pollfunc (ide_drive_t *drive)
printk("%s: ATAPI reset complete\n", drive->name);
} else {
if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
- ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
+ old_timeout = set_timeout(drive, HZ / 20);
+ ide_set_handler (drive, &atapi_reset_pollfunc);
+ restore_timeout(drive, old_timeout);
return; /* continue polling */
}
hwgroup->poll_timeout = 0; /* end of polling */
@@ -595,11 +613,14 @@ static void reset_pollfunc (ide_drive_t *drive)
{
ide_hwgroup_t *hwgroup = HWGROUP(drive);
ide_hwif_t *hwif = HWIF(drive);
+ unsigned long old_timeout;
byte tmp;
if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
- ide_set_handler (drive, &reset_pollfunc, HZ/20);
+ old_timeout = set_timeout(drive, HZ / 20);
+ ide_set_handler (drive, &reset_pollfunc);
+ restore_timeout(drive, old_timeout);
return; /* continue polling */
}
printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
@@ -667,6 +688,7 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
unsigned long flags;
ide_hwif_t *hwif = HWIF(drive);
ide_hwgroup_t *hwgroup = HWGROUP(drive);
+ unsigned long old_timeout;
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
@@ -678,7 +700,9 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
udelay (20);
OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
+ old_timeout = set_timeout(drive, HZ / 20);
+ ide_set_handler (drive, &atapi_reset_pollfunc);
+ restore_timeout(drive, old_timeout);
__restore_flags (flags); /* local CPU only */
return;
}
@@ -708,7 +732,18 @@ static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
udelay(10); /* more than enough time */
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler (drive, &reset_pollfunc, HZ/20);
+ old_timeout = set_timeout(drive, HZ / 20);
+ ide_set_handler (drive, &reset_pollfunc);
+ restore_timeout(drive, old_timeout);
+
+ /*
+ * Some weird controller like resetting themselves to a strange
+ * state when the disks are reset this way. At least, the Winbond
+ * 553 documentation says that
+ */
+ if (hwif->resetproc != NULL)
+ hwif->resetproc(drive);
+
#endif /* OK_TO_RESET_CONTROLLER */
__restore_flags (flags); /* local CPU only */
@@ -899,7 +934,7 @@ void ide_error (ide_drive_t *drive, const char *msg, byte stat)
*/
void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
{
- ide_set_handler (drive, handler, WAIT_CMD);
+ ide_set_handler (drive, handler);
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */
OUT_BYTE(nsect,IDE_NSECTOR_REG);
@@ -1018,6 +1053,10 @@ static void execute_drive_cmd (ide_drive_t *drive, struct request *rq)
if (args[0] == WIN_SMART) {
OUT_BYTE(0x4f, IDE_LCYL_REG);
OUT_BYTE(0xc2, IDE_HCYL_REG);
+ OUT_BYTE(args[2],IDE_FEATURE_REG);
+ OUT_BYTE(args[1],IDE_SECTOR_REG);
+ ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
+ return;
}
OUT_BYTE(args[2],IDE_FEATURE_REG);
ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
@@ -1218,13 +1257,37 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, unsigned long *hwgroup_flags
bdev->current_request = hwgroup->rq = drive->queue;
spin_unlock_irqrestore(&io_request_lock, io_flags);
+#if 0
if (hwif->irq != masked_irq)
- disable_irq(hwif->irq);
+ disable_irq_nosync(hwif->irq);
spin_unlock_irqrestore(&hwgroup->spinlock, *hwgroup_flags);
start_request(drive);
spin_lock_irqsave(&hwgroup->spinlock, *hwgroup_flags);
if (hwif->irq != masked_irq)
enable_irq(hwif->irq);
+#else
+
+ if (masked_irq && hwif->irq != masked_irq) {
+ printk("%s: (disable_irq) %smasked_irq %d\n",
+ drive->name,
+ masked_irq ? "" : "un_", hwif->irq);
+
+#if 0
+ disable_irq(hwif->irq);
+#else
+ disable_irq_nosync(hwif->irq);
+#endif
+ }
+ spin_unlock_irqrestore(&hwgroup->spinlock, *hwgroup_flags);
+ start_request(drive);
+ spin_lock_irqsave(&hwgroup->spinlock, *hwgroup_flags);
+ if (masked_irq && hwif->irq != masked_irq) {
+ printk("%s: (enable_irq) %smasked_irq %d\n",
+ drive->name,
+ masked_irq ? "" : "un_", hwif->irq);
+ enable_irq(hwif->irq);
+ }
+#endif
}
}
@@ -1373,8 +1436,8 @@ void ide_timer_expiry (unsigned long data)
}
hwgroup->busy = 1; /* should already be "1" */
hwgroup->handler = NULL;
- del_timer(&hwgroup->timer); /* Is this needed?? */
- if (hwgroup->poll_timeout != 0) { /* polling in progress? */
+ /* polling in progress or just don't timeout */
+ if (hwgroup->poll_timeout != 0) {
spin_unlock_irqrestore(&hwgroup->spinlock, flags);
handler(drive);
} else if (drive_is_ready(drive)) {
@@ -1612,8 +1675,10 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
}
spin_unlock_irqrestore(&io_request_lock, flags);
do_hwgroup_request(hwgroup);
- if (action == ide_wait && rq->rq_status != RQ_INACTIVE)
+ if (action == ide_wait) {
down(&sem); /* wait for it to be serviced */
+ rq->sem = NULL;
+ }
return rq->errors ? -EIO : 0; /* return -EIO if errors */
}
@@ -2270,8 +2335,13 @@ void ide_delay_50ms (void)
int ide_config_drive_speed (ide_drive_t *drive, byte speed)
{
+ struct hd_driveid *id = drive->id;
+ unsigned long flags;
int err;
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
+
/*
* Don't use ide_wait_cmd here - it will
* attempt to set_geometry and recalibrate,
@@ -2287,6 +2357,109 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed)
err = ide_wait_stat(drive, DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD);
+#if 0
+ if (IDE_CONTROL_REG)
+ OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
+#endif
+
+ __restore_flags(flags); /* local CPU only */
+
+ switch(speed) {
+ case XFER_UDMA_4:
+ if (!((id->dma_ultra >> 8) & 16)) {
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x1010;
+ }
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_UDMA_3:
+ if (!((id->dma_ultra >> 8) & 8)) {
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x0808;
+ }
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_UDMA_2:
+ if (!((id->dma_ultra >> 8) & 4)) {
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x0404;
+ }
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_UDMA_1:
+ if (!((id->dma_ultra >> 8) & 2)) {
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x0202;
+ }
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_UDMA_0:
+ if (!((id->dma_ultra >> 8) & 1)) {
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_ultra |= 0x0101;
+ }
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_MW_DMA_2:
+ drive->id->dma_ultra &= ~0xFF00;
+ if (!((id->dma_mword >> 8) & 4)) {
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_mword |= 0x0404;
+ }
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_MW_DMA_1:
+ drive->id->dma_ultra &= ~0xFF00;
+ if (!((id->dma_mword >> 8) & 2)) {
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_mword |= 0x0202;
+ }
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_MW_DMA_0:
+ drive->id->dma_ultra &= ~0xFF00;
+ if (!((id->dma_mword >> 8) & 1)) {
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_mword |= 0x0101;
+ }
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ case XFER_SW_DMA_2:
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_mword &= ~0x0F00;
+ if (!((id->dma_1word >> 8) & 4)) {
+ drive->id->dma_1word &= ~0x0F00;
+ drive->id->dma_1word |= 0x0404;
+ }
+ break;
+ case XFER_SW_DMA_1:
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_mword &= ~0x0F00;
+ if (!((id->dma_1word >> 8) & 2)) {
+ drive->id->dma_1word &= ~0x0F00;
+ drive->id->dma_1word |= 0x0202;
+ }
+ break;
+ case XFER_SW_DMA_0:
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_mword &= ~0x0F00;
+ if (!((id->dma_1word >> 8) & 1)) {
+ drive->id->dma_1word &= ~0x0F00;
+ drive->id->dma_1word |= 0x0101;
+ }
+ break;
+ default:
+ drive->id->dma_ultra &= ~0xFF00;
+ drive->id->dma_mword &= ~0x0F00;
+ drive->id->dma_1word &= ~0x0F00;
+ break;
+ }
+
return(err);
}
@@ -2803,7 +2976,7 @@ void __init ide_setup (char *s)
}
}
-#if defined(CONFIG_BLK_DEV_VIA82C586)
+#if defined(CONFIG_BLK_DEV_VIA82CXXX)
/*
* Look for drive option "splitfifo=..."
*/
@@ -2853,7 +3026,7 @@ void __init ide_setup (char *s)
fifoconfig = tmp;
goto done;
}
-#endif /* defined(CONFIG_BLK_DEV_VIA82C586) */
+#endif /* defined(CONFIG_BLK_DEV_VIA82CXXX) */
if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e')
goto bad_option;
@@ -3393,6 +3566,7 @@ EXPORT_SYMBOL(do_ide9_request);
EXPORT_SYMBOL(ide_scan_devices);
EXPORT_SYMBOL(ide_register_subdriver);
EXPORT_SYMBOL(ide_unregister_subdriver);
+EXPORT_SYMBOL(ide_replace_subdriver);
EXPORT_SYMBOL(ide_input_data);
EXPORT_SYMBOL(ide_output_data);
EXPORT_SYMBOL(atapi_input_bytes);
@@ -3464,7 +3638,11 @@ static void __init parse_options (char *line)
while ((line = next) != NULL) {
if ((next = strchr(line,' ')) != NULL)
*next++ = 0;
- if (!strncmp(line,"ide",3) || (!strncmp(line,"hd",2) && line[2] != '='))
+ if (!strncmp(line,"ide",3) ||
+#ifdef CONFIG_BLK_DEV_VIA82CXXX
+ !strncmp(line,"splitfifo",9) ||
+#endif /* CONFIG_BLK_DEV_VIA82CXXX */
+ (!strncmp(line,"hd",2) && line[2] != '='))
ide_setup(line);
}
}
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 0114dd8ec..9366a8856 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -416,10 +416,6 @@ void make_request(int major,int rw, struct buffer_head * bh)
count = bh->b_size >> 9;
sector = bh->b_rsector;
- /* We'd better have a real physical mapping! */
- if (!buffer_mapped(bh))
- BUG();
-
/* It had better not be a new buffer by the time we see it */
if (buffer_new(bh))
BUG();
@@ -480,6 +476,13 @@ void make_request(int major,int rw, struct buffer_head * bh)
goto end_io;
}
+ /* We'd better have a real physical mapping!
+ Check this bit only if the buffer was dirty and just locked
+ down by us so at this point flushpage will block and
+ won't clear the mapped bit under us. */
+ if (!buffer_mapped(bh))
+ BUG();
+
/* look for a free request. */
/* Loop uses two requests, 1 for loop and 1 for the real device.
* Cut max_req in half to avoid running out and deadlocking. */
@@ -694,7 +697,7 @@ void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
sorry:
for (i = 0; i < nr; i++) {
- clear_bit(BH_Dirty, &bh[i]->b_state);
+ mark_buffer_clean(bh[i]); /* remeber to refile it */
clear_bit(BH_Uptodate, &bh[i]->b_state);
bh[i]->b_end_io(bh[i], 0);
}
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 027517320..96e0e421e 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -214,8 +214,11 @@ static int pcd_drive_reset(struct cdrom_device_info *cdi);
static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
unsigned int cmd, void *arg);
+static int pcd_packet(struct cdrom_device_info *cdi,
+ struct cdrom_generic_command *cgc);
static int pcd_detect(void);
+static void pcd_probe_capabilities(void);
static void do_pcd_read_drq(void);
static void do_pcd_request(void);
static void do_pcd_read(void);
@@ -276,14 +279,18 @@ static struct cdrom_device_ops pcd_dops = {
pcd_drive_reset,
pcd_audio_ioctl,
0, /* dev_ioctl */
- CDC_CLOSE_TRAY |
- CDC_OPEN_TRAY |
- CDC_LOCK |
- CDC_MCN |
- CDC_MEDIA_CHANGED |
- CDC_RESET |
- CDC_PLAY_AUDIO,
- 0
+ CDC_CLOSE_TRAY |
+ CDC_OPEN_TRAY |
+ CDC_LOCK |
+ CDC_MCN |
+ CDC_MEDIA_CHANGED |
+ CDC_RESET |
+ CDC_PLAY_AUDIO |
+ CDC_GENERIC_PACKET |
+ CDC_CD_R |
+ CDC_CD_RW,
+ 0,
+ pcd_packet,
};
static void pcd_init_units( void )
@@ -325,6 +332,9 @@ int pcd_init (void) /* preliminary initialisation */
if (pcd_detect()) return -1;
+ /* get the atapi capabilities page */
+ pcd_probe_capabilities();
+
if (register_blkdev(MAJOR_NR,name,&cdrom_fops)) {
printk("pcd: unable to get major number %d\n",MAJOR_NR);
return -1;
@@ -525,6 +535,16 @@ static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
return r;
}
+static int pcd_packet(struct cdrom_device_info *cdi,
+ struct cdrom_generic_command *cgc)
+{
+ char *un_cmd;
+ int unit = DEVICE_NR(cdi->dev);
+
+ un_cmd = cgc->cmd;
+ return pcd_atapi(unit,un_cmd,cgc->buflen,cgc->buffer, "generic packet");
+}
+
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
@@ -667,6 +687,32 @@ static int pcd_probe( int unit, int ms, char * id )
return -1;
}
+static void pcd_probe_capabilities( void )
+
+{ int unit, r;
+ char buffer[32];
+ char cmd[12]={0x5a,1<<3,0x2a,0,0,0,0,18,0,0,0,0};
+
+ for (unit=0;unit<PCD_UNITS;unit++) {
+ if (!PCD.present) continue;
+ r = pcd_atapi(unit,cmd,18, buffer,"mode sense capabilities");
+ if (r) continue;
+ /* we should now have the cap page */
+ if ((buffer[11] & 1) == 0)
+ PCD.info.mask |= CDC_CD_R;
+ if ((buffer[11] & 2) == 0)
+ PCD.info.mask |= CDC_CD_RW;
+ if ((buffer[12] & 1) == 0)
+ PCD.info.mask |= CDC_PLAY_AUDIO;
+ if ((buffer[14] & 1) == 0)
+ PCD.info.mask |= CDC_LOCK;
+ if ((buffer[14] & 8) == 0)
+ PCD.info.mask |= CDC_OPEN_TRAY;
+ if ((buffer[14] >> 6) == 0)
+ PCD.info.mask |= CDC_CLOSE_TRAY;
+ }
+}
+
static int pcd_detect( void )
{ char id[18];
@@ -836,63 +882,6 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
switch (cmd) {
- case CDROMPAUSE:
-
- { char cmd[12]={GPCMD_PAUSE_RESUME,0,0,0,0,0,0,0,0,0,0,0};
-
- return (pcd_atapi(unit,cmd,0,NULL,"pause")) * EIO;
- }
-
- case CDROMRESUME:
-
- { char cmd[12]={GPCMD_PAUSE_RESUME,0,0,0,0,0,0,0,1,0,0,0};
-
- return (pcd_atapi(unit,cmd,0,NULL,"resume")) * EIO;
- }
-
- case CDROMPLAYMSF:
-
- { char cmd[12]={GPCMD_PLAY_AUDIO_MSF,0,0,0,0,0,0,0,0,0,0,0};
- struct cdrom_msf* msf = (struct cdrom_msf*)arg;
-
- cmd[3] = msf->cdmsf_min0;
- cmd[4] = msf->cdmsf_sec0;
- cmd[5] = msf->cdmsf_frame0;
- cmd[6] = msf->cdmsf_min1;
- cmd[7] = msf->cdmsf_sec1;
- cmd[8] = msf->cdmsf_frame1;
-
- return (pcd_atapi(unit,cmd,0,NULL,"play msf")) * EIO;
- }
-
- case CDROMPLAYBLK:
-
- { char cmd[12]={GPCMD_PLAY_AUDIO_10,0,0,0,0,0,0,0,0,0,0,0};
- struct cdrom_blk* blk = (struct cdrom_blk*)arg;
-
- cmd[2] = blk->from >> 24;
- cmd[3] = blk->from >> 16;
- cmd[4] = blk->from >> 8;
- cmd[5] = blk->from;
- cmd[7] = blk->len >> 8;
- cmd[8] = blk->len;
-
- return (pcd_atapi(unit,cmd,0,NULL,"play block")) * EIO;
- }
-
- case CDROMPLAYTRKIND:
-
- { char cmd[12]={GPCMD_PLAYAUDIO_TI,0,0,0,0,0,0,0,0,0,0,0};
- struct cdrom_ti* ti = (struct cdrom_ti*)arg;
-
- cmd[4] = ti->cdti_trk0;
- cmd[5] = ti->cdti_ind0;
- cmd[7] = ti->cdti_trk1;
- cmd[8] = ti->cdti_ind1;
-
- return (pcd_atapi(unit,cmd,0,NULL,"play track")) * EIO;
- }
-
case CDROMREADTOCHDR:
{ char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
@@ -936,97 +925,6 @@ static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
return r * EIO;
}
- case CDROMSTOP:
-
- { char cmd[12]={GPCMD_START_STOP_UNIT,1,0,0,0,0,0,0,0,0,0,0};
-
- return (pcd_atapi(unit,cmd,0,NULL,"stop")) * EIO;
- }
-
- case CDROMSTART:
-
- { char cmd[12]={GPCMD_START_STOP_UNIT,1,0,0,1,0,0,0,0,0,0,0};
-
- return (pcd_atapi(unit,cmd,0,NULL,"start")) * EIO;
- }
-
- case CDROMVOLCTRL:
-
- { char cmd[12]={GPCMD_MODE_SENSE_10,0,0,0,0,0,0,0,0,0,0,0};
- char buffer[32];
- char mask[32];
- struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
-
- cmd[2] = 0xe;
- cmd[4] = 28;
-
- if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol"))
- return -EIO;
-
- cmd[2] = 0x4e;
-
- if (pcd_atapi(unit,cmd,28,buffer,"mode sense vol mask"))
- return -EIO;
-
- buffer[0] = 0;
-
- buffer[21] = volctrl->channel0 & mask[21];
- buffer[23] = volctrl->channel1 & mask[23];
- buffer[25] = volctrl->channel2 & mask[25];
- buffer[27] = volctrl->channel3 & mask[27];
-
- cmd[0] = 0x55;
- cmd[1] = 0x10;
-
- return pcd_atapi(unit,cmd,28,buffer,"mode select vol") * EIO;
- }
-
- case CDROMVOLREAD:
-
- { char cmd[12]={GPCMD_MODE_SENSE_10,0,0,0,0,0,0,0,0,0,0,0};
- char buffer[32];
- struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
- int r;
-
- cmd[2] = 0xe;
- cmd[4] = 28;
-
- r = pcd_atapi(unit,cmd,28,buffer,"mode sense vol read");
-
- volctrl->channel0 = buffer[21];
- volctrl->channel1 = buffer[23];
- volctrl->channel2 = buffer[25];
- volctrl->channel3 = buffer[27];
-
- return r * EIO;
- }
-
-
- case CDROMSUBCHNL:
-
- { char cmd[12]={GPCMD_READ_SUBCHANNEL,2,0x40,1,0,0,0,0,16,0,0,0};
- struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg;
- char buffer[32];
-
- if (pcd_atapi(unit,cmd,16,buffer,"read subchannel"))
- return -EIO;
-
- subchnl->cdsc_audiostatus = buffer[1];
- subchnl->cdsc_format = CDROM_MSF;
- subchnl->cdsc_ctrl = buffer[5] & 0xf;
- subchnl->cdsc_trk = buffer[6];
- subchnl->cdsc_ind = buffer[7];
-
- subchnl->cdsc_reladdr.msf.minute = buffer[13];
- subchnl->cdsc_reladdr.msf.second = buffer[14];
- subchnl->cdsc_reladdr.msf.frame = buffer[15];
- subchnl->cdsc_absaddr.msf.minute = buffer[9];
- subchnl->cdsc_absaddr.msf.second = buffer[10];
- subchnl->cdsc_absaddr.msf.frame = buffer[11];
-
- return 0;
- }
-
default:
return -ENOSYS;
diff --git a/drivers/block/pdc202xx.c b/drivers/block/pdc202xx.c
index aeffcc9ba..2155aa8af 100644
--- a/drivers/block/pdc202xx.c
+++ b/drivers/block/pdc202xx.c
@@ -1,8 +1,8 @@
/*
- * linux/drivers/block/pdc202xx.c Version 0.26 May 12, 1999
+ * linux/drivers/block/pdc202xx.c Version 0.27 Sept. 3, 1999
*
- * Copyright (C) 1998-99 Andre Hedrick
- * (hedrick@astro.dyer.vanderbilt.edu)
+ * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
* Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
* compiled into the kernel if you have more than one card installed.
@@ -72,6 +72,12 @@
* = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
*/
+/*
+ * Portions Copyright (C) 1999 Promise Technology, Inc.
+ * Author: Frank Tiernan (frankt@promise.com)
+ * Released under terms of General Public License
+ */
+
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
@@ -88,6 +94,8 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include "ide_modes.h"
+
#define PDC202XX_DEBUG_DRIVE_INFO 0
#define PDC202XX_DECODE_REGISTER_INFO 0
@@ -208,27 +216,78 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
+ unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK;
int err;
unsigned int drive_conf;
byte drive_pci;
- byte test1, test2, speed;
- byte AP, BP, CP, DP, EP;
+ byte test1, test2, speed = -1;
+ byte AP, BP, CP, DP, TB, TC;
+ unsigned short EP;
+ byte CLKSPD = IN_BYTE(high_16 + 0x11);
int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
byte udma_66 = ((id->word93 & 0x2000) && (hwif->udma_four)) ? 1 : 0;
- byte udma_33 = ultra ? (inb((dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK) + 0x001f) & 1) : 0;
-
- pci_read_config_byte(dev, 0x50, &EP);
+ byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0;
+
+ /*
+ * Set the control register to use the 66Mhz system
+ * clock for UDMA 3/4 mode operation. If one drive on
+ * a channel is U66 capable but the other isn't we
+ * fall back to U33 mode. The BIOS INT 13 hooks turn
+ * the clock on then off for each read/write issued. I don't
+ * do that here because it would require modifying the
+ * kernel, seperating the fop routines from the kernel or
+ * somehow hooking the fops calls. It may also be possible to
+ * leave the 66Mhz clock on and readjust the timing
+ * parameters.
+ */
+
+ byte mask = hwif->channel ? 0x08 : 0x02;
+ unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10);
+ byte ultra_66 = ((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008)) ? 1 : 0;
+
+ pci_read_config_word(dev, 0x50, &EP);
+
+ if ((ultra_66) && (EP & c_mask)) {
+#ifdef DEBUG
+ printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary", "Primary");
+ printk(" Switching to Ultra33 mode.\n");
+#endif /* DEBUG */
+ /* Primary : zero out second bit */
+ /* Secondary : zero out fourth bit */
+ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
+ } else {
+ if (ultra_66) {
+ /*
+ * check to make sure drive on same channel
+ * is u66 capable
+ */
+ if (hwif->drives[!(drive_number%2)].id) {
+ if ((hwif->drives[!(drive_number%2)].id->dma_ultra & 0x0010) ||
+ (hwif->drives[!(drive_number%2)].id->dma_ultra & 0x0008)) {
+ OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
+ } else {
+ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
+ }
+ } else { /* udma4 drive by itself */
+ OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
+ }
+ }
+ }
switch(drive_number) {
case 0: drive_pci = 0x60;
pci_read_config_dword(dev, drive_pci, &drive_conf);
+ if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
+ goto chipset_is_set;
pci_read_config_byte(dev, (drive_pci), &test1);
if (!(test1 & SYNC_ERRDY_EN))
pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN);
break;
case 1: drive_pci = 0x64;
pci_read_config_dword(dev, drive_pci, &drive_conf);
+ if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
+ goto chipset_is_set;
pci_read_config_byte(dev, 0x60, &test1);
pci_read_config_byte(dev, (drive_pci), &test2);
if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN))
@@ -236,12 +295,16 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
break;
case 2: drive_pci = 0x68;
pci_read_config_dword(dev, drive_pci, &drive_conf);
+ if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
+ goto chipset_is_set;
pci_read_config_byte(dev, (drive_pci), &test1);
if (!(test1 & SYNC_ERRDY_EN))
pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN);
break;
case 3: drive_pci = 0x6c;
pci_read_config_dword(dev, drive_pci, &drive_conf);
+ if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
+ goto chipset_is_set;
pci_read_config_byte(dev, 0x68, &test1);
pci_read_config_byte(dev, (drive_pci), &test2);
if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN))
@@ -251,6 +314,8 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
return ide_dma_off;
}
+chipset_is_set:
+
if (drive->media != ide_disk)
return ide_dma_off_quietly;
@@ -285,127 +350,46 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) {
- if (!((id->dma_ultra >> 8) & 16)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x1010;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 8 == UDMA mode 4 == speed 6 plus cable */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x20);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x01);
- speed = XFER_UDMA_4;
+ speed = XFER_UDMA_4; TB = 0x20; TC = 0x01;
} else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) {
- if (!((id->dma_ultra >> 8) & 8)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0808;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 7 == UDMA mode 3 == speed 5 plus cable */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x40);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x02);
- speed = XFER_UDMA_3;
+ speed = XFER_UDMA_3; TB = 0x40; TC = 0x02;
} else if ((id->dma_ultra & 0x0004) && (udma_33)) {
- if (!((id->dma_ultra >> 8) & 4)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 6 == UDMA mode 2 */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x20);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x01);
- speed = XFER_UDMA_2;
+ speed = XFER_UDMA_2; TB = 0x20; TC = 0x01;
} else if ((id->dma_ultra & 0x0002) && (udma_33)) {
- if (!((id->dma_ultra >> 8) & 2)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 5 == UDMA mode 1 */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x40);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x02);
- speed = XFER_UDMA_1;
+ speed = XFER_UDMA_1; TB = 0x40; TC = 0x02;
} else if ((id->dma_ultra & 0x0001) && (udma_33)) {
- if (!((id->dma_ultra >> 8) & 1)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 4 == UDMA mode 0 */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x03);
- speed = XFER_UDMA_0;
+ speed = XFER_UDMA_0; TB = 0x60; TC = 0x03;
} else if (id->dma_mword & 0x0004) {
- if (!((id->dma_mword >> 8) & 4)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0404;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 4 == DMA mode 2 multi-word */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x03);
- speed = XFER_MW_DMA_2;
+ speed = XFER_MW_DMA_2; TB = 0x60; TC = 0x03;
} else if (id->dma_mword & 0x0002) {
- if (!((id->dma_mword >> 8) & 2)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0202;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 3 == DMA mode 1 multi-word */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x04);
- speed = XFER_MW_DMA_1;
+ speed = XFER_MW_DMA_1; TB = 0x60; TC = 0x04;
} else if (id->dma_mword & 0x0001) {
- if (!((id->dma_mword >> 8) & 1)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0101;
- drive->id->dma_1word &= ~0x0F00;
- }
/* speed 2 == DMA mode 0 multi-word */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x05);
- speed = XFER_MW_DMA_0;
+ speed = XFER_MW_DMA_0; TB = 0x60; TC = 0x05;
} else if (id->dma_1word & 0x0004) {
- if (!((id->dma_1word >> 8) & 4)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0404;
- }
/* speed 2 == DMA mode 2 single-word */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x60);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x05);
- speed = XFER_SW_DMA_2;
+ speed = XFER_SW_DMA_2; TB = 0x60; TC = 0x05;
} else if (id->dma_1word & 0x0002) {
- if (!((id->dma_1word >> 8) & 2)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0202;
- }
/* speed 1 == DMA mode 1 single-word */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0x80);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x06);
- speed = XFER_SW_DMA_1;
+ speed = XFER_SW_DMA_1; TB = 0x80; TC = 0x06;
} else if (id->dma_1word & 0x0001) {
- if (!((id->dma_1word >> 8) & 1)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0101;
- }
/* speed 0 == DMA mode 0 single-word */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|0xC0);
- pci_write_config_byte(dev, (drive_pci)|0x02, CP|0x0B);
- speed = XFER_SW_DMA_0;
+ speed = XFER_SW_DMA_0; TB = 0xC0; TC = 0x0B;
} else {
/* restore original pci-config space */
pci_write_config_dword(dev, drive_pci, drive_conf);
return ide_dma_off_quietly;
}
- err = ide_config_drive_speed(drive, speed);
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
+ pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
#if PDC202XX_DECODE_REGISTER_INFO
pci_read_config_byte(dev, (drive_pci), &AP);
@@ -418,6 +402,8 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
decode_registers(REG_D, DP);
#endif /* PDC202XX_DECODE_REGISTER_INFO */
+ err = ide_config_drive_speed(drive, speed);
+
#if PDC202XX_DEBUG_DRIVE_INFO
printk("%s: %s drive%d 0x%08x ",
drive->name, ide_xfer_verbose(speed),
@@ -441,6 +427,83 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
* 11, 5, 4, 3, 2, 1, 0
*/
+static int config_chipset_for_pio (ide_drive_t *drive, byte pio)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ byte drive_pci, speed;
+ byte AP, BP, TA, TB;
+
+ int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
+ int err;
+
+ switch (drive_number) {
+ case 0: drive_pci = 0x60; break;
+ case 1: drive_pci = 0x64; break;
+ case 2: drive_pci = 0x68; break;
+ case 3: drive_pci = 0x6c; break;
+ default: return 1;
+ }
+
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+
+
+ if ((AP & 0x0F) || (BP & 0x07)) {
+ /* clear PIO modes of lower 8421 bits of A Register */
+ pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
+ pci_read_config_byte(dev, (drive_pci), &AP);
+
+ /* clear PIO modes of lower 421 bits of B Register */
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+ }
+
+ pio = (pio == 5) ? 4 : pio;
+ switch (ide_get_best_pio_mode(drive, 255, pio, NULL)) {
+ case 4: speed = XFER_PIO_4; TA=0x01; TB=0x04; break;
+ case 3: speed = XFER_PIO_3; TA=0x02; TB=0x06; break;
+ case 2: speed = XFER_PIO_2; TA=0x03; TB=0x08; break;
+ case 1: speed = XFER_PIO_1; TA=0x05; TB=0x0C; break;
+ case 0:
+ default: speed = XFER_PIO_0; TA=0x09; TB=0x13; break;
+ }
+ pci_write_config_byte(dev, (drive_pci), AP|TA);
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
+
+#if PDC202XX_DECODE_REGISTER_INFO
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+ pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+ pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
+
+ decode_registers(REG_A, AP);
+ decode_registers(REG_B, BP);
+ decode_registers(REG_C, CP);
+ decode_registers(REG_D, DP);
+#endif /* PDC202XX_DECODE_REGISTER_INFO */
+
+ err = ide_config_drive_speed(drive, speed);
+
+#if PDC202XX_DEBUG_DRIVE_INFO
+ printk("%s: %s drive%d 0x%08x ",
+ drive->name, ide_xfer_verbose(speed),
+ drive_number, drive_conf);
+ pci_read_config_dword(dev, drive_pci, &drive_conf);
+ printk("0x%08x\n", drive_conf);
+#endif /* PDC202XX_DEBUG_DRIVE_INFO */
+
+ return err;
+}
+
+static void pdc202xx_tune_drive (ide_drive_t *drive, byte pio)
+{
+ (void) config_chipset_for_pio(drive, pio);
+}
+
static int config_drive_xfer_rate (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
@@ -450,9 +513,10 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
if (id && (id->capability & 1) && hwif->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive)) {
- return HWIF(drive)->dmaproc(ide_dma_off, drive);
+ dma_func = ide_dma_off;
+ goto fast_ata_pio;
}
-
+ dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
if (id->dma_ultra & 0x001F) {
/* Force if Capable UltraDMA */
@@ -463,17 +527,31 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
}
} else if (id->field_valid & 2) {
try_dma_modes:
- if ((id->dma_mword & 0x0004) ||
- (id->dma_1word & 0x0004)) {
+ if ((id->dma_mword & 0x0007) ||
+ (id->dma_1word & 0x0007)) {
/* Force if Capable regular DMA modes */
dma_func = config_chipset_for_dma(drive, 0);
+ if (dma_func != ide_dma_on)
+ goto no_dma_set;
+ }
+ } else if (ide_dmaproc(ide_dma_good_drive, drive)) {
+ if (id->eide_dma_time > 150) {
+ goto no_dma_set;
}
- } else if ((ide_dmaproc(ide_dma_good_drive, drive)) &&
- (id->eide_dma_time > 150)) {
/* Consult the list of known "good" drives */
dma_func = config_chipset_for_dma(drive, 0);
+ if (dma_func != ide_dma_on)
+ goto no_dma_set;
+ } else {
+ goto fast_ata_pio;
}
+ } else if ((id->capability & 8) || (id->field_valid & 2)) {
+fast_ata_pio:
+ dma_func = ide_dma_off_quietly;
+no_dma_set:
+ (void) config_chipset_for_pio(drive, 5);
}
+
return HWIF(drive)->dmaproc(dma_func, drive);
}
@@ -498,6 +576,26 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
byte primary_mode = inb(high_16 + 0x001a);
byte secondary_mode = inb(high_16 + 0x001b);
+ if (dev->device == PCI_DEVICE_ID_PROMISE_20262) {
+ int i = 0;
+ /*
+ * software reset - this is required because the bios
+ * will set UDMA timing on if the hdd supports it. The
+ * user may want to turn udma off. A bug in the pdc20262
+ * is that it cannot handle a downgrade in timing from UDMA
+ * to DMA. Disk accesses after issuing a set feature command
+ * will result in errors. A software reset leaves the timing
+ * registers intact, but resets the drives.
+ */
+
+ OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
+ ide_delay_50ms();
+ ide_delay_50ms();
+ OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
+ for (i=0; i<40; i++)
+ ide_delay_50ms();
+ }
+
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("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
@@ -547,24 +645,23 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
return dev->irq;
}
+unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
+{
+ unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10);
+ unsigned short CIS;
+
+ pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
+ return ((CIS & mask) ? 0 : 1);
+}
+
void __init ide_init_pdc202xx (ide_hwif_t *hwif)
{
+ hwif->tuneproc = &pdc202xx_tune_drive;
+
if (hwif->dma_base) {
hwif->dmaproc = &pdc202xx_dmaproc;
-
- switch(hwif->pci_dev->device) {
- case PCI_DEVICE_ID_PROMISE_20262:
-#if 0
- {
- unsigned long high_16 = hwif->pci_dev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK;
- hwif->udma_four = 1;
- }
-#endif
- break;
- case PCI_DEVICE_ID_PROMISE_20246:
- default:
- hwif->udma_four = 0;
- break;
- }
+ } else {
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
}
}
diff --git a/drivers/block/pdc4030.c b/drivers/block/pdc4030.c
index 84fbb4856..080d353a5 100644
--- a/drivers/block/pdc4030.c
+++ b/drivers/block/pdc4030.c
@@ -162,6 +162,7 @@ int __init setup_pdc4030 (ide_hwif_t *hwif)
if (!hwif) return 0;
drive = &hwif->drives[0];
+ drive->timeout = HZ/100;
hwif2 = &ide_hwifs[hwif->index+1];
if (hwif->chipset == ide_pdc4030) /* we've already been found ! */
return 1;
@@ -169,7 +170,8 @@ int __init setup_pdc4030 (ide_hwif_t *hwif)
if (IN_BYTE(IDE_NSECTOR_REG) == 0xFF || IN_BYTE(IDE_SECTOR_REG) == 0xFF) {
return 0;
}
- OUT_BYTE(0x08,IDE_CONTROL_REG);
+ if (IDE_CONTROL_REG)
+ OUT_BYTE(0x08,IDE_CONTROL_REG);
if (pdc4030_cmd(drive,PROMISE_GET_CONFIG)) {
return 0;
}
@@ -307,6 +309,9 @@ static void promise_read_intr (ide_drive_t *drive)
unsigned int sectors_left, sectors_avail, nsect;
struct request *rq;
+ /* reset timeout */
+ drive->timeout = HZ/100;
+
if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
ide_error(drive, "promise_read_intr", stat);
return;
@@ -361,7 +366,8 @@ read_next:
if (stat & DRQ_STAT)
goto read_again;
if (stat & BUSY_STAT) {
- ide_set_handler (drive, &promise_read_intr, WAIT_CMD);
+ drive->timeout = WAIT_CMD;
+ ide_set_handler (drive, &promise_read_intr);
#ifdef DEBUG_READ
printk(KERN_DEBUG "%s: promise_read: waiting for"
"interrupt\n", drive->name);
@@ -390,7 +396,7 @@ static void promise_complete_pollfunc(ide_drive_t *drive)
if (GET_STAT() & BUSY_STAT) {
if (time_before(jiffies, hwgroup->poll_timeout)) {
- ide_set_handler(drive, &promise_complete_pollfunc, 1);
+ ide_set_handler(drive, &promise_complete_pollfunc);
return; /* continue polling... */
}
hwgroup->poll_timeout = 0;
@@ -419,7 +425,7 @@ static void promise_write_pollfunc (ide_drive_t *drive)
if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
if (time_before(jiffies, hwgroup->poll_timeout)) {
- ide_set_handler (drive, &promise_write_pollfunc, 1);
+ ide_set_handler (drive, &promise_write_pollfunc);
return; /* continue polling... */
}
hwgroup->poll_timeout = 0;
@@ -433,7 +439,7 @@ static void promise_write_pollfunc (ide_drive_t *drive)
*/
ide_multwrite(drive, 4);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler(drive, &promise_complete_pollfunc, 1);
+ ide_set_handler(drive, &promise_complete_pollfunc);
#ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
drive->name, GET_STAT());
@@ -466,7 +472,7 @@ static void promise_write (ide_drive_t *drive)
if (rq->nr_sectors > 4) {
ide_multwrite(drive, rq->nr_sectors - 4);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler (drive, &promise_write_pollfunc, 1);
+ ide_set_handler (drive, &promise_write_pollfunc);
} else {
/*
* There are 4 or fewer sectors to transfer, do them all in one go
@@ -474,7 +480,7 @@ static void promise_write (ide_drive_t *drive)
*/
ide_multwrite(drive, rq->nr_sectors);
hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler(drive, &promise_complete_pollfunc, 1);
+ ide_set_handler(drive, &promise_complete_pollfunc);
#ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
"status = %02x\n", drive->name, GET_STAT());
@@ -517,7 +523,8 @@ void do_pdc4030_io (ide_drive_t *drive, struct request *rq)
printk(KERN_DEBUG "%s: read: waiting for "
"interrupt\n", drive->name);
#endif
- ide_set_handler(drive, &promise_read_intr, WAIT_CMD);
+ drive->timeout = WAIT_CMD;
+ ide_set_handler(drive, &promise_read_intr);
return;
}
udelay(1);
diff --git a/drivers/block/piix.c b/drivers/block/piix.c
index b1fd76014..a9bcb347c 100644
--- a/drivers/block/piix.c
+++ b/drivers/block/piix.c
@@ -1,8 +1,9 @@
/*
- * linux/drivers/block/piix.c Version 0.25 July 11, 1999
+ * linux/drivers/block/piix.c Version 0.27 Sept. 3, 1999
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
- * Copyright (C) 1998-1999 Andre Hedrick, Author and Maintainer
+ * Copyright (C) 1998-1999 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
* PIO mode setting function for Intel chipsets.
* For use instead of BIOS settings.
@@ -182,30 +183,13 @@ static int piix_config_drive_for_dma(ide_drive_t *drive)
}
}
- if ((id->dma_ultra & 0x0010) && (ultra)) {
- goto backspeed;
- } else if ((id->dma_ultra & 0x0008) && (ultra)) {
- goto backspeed;
- } else if ((id->dma_ultra & 0x0004) && (ultra)) {
-backspeed:
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- if (!((id->dma_ultra >> 8) & 4)) {
- drive->id->dma_ultra &= ~0x0F00;
- drive->id->dma_ultra |= 0x0404;
- }
+ if (((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008) || (id->dma_ultra & 0x0004)) && (ultra)) {
u_speed = 2 << (drive_number * 4);
if (!(reg4a & u_speed)) {
pci_write_config_word(dev, 0x4a, reg4a|u_speed);
}
speed = XFER_UDMA_2;
} else if ((id->dma_ultra & 0x0002) && (ultra)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- if (!((id->dma_ultra >> 8) & 2)) {
- drive->id->dma_ultra &= ~0x0F00;
- drive->id->dma_ultra |= 0x0202;
- }
u_speed = 1 << (drive_number * 4);
if (!(reg4a & u_speed)) {
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
@@ -213,12 +197,6 @@ backspeed:
}
speed = XFER_UDMA_1;
} else if ((id->dma_ultra & 0x0001) && (ultra)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- if (!((id->dma_ultra >> 8) & 1)) {
- drive->id->dma_ultra &= ~0x0F00;
- drive->id->dma_ultra |= 0x0101;
- }
u_speed = 0 << (drive_number * 4);
if (!(reg4a & u_speed)) {
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
@@ -228,32 +206,14 @@ backspeed:
} else if (id->dma_mword & 0x0004) {
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- drive->id->dma_ultra &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- if (!((id->dma_mword >> 8) & 4)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0404;
- }
speed = XFER_MW_DMA_2;
} else if (id->dma_mword & 0x0002) {
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- drive->id->dma_ultra &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- if (!((id->dma_mword >> 8) & 2)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0202;
- }
speed = XFER_MW_DMA_1;
} else if (id->dma_1word & 0x0004) {
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
- drive->id->dma_ultra &= ~0x0F00;
- drive->id->dma_mword &= ~0x0F00;
- if (!((id->dma_1word >> 8) & 4)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0404;
- }
speed = XFER_SW_DMA_2;
} else {
speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
@@ -264,10 +224,7 @@ backspeed:
(void) ide_config_drive_speed(drive, speed);
#if PIIX_DEBUG_DRIVE_INFO
- printk("%s: %s drive%d ",
- drive->name,
- ide_xfer_verbose(speed),
- drive_number);
+ printk("%s: %s drive%d ", drive->name, ide_xfer_verbose(speed), drive_number);
printk("\n");
#endif /* PIIX_DEBUG_DRIVE_INFO */
@@ -291,7 +248,7 @@ static int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
}
#endif /* CONFIG_BLK_DEV_PIIX_TUNING */
-void ide_init_piix (ide_hwif_t *hwif)
+void __init ide_init_piix (ide_hwif_t *hwif)
{
hwif->tuneproc = &piix_tune_drive;
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 7aeb3a30f..7c2b23dab 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -704,8 +704,9 @@ void __init initrd_load(void)
#define OF(args) args
+#ifndef memzero
#define memzero(s, n) memset ((s), 0, (n))
-
+#endif
typedef unsigned char uch;
typedef unsigned short ush;
diff --git a/drivers/block/sis5513.c b/drivers/block/sis5513.c
index 08bbb1c91..8a3abd025 100644
--- a/drivers/block/sis5513.c
+++ b/drivers/block/sis5513.c
@@ -1,11 +1,11 @@
/*
- * linux/drivers/block/sis5513.c Version 0.06 July 11, 1999
+ * linux/drivers/block/sis5513.c Version 0.07 Sept. 3, 1999
*
- * Copyright (C) 1999 Andre Hedrick
+ * Copyright (C) 1999 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
- * drive_number
- * = ((HWIF(drive)->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
- * = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
+ * Thanks to SIS Taiwan for direct support and hardware.
+ * Tested and designed on the SiS620/5513 chipset.
*/
#include <linux/types.h>
@@ -27,10 +27,178 @@
#include "ide_modes.h"
+#define SIS5513_DEBUG_DRIVE_INFO 0
+
+#define DISPLAY_SIS_TIMINGS
+
static struct pci_dev *host_dev;
-#define SIS5513_DEBUG_DRIVE_INFO 0
+#if 0
+static struct _pio_mode_mapping {
+ byte data_active;
+ byte recovery;
+ byte pio_mode;
+} pio_mode_mapping[] = {
+ { 8, 12, 0 },
+ { 6, 7, 1 },
+ { 4, 4, 2 },
+ { 3, 3, 3 },
+ { 3, 1, 4 }
+};
+
+static struct _dma_mode_mapping {
+ byte data_active;
+ byte recovery;
+ byte dma_mode;
+} dma_mode_mapping[] = {
+ { 8, 8, 0 },
+ { 3, 2, 1 },
+ { 3, 1, 2 }
+};
+
+static struct _udma_mode_mapping {
+ byte cycle_time;
+ char * udma_mode;
+} udma_mode_mapping[] = {
+ { 8, "Mode 0" },
+ { 6, "Mode 1" },
+ { 4, "Mode 2" },
+ { 3, "Mode 3" },
+ { 2, "Mode 4" },
+ { 0, "Undefined" }
+};
+
+static __inline__ char * find_udma_mode (byte cycle_time)
+{
+ int n;
+
+ for (n = 0; n <= 4; n++)
+ if (udma_mode_mapping[n].cycle_time <= cycle_time)
+ return udma_mode_mapping[n].udma_mode;
+ return udma_mode_mapping[4].udma_mode;
+}
+#endif
+
+#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int sis_get_info(char *, char **, off_t, int, int);
+extern int (*sis_display_info)(char *, char **, off_t, int, int); /* ide-proc.c */
+struct pci_dev *bmide_dev;
+
+static char *cable_type[] = {
+ "80 pins",
+ "40 pins"
+};
+
+static char *recovery_time [] ={
+ "12 PCICLK", "1 PCICLK",
+ "2 PCICLK", "3 PCICLK",
+ "4 PCICLK", "5 PCICLCK",
+ "6 PCICLK", "7 PCICLCK",
+ "8 PCICLK", "9 PCICLCK",
+ "10 PCICLK", "11 PCICLK",
+ "13 PCICLK", "14 PCICLK",
+ "15 PCICLK", "15 PCICLK"
+};
+
+static char *cycle_time [] = {
+ "Undefined", "2 CLCK",
+ "3 CLK", "4 CLK",
+ "5 CLK", "6 CLK",
+ "7 CLK", "8 CLK"
+};
+
+static char *active_time [] = {
+ "8 PCICLK", "1 PCICLCK",
+ "2 PCICLK", "2 PCICLK",
+ "4 PCICLK", "5 PCICLK",
+ "6 PCICLK", "12 PCICLK"
+};
+
+static int sis_get_info (char *buffer, char **addr, off_t offset, int count, int dummy)
+{
+ int rc;
+ char *p = buffer;
+ byte reg,reg1;
+#if 0
+ byte cyc, rec, act;
+#endif
+ u16 reg2, reg3;
+
+ p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+ rc = pci_read_config_byte(bmide_dev, 0x4a, &reg);
+ p += sprintf(p, "Channel Status: %s \t \t \t \t %s \n",
+ (reg & 0x02) ? "On" : "Off",
+ (reg & 0x04) ? "On" : "Off");
+
+ rc = pci_read_config_byte(bmide_dev, 0x09, &reg);
+ p += sprintf(p, "Operation Mode: %s \t \t \t %s \n",
+ (reg & 0x01) ? "Native" : "Compatible",
+ (reg & 0x04) ? "Native" : "Compatible");
+
+ rc = pci_read_config_byte(bmide_dev, 0x48, &reg);
+ p += sprintf(p, "Cable Type: %s \t \t \t %s\n",
+ (reg & 0x10) ? cable_type[1] : cable_type[0],
+ (reg & 0x20) ? cable_type[1] : cable_type[0]);
+
+ rc = pci_read_config_word(bmide_dev, 0x4c, &reg2);
+ rc = pci_read_config_word(bmide_dev, 0x4e, &reg3);
+ p += sprintf(p, "Prefetch Count: %d \t \t \t \t %d\n",
+ reg2, reg3);
+
+ rc = pci_read_config_byte(bmide_dev, 0x4b, &reg);
+ p += sprintf(p, "Drvie 0: Postwrite %s \t \t Postwrite %s\n",
+ (reg & 0x10) ? "Enabled" : "Disabled",
+ (reg & 0x40) ? "Enabled" : "Disabled");
+ p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n",
+ (reg & 0x01) ? "Enabled" : "Disabled",
+ (reg & 0x04) ? "Enabled" : "Disabled");
+
+ rc = pci_read_config_byte(bmide_dev, 0x41, &reg);
+ rc = pci_read_config_byte(bmide_dev, 0x45, &reg1);
+ p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n",
+ (reg & 0x80) ? "Enabled" : "Disabled",
+ (reg1 & 0x80) ? "Enabled" : "Disabled");
+ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
+ cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
+ p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
+ active_time[(reg & 0x07)], active_time[(reg &0x07)] );
+
+ rc = pci_read_config_byte(bmide_dev, 0x40, &reg);
+ rc = pci_read_config_byte(bmide_dev, 0x44, &reg1);
+ p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n",
+ recovery_time[(reg & 0x0f)], recovery_time[(reg1 & 0x0f)]);
+
+
+ rc = pci_read_config_byte(bmide_dev, 0x4b, &reg);
+ p += sprintf(p, "Drvie 1: Postwrite %s \t \t Postwrite %s\n",
+ (reg & 0x20) ? "Enabled" : "Disabled",
+ (reg & 0x80) ? "Enabled" : "Disabled");
+ p += sprintf(p, " Prefetch %s \t \t Prefetch %s\n",
+ (reg & 0x02) ? "Enabled" : "Disabled",
+ (reg & 0x08) ? "Enabled" : "Disabled");
+
+ rc = pci_read_config_byte(bmide_dev, 0x43, &reg);
+ rc = pci_read_config_byte(bmide_dev, 0x47, &reg1);
+ p += sprintf(p, " UDMA %s \t \t \t UDMA %s\n",
+ (reg & 0x80) ? "Enabled" : "Disabled",
+ (reg1 & 0x80) ? "Enabled" : "Disabled");
+ p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n",
+ cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]);
+ p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n",
+ active_time[(reg & 0x07)], active_time[(reg &0x07)] );
+
+ rc = pci_read_config_byte(bmide_dev, 0x42, &reg);
+ rc = pci_read_config_byte(bmide_dev, 0x46, &reg1);
+ p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n",
+ recovery_time[(reg & 0x0f)], recovery_time[(reg1 & 0x0f)]);
+ return p-buffer;
+}
+#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
+byte sis_proc = 0;
extern char *ide_xfer_verbose (byte xfer_rate);
/*
@@ -79,36 +247,18 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
}
if ((id->dma_ultra & 0x0010) && (ultra) && (udma_66) && (four_two)) {
- if (!((id->dma_ultra >> 8) & 16)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x1010;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
if (!(test2 & 0x90)) {
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
pci_write_config_byte(dev, drive_pci|0x01, test2|0x90);
}
speed = XFER_UDMA_4;
} else if ((id->dma_ultra & 0x0008) && (ultra) && (udma_66) && (four_two)) {
- if (!((id->dma_ultra >> 8) & 8)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0808;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
if (!(test2 & 0xA0)) {
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
pci_write_config_byte(dev, drive_pci|0x01, test2|0xA0);
}
speed = XFER_UDMA_3;
} else if ((id->dma_ultra & 0x0004) && (ultra)) {
- if (!((id->dma_ultra >> 8) & 4)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
mask = (four_two) ? 0xB0 : 0xA0;
if (!(test2 & mask)) {
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
@@ -116,12 +266,6 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
}
speed = XFER_UDMA_2;
} else if ((id->dma_ultra & 0x0002) && (ultra)) {
- if (!((id->dma_ultra >> 8) & 2)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
mask = (four_two) ? 0xD0 : 0xC0;
if (!(test2 & mask)) {
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
@@ -129,58 +273,22 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
}
speed = XFER_UDMA_1;
} else if ((id->dma_ultra & 0x0001) && (ultra)) {
- if (!((id->dma_ultra >> 8) & 1)) {
- drive->id->dma_ultra &= ~0xFF00;
- drive->id->dma_ultra |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_1word &= ~0x0F00;
- }
if (!(test2 & unmask)) {
pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);
pci_write_config_byte(dev, drive_pci|0x01, test2|unmask);
}
speed = XFER_UDMA_0;
} else if (id->dma_mword & 0x0004) {
- if (!((id->dma_mword >> 8) & 4)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0404;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_2;
} else if (id->dma_mword & 0x0002) {
- if (!((id->dma_mword >> 8) & 2)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0202;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_1;
} else if (id->dma_mword & 0x0001) {
- if (!((id->dma_mword >> 8) & 1)) {
- drive->id->dma_mword &= ~0x0F00;
- drive->id->dma_mword |= 0x0101;
- drive->id->dma_1word &= ~0x0F00;
- }
speed = XFER_MW_DMA_0;
} else if (id->dma_1word & 0x0004) {
- if (!((id->dma_1word >> 8) & 4)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0404;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_2;
} else if (id->dma_1word & 0x0002) {
- if (!((id->dma_1word >> 8) & 2)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0202;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_1;
} else if (id->dma_1word & 0x0001) {
- if (!((id->dma_1word >> 8) & 1)) {
- drive->id->dma_1word &= ~0x0F00;
- drive->id->dma_1word |= 0x0101;
- drive->id->dma_mword &= ~0x0F00;
- }
speed = XFER_SW_DMA_0;
} else {
return ((int) ide_dma_off_quietly);
@@ -189,10 +297,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
err = ide_config_drive_speed(drive, speed);
#if SIS5513_DEBUG_DRIVE_INFO
- printk("%s: %s drive%d\n",
- drive->name,
- ide_xfer_verbose(speed),
- drive_number);
+ printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive_number);
#endif /* SIS5513_DEBUG_DRIVE_INFO */
return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
@@ -333,10 +438,9 @@ int sis5513_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
{
struct pci_dev *host;
- byte latency = 0, reg48h = 0;
+ byte latency = 0;
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
- pci_read_config_byte(dev, 0x48, &reg48h);
for (host = pci_devices; host; host=host->next) {
if (host->vendor == PCI_VENDOR_ID_SI &&
@@ -344,30 +448,18 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
if (latency != 0x10)
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);
host_dev = host;
- printk("%s: Chipset Core ATA-66, SiS620\n", name);
- printk("%s: Primary ATA-%s, Secondary ATA-%s Cable Detect\n",
- name,
- (reg48h & 0x10) ? "33" : "66",
- (reg48h & 0x20) ? "33" : "66");
break;
} else if (host->vendor == PCI_VENDOR_ID_SI &&
host->device == PCI_DEVICE_ID_SI_530) {
host_dev = host;
- printk("%s: Chipset Core ATA-66, SiS530\n", name);
- printk("%s: Primary ATA-%s, Secondary ATA-%s Cable Detect\n",
- name,
- (reg48h & 0x10) ? "33" : "66",
- (reg48h & 0x20) ? "33" : "66");
break;
} else if (host->vendor == PCI_VENDOR_ID_SI &&
host->device == PCI_DEVICE_ID_SI_5600) {
host_dev = host;
- printk("SIS5600:%s Chipset Core ATA-33\n", name);
break;
} else if (host->vendor == PCI_VENDOR_ID_SI &&
host->device == PCI_DEVICE_ID_SI_5597) {
host_dev = host;
- printk("SIS5597:%s Chipset Core ATA-33\n", name);
break;
}
}
@@ -377,18 +469,38 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
pci_read_config_byte(dev, 0x52, &reg52h);
if (!(reg52h & 0x04))
+ /* set IDE controller to operate in Compabitility mode obly */
pci_write_config_byte(dev, 0x52, reg52h|0x04);
+#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
+ sis_proc = 1;
+ bmide_dev = dev;
+ sis_display_info = &sis_get_info;
+#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
}
-
return 0;
}
-void __init ide_init_sis5513 (ide_hwif_t *hwif)
+unsigned int __init ata66_sis5513 (ide_hwif_t *hwif)
{
- byte reg48h = 0;
+ byte reg48h = 0, ata66 = 0;
byte mask = hwif->channel ? 0x20 : 0x10;
-
pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
+
+ if (host_dev) {
+ switch(host_dev->device) {
+ case PCI_DEVICE_ID_SI_530:
+ case PCI_DEVICE_ID_SI_620:
+ ata66 = (reg48h & mask) ? 0 : 1;
+ default:
+ break;
+ }
+ }
+ return (ata66);
+}
+
+void __init ide_init_sis5513 (ide_hwif_t *hwif)
+{
+
hwif->irq = hwif->channel ? 15 : 14;
if (!(hwif->dma_base))
@@ -398,20 +510,15 @@ void __init ide_init_sis5513 (ide_hwif_t *hwif)
switch(host_dev->device) {
case PCI_DEVICE_ID_SI_530:
case PCI_DEVICE_ID_SI_620:
- hwif->autodma = 1;
- hwif->udma_four = (reg48h & mask) ? 0 : 1;
- hwif->dmaproc = &sis5513_dmaproc;
- return;
case PCI_DEVICE_ID_SI_5600:
case PCI_DEVICE_ID_SI_5597:
hwif->autodma = 1;
- hwif->udma_four = 0;
hwif->dmaproc = &sis5513_dmaproc;
- return;
+ break;
default:
hwif->autodma = 0;
- hwif->udma_four = 0;
- return;
+ break;
}
}
+ return;
}
diff --git a/drivers/block/sl82c105.c b/drivers/block/sl82c105.c
index d4e22d33b..fa47adbb7 100644
--- a/drivers/block/sl82c105.c
+++ b/drivers/block/sl82c105.c
@@ -5,7 +5,7 @@
*
* Maintainer unknown.
*
- * Drive tuning added from Corel Computer's kernel sources
+ * Drive tuning added from Rebel.com's kernel sources
* -- Russell King (15/11/98) linux@arm.linux.org.uk
*/
diff --git a/drivers/block/trm290.c b/drivers/block/trm290.c
index ad6a75d0f..5c7c8fd3c 100644
--- a/drivers/block/trm290.c
+++ b/drivers/block/trm290.c
@@ -192,7 +192,8 @@ static int trm290_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
if (drive->media != ide_disk)
return 0;
- ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
+ drive->timeout = WAIT_CMD;
+ ide_set_handler(drive, &ide_dma_intr);
OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
return 0;
case ide_dma_begin:
diff --git a/drivers/block/via82c586.c b/drivers/block/via82cxxx.c
index e5697014e..e6f61c03f 100644
--- a/drivers/block/via82c586.c
+++ b/drivers/block/via82cxxx.c
@@ -1,9 +1,12 @@
/*
- * linux/drivers/block/via82c586.c Version 0.04 July 11, 1999
+ * linux/drivers/block/via82cxxx.c Version 0.05 Sept. 03, 1999
*
- * Copyright (C) 1998 Michel Aubry, Maintainer
- * Copyright (C) 1998 Andre Hedrick, Maintainer
+ * Copyright (C) 1998-99 Michel Aubry, Maintainer
+ * Copyright (C) 1999 Jeff Garzik, MVP4 Support (jgarzik@pobox.com)
+ * Copyright (C) 1998-99 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
*
+ * The VIA MVP-4 is reported OK with UDMA.
* The VIA MVP-3 is reported OK with UDMA.
* The TX Pro III is also reported OK with UDMA.
*
@@ -57,8 +60,44 @@
#include <asm/io.h>
-static struct pci_dev *host_dev;
-static struct pci_dev *isa_dev;
+static struct pci_dev *host_dev = NULL;
+static struct pci_dev *isa_dev = NULL;
+
+static const struct {
+ const char *name;
+ unsigned short host_id;
+} ApolloHostChipInfo[] = {
+ { "VT 82C585 Apollo VP1/VPX", PCI_DEVICE_ID_VIA_82C585, },
+ { "VT 82C595 Apollo VP2", PCI_DEVICE_ID_VIA_82C595, },
+ { "VT 82C597 Apollo VP3", PCI_DEVICE_ID_VIA_82C597_0, },
+ { "VT 82C598 Apollo MVP3", PCI_DEVICE_ID_VIA_82C598_0, },
+ { "VT 82C680 Apollo P6", PCI_DEVICE_ID_VIA_82C680, },
+ { "VT 82C691 Apollo Pro", PCI_DEVICE_ID_VIA_82C691, },
+ { "VT 82C693 Apollo Pro Plus", PCI_DEVICE_ID_VIA_82C693, },
+ { "Apollo MVP4", PCI_DEVICE_ID_VIA_8501_0, },
+};
+
+#define NUM_APOLLO_ISA_CHIP_DEVICES 2
+#define VIA_FLAG_CHECK_REV 0x00000001
+#define VIA_FLAG_ATA_66 0x00000002
+
+static const struct {
+ unsigned short host_id;
+ unsigned short isa_id;
+ unsigned int flags;
+} ApolloISAChipInfo[] = {
+ { PCI_DEVICE_ID_VIA_82C585, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV },
+ { PCI_DEVICE_ID_VIA_82C595, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV },
+ { PCI_DEVICE_ID_VIA_82C597_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV },
+ { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV },
+ { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C596, 0 },
+ { PCI_DEVICE_ID_VIA_82C680, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV },
+ { PCI_DEVICE_ID_VIA_82C691, PCI_DEVICE_ID_VIA_82C596, 0 },
+ { PCI_DEVICE_ID_VIA_82C693, PCI_DEVICE_ID_VIA_82C596, 0 },
+ { PCI_DEVICE_ID_VIA_8501_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66 },
+};
+
+#define arraysize(x) (sizeof(x)/sizeof(*(x)))
#define DISPLAY_VIA_TIMINGS
@@ -298,6 +337,7 @@ static int via_get_info (char *buffer, char **addr, off_t offset, int count, int
* Used to set Fifo configuration via kernel command line:
*/
+byte via_proc = 0;
byte fifoconfig = 0;
static byte newfifo = 0;
@@ -340,8 +380,8 @@ static void set_via_timings (ide_hwif_t *hwif)
/*
* setting Channel read and End-of-sector FIFO flush.
* (This feature ensures that FIFO flush is enabled:
- * - for read DMA when interrupt asserts the given channel.
- * - at the end of each sector for the given channel.)
+ * - for read DMA when interrupt asserts the given channel.
+ * - at the end of each sector for the given channel.)
*/
if ((rc = pci_read_config_byte(dev, 0x46, &via_config)))
errors++;
@@ -363,7 +403,7 @@ static void set_via_timings (ide_hwif_t *hwif)
}
/*
- * Sets VIA 82c586 FIFO configuration:
+ * Sets VIA 82cxxx FIFO configuration:
* This chipsets gets a splitable fifo. This can be driven either by command
* line option (eg "splitfifo=2,2,3" which asks this driver to switch all the
* 16 fifo levels to the second drive, and give it a threshold of 3 for (u)dma
@@ -435,139 +475,71 @@ static int via_set_fifoconfig(ide_hwif_t *hwif)
(newfifo & 0x01) ? "1/4" : "1/2"));
#if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS)
+ via_proc = 1;
bmide_dev = hwif->pci_dev;
via_display_info = &via_get_info;
#endif /* DISPLAY_VIA_TIMINGS && CONFIG_PROC_FS*/
return 0;
}
-unsigned int __init pci_init_via82c568 (struct pci_dev *dev, const char *name)
+unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
{
struct pci_dev *host;
struct pci_dev *isa;
+ int i, j, ata33, ata66;
byte revision = 0;
- for (host = pci_devices; host; host=host->next) {
- if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C585) {
- host_dev = host;
- printk("VT 82C585 Apollo VP1/VPX");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C586_1) {
- isa_dev = isa;
- pci_read_config_byte(isa_dev, 0x0d, &revision);
- if (revision >= 0x20)
- printk(" Chipset Core ATA-33");
- break;
- }
- }
- printk("\n");
- break;
- } else if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C595) {
- host_dev = host;
- printk("VT 82C595 Apollo VP2");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C586_1) {
- isa_dev = isa;
- pci_read_config_byte(isa_dev, 0x0d, &revision);
- if (revision >= 0x20)
- printk(" Chipset Core ATA-33");
- break;
- }
- }
- printk("\n");
- break;
- } else if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C597_0) {
- host_dev = host;
- printk("VT 82C597 Apollo VP3");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C586_1) {
- isa_dev = isa;
- pci_read_config_byte(isa_dev, 0x0d, &revision);
- if (revision >= 0x20)
- printk(" Chipset Core ATA-33");
- break;
- }
- }
- printk("\n");
- break;
- } else if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C598_0) {
- host_dev = host;
- printk("VT 82C598 Apollo MVP3");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C586_1) {
- isa_dev = isa;
- pci_read_config_byte(isa_dev, 0x0d, &revision);
- if (revision >= 0x20)
- printk(" Chipset Core ATA-33");
- break;
- } else if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C596) {
- isa_dev = isa;
- printk(" Chipset Core ATA-33");
- break;
- }
- }
- printk("\n");
- break;
- } else if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C680) {
- host_dev = host;
- printk("VT 82C680 Apollo P6");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C586_1) {
- isa_dev = isa;
- pci_read_config_byte(isa_dev, 0x0d, &revision);
- if (revision >= 0x20)
- printk(" Chipset Core ATA-33");
- break;
- }
+ for (i = 0; i < arraysize (ApolloHostChipInfo) && !host_dev; i++) {
+ host = pci_find_device (PCI_VENDOR_ID_VIA,
+ ApolloHostChipInfo[i].host_id,
+ NULL);
+ if (!host)
+ continue;
+
+ host_dev = host;
+ printk(ApolloHostChipInfo[i].name);
+
+ for (j = 0; j < arraysize (ApolloISAChipInfo) && !isa_dev; j++) {
+ if (ApolloISAChipInfo[j].host_id !=
+ ApolloHostChipInfo[i].host_id)
+ continue;
+
+ isa = pci_find_device (PCI_VENDOR_ID_VIA,
+ ApolloISAChipInfo[i].isa_id,
+ NULL);
+ if (!isa)
+ continue;
+
+ isa_dev = isa;
+
+ ata33 = 1;
+ ata66 = 0;
+
+ if (ApolloISAChipInfo[i].flags & VIA_FLAG_CHECK_REV) {
+ pci_read_config_byte(isa_dev, 0x0d, &revision);
+ ata33 = (revision >= 0x20) ? 1 : 0;
+ } else if (ApolloISAChipInfo[i].flags & VIA_FLAG_ATA_66) {
+ ata33 = 0;
+ ata66 = 1;
}
- printk("\n");
- break;
- } else if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C691) {
- host_dev = host;
- printk("VT 82C691 Apollo Pro");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C596) {
- isa_dev = isa;
- printk(" Chipset Core ATA-33");
- break;
- }
- }
- printk("\n");
- break;
- } else if (host->vendor == PCI_VENDOR_ID_VIA &&
- host->device == PCI_DEVICE_ID_VIA_82C693) {
- host_dev = host;
- printk("VT 82C693 Apollo Pro Plus");
- for (isa = pci_devices; isa; isa=isa->next) {
- if (isa->vendor == PCI_VENDOR_ID_VIA &&
- isa->device == PCI_DEVICE_ID_VIA_82C596) {
- isa_dev = isa;
- printk(" Chipset Core ATA-33");
- break;
- }
- }
- printk("\n");
- break;
+
+ if (ata33 | ata66)
+ printk(" Chipset Core ATA-%s", ata66 ? "66" : "33");
}
+ printk("\n");
}
+
+ return 0;
+}
+
+unsigned int __init ata66_via82cxxx (ide_hwif_t *hwif)
+{
+ /* (Jeff Garzik) FIXME!!! for MVP4 */
return 0;
}
-void __init ide_init_via82c586 (ide_hwif_t *hwif)
+void __init ide_init_via82cxxx (ide_hwif_t *hwif)
{
set_via_timings(hwif);
}
@@ -581,7 +553,7 @@ void __init ide_init_via82c586 (ide_hwif_t *hwif)
* bypasses the setup if not capable.
*/
-void ide_dmacapable_via82c586 (ide_hwif_t *hwif, unsigned long dmabase)
+void ide_dmacapable_via82cxxx (ide_hwif_t *hwif, unsigned long dmabase)
{
if (!done) {
via_set_fifoconfig(hwif);