summaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
commitb9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch)
tree42d07b0c7246ae2536a702e7c5de9e2732341116 /drivers/ide
parent7406b0a326f2d70ade2671c37d1beef62249db97 (diff)
Merge with 2.3.99-pre6.
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Config.in12
-rw-r--r--drivers/ide/Makefile4
-rw-r--r--drivers/ide/aec6210.c376
-rw-r--r--drivers/ide/aec62xx.c553
-rw-r--r--drivers/ide/ali14xx.c3
-rw-r--r--drivers/ide/alim15x3.c7
-rw-r--r--drivers/ide/amd7409.c1
-rw-r--r--drivers/ide/buddha.c1
-rw-r--r--drivers/ide/cmd640.c3
-rw-r--r--drivers/ide/cmd64x.c7
-rw-r--r--drivers/ide/cy82c693.c4
-rw-r--r--drivers/ide/dtc2278.c1
-rw-r--r--drivers/ide/falconide.c1
-rw-r--r--drivers/ide/gayle.c1
-rw-r--r--drivers/ide/ht6560b.c5
-rw-r--r--drivers/ide/icside.c1
-rw-r--r--drivers/ide/ide-cd.c578
-rw-r--r--drivers/ide/ide-cd.h20
-rw-r--r--drivers/ide/ide-disk.c8
-rw-r--r--drivers/ide/ide-dma.c8
-rw-r--r--drivers/ide/ide-floppy.c11
-rw-r--r--drivers/ide/ide-pci.c34
-rw-r--r--drivers/ide/ide-pnp.c2
-rw-r--r--drivers/ide/ide-probe.c4
-rw-r--r--drivers/ide/ide-proc.c24
-rw-r--r--drivers/ide/ide-tape.c1
-rw-r--r--drivers/ide/ide.c32
-rw-r--r--drivers/ide/ide_modes.h7
-rw-r--r--drivers/ide/macide.c1
-rw-r--r--drivers/ide/ns87415.c1
-rw-r--r--drivers/ide/opti621.c5
-rw-r--r--drivers/ide/pdc4030.c1
-rw-r--r--drivers/ide/piix.c1
-rw-r--r--drivers/ide/qd6580.c1
-rw-r--r--drivers/ide/rapide.c1
-rw-r--r--drivers/ide/rz1000.c1
-rw-r--r--drivers/ide/sis5513.c4
-rw-r--r--drivers/ide/umc8672.c1
-rw-r--r--drivers/ide/via82cxxx.c270
39 files changed, 1138 insertions, 858 deletions
diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in
index 15e1fd52b..6d68bd5ea 100644
--- a/drivers/ide/Config.in
+++ b/drivers/ide/Config.in
@@ -16,7 +16,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE
dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE
dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
- dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
+ dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI
comment 'IDE chipset support/bugfixes'
if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
@@ -35,8 +35,8 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
define_bool CONFIG_IDEDMA_PCI_EXPERIMENTAL $CONFIG_EXPERIMENTAL
dep_bool ' ATA Work(s) In Progress (EXPERIMENTAL)' CONFIG_IDEDMA_PCI_WIP $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
dep_bool ' Good-Bad DMA Model-Firmware (WIP)' CONFIG_IDEDMA_NEW_DRIVE_LISTINGS $CONFIG_IDEDMA_PCI_WIP
- dep_bool ' AEC6210 chipset support' CONFIG_BLK_DEV_AEC6210 $CONFIG_BLK_DEV_IDEDMA_PCI
- dep_mbool ' AEC6210 Tuning support (WIP)' CONFIG_AEC6210_TUNING $CONFIG_BLK_DEV_AEC6210 $CONFIG_IDEDMA_PCI_WIP
+ dep_bool ' AEC62XX chipset support' CONFIG_BLK_DEV_AEC62XX $CONFIG_BLK_DEV_IDEDMA_PCI
+ dep_mbool ' AEC62XX Tuning support (WIP)' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX $CONFIG_IDEDMA_PCI_WIP
dep_bool ' ALI M15x3 chipset support' CONFIG_BLK_DEV_ALI15X3 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' ALI M15x3 WDC support (DANGEROUS)' CONFIG_WDC_ALI15X3 $CONFIG_BLK_DEV_ALI15X3
dep_bool ' AMD Viper support' CONFIG_BLK_DEV_AMD7409 $CONFIG_BLK_DEV_IDEDMA_PCI
@@ -62,6 +62,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
dep_bool ' Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' VIA82CXXX chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
+ dep_mbool ' VIA82CXXX Tuning support (WIP)' CONFIG_VIA82CXXX_TUNING $CONFIG_BLK_DEV_VIA82CXXX $CONFIG_IDEDMA_PCI_WIP
fi
if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
bool ' Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
@@ -122,7 +123,7 @@ else
fi
if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \
- "$CONFIG_BLK_DEV_AEC6210" = "y" -o \
+ "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \
"$CONFIG_BLK_DEV_ALI15X3" = "y" -o \
"$CONFIG_BLK_DEV_AMD7409" = "y" -o \
"$CONFIG_BLK_DEV_CMD640" = "y" -o \
@@ -136,7 +137,8 @@ if [ "$CONFIG_IDE_CHIPSETS" = "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
+ "$CONFIG_BLK_DEV_SL82C105" = "y" -o \
+ "$CONFIG_BLK_DEV_VIA82CXXX" = "y" ]; then
define_bool CONFIG_BLK_DEV_IDE_MODES y
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 699c48b82..278ad7ab7 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -25,8 +25,8 @@ MOD_LIST_NAME := IDE_MODULES
LX_OBJS :=
MX_OBJS :=
-ifeq ($(CONFIG_BLK_DEV_AEC6210),y)
-IDE_OBJS += aec6210.o
+ifeq ($(CONFIG_BLK_DEV_AEC62XX),y)
+IDE_OBJS += aec62xx.o
endif
ifeq ($(CONFIG_BLK_DEV_ALI14XX),y)
diff --git a/drivers/ide/aec6210.c b/drivers/ide/aec6210.c
deleted file mode 100644
index cf41fa3d0..000000000
--- a/drivers/ide/aec6210.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * linux/drivers/ide/aec6210.c Version 0.06 Mar. 18, 2000
- *
- * Copyright (C) 1998-2000 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
- * pio 2 :: 40: 08 07 00 00 00 00 00 00 02 07 a6 05 00 02 00 02
- * pio 3 :: 40: 03 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * pio 4 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * dma 0 :: 40: 0a 07 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * dma 1 :: 40: 02 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * dma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * 50: ff ff ff ff 00 06 04 00 00 00 00 00 00 00 00 00
- *
- * udma 0 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00
- *
- * udma 1 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * 50: ff ff ff ff 01 06 04 00 00 00 00 00 00 00 00 00
- *
- * udma 2 :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00
- *
- * auto :: 40: 01 04 00 00 00 00 00 00 02 05 a6 05 00 02 00 02
- * 50: ff ff ff ff 02 06 04 00 00 00 00 00 00 00 00 00
- *
- * auto :: 40: 01 04 01 04 01 04 01 04 02 05 a6 cf 00 02 00 02
- * 50: ff ff ff ff aa 06 04 00 00 00 00 00 00 00 00 00
- *
- * NO-Devices
- * 40: 00 00 00 00 00 00 00 00 02 05 a6 00 00 02 00 02
- * 50: ff ff ff ff 00 06 00 00 00 00 00 00 00 00 00 00
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "ide_modes.h"
-
-#define ACARD_DEBUG_DRIVE_INFO 0
-
-#undef DISPLAY_AEC6210_TIMINGS
-
-#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static int aec6210_get_info(char *, char **, off_t, int);
-extern int (*aec6210_display_info)(char *, char **, off_t, int); /* ide-proc.c */
-extern char *ide_media_verbose(ide_drive_t *);
-static struct pci_dev *bmide_dev;
-
-static int aec6210_get_info (char *buffer, char **addr, off_t offset, int count)
-{
- char *p = buffer;
-
- u32 bibma = bmide_dev->resource[4].start;
- u8 c0 = 0, c1 = 0;
-
- p += sprintf(p, "\n AEC6210 Chipset.\n");
-
- /*
- * at that point bibma+0x2 et bibma+0xa are byte registers
- * to investigate:
- */
- c0 = inb_p((unsigned short)bibma + 0x02);
- c1 = inb_p((unsigned short)bibma + 0x0a);
-
- p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
- p += sprintf(p, " %sabled %sabled\n",
- (c0&0x80) ? "dis" : " en",
- (c1&0x80) ? "dis" : " en");
- p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
- p += sprintf(p, "DMA enabled: %s %s %s %s\n",
- (c0&0x20) ? "yes" : "no ", (c0&0x40) ? "yes" : "no ",
- (c1&0x20) ? "yes" : "no ", (c1&0x40) ? "yes" : "no " );
-
- p += sprintf(p, "UDMA\n");
- p += sprintf(p, "DMA\n");
- p += sprintf(p, "PIO\n");
- return p-buffer;/* => must be less than 4k! */
-}
-#endif /* defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS) */
-
-byte aec6210_proc = 0;
-
-#ifdef CONFIG_AEC6210_TUNING
-
-struct chipset_bus_clock_list_entry {
- byte xfer_speed;
- unsigned short chipset_settings;
- byte ultra_settings;
-};
-
-struct chipset_bus_clock_list_entry aec6210_base [] = {
- { XFER_UDMA_2, 0x0401, 0x02 },
- { XFER_UDMA_1, 0x0401, 0x01 },
- { XFER_UDMA_0, 0x0401, 0x01 },
-
- { XFER_MW_DMA_2, 0x0401, 0x00 },
- { XFER_MW_DMA_1, 0x0402, 0x00 },
- { XFER_MW_DMA_0, 0x070a, 0x00 },
-
- { XFER_PIO_4, 0x0401, 0x00 },
- { XFER_PIO_3, 0x0403, 0x00 },
- { XFER_PIO_2, 0x0708, 0x00 },
- { XFER_PIO_1, 0x070a, 0x00 },
- { XFER_PIO_0, 0x0700, 0x00 },
- { 0, 0x0000, 0x00 }
-};
-
-extern char *ide_xfer_verbose (byte xfer_rate);
-
-/*
- * TO DO: active tuning and correction of cards without a bios.
- */
-
-static unsigned short pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
-{
- for ( ; chipset_table->xfer_speed ; chipset_table++)
- if (chipset_table->xfer_speed == speed) {
- return chipset_table->chipset_settings;
- }
- return 0x0000;
-}
-
-static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
-{
- for ( ; chipset_table->xfer_speed ; chipset_table++)
- if (chipset_table->xfer_speed == speed) {
- return chipset_table->ultra_settings;
- }
- return 0x00;
-}
-
-static int aec6210_tune_chipset (ide_drive_t *drive, byte speed)
-{
- ide_hwif_t *hwif = HWIF(drive);
-
- int err;
- byte drive_pci;
- unsigned short drive_conf = 0x0000;
- byte ultra = 0x00, ultra_conf = 0x00;
- byte tmp1 = 0x00, tmp2 = 0x00;
-
- int drive_number = ((hwif->channel ? 2 : 0) + (drive->select.b.unit & 0x01));
-
- switch(drive_number) {
- case 0: drive_pci = 0x40; break;
- case 1: drive_pci = 0x42; break;
- case 2: drive_pci = 0x44; break;
- case 3: drive_pci = 0x46; break;
- default: return -1;
- }
-
- pci_read_config_word(HWIF(drive)->pci_dev, drive_pci, &drive_conf);
- drive_conf = pci_bus_clock_list(speed, aec6210_base);
- pci_write_config_word(HWIF(drive)->pci_dev, drive_pci, drive_conf);
-
- pci_read_config_byte(HWIF(drive)->pci_dev, 0x54, &ultra);
- tmp1 = ((0x00 << (2*drive_number)) | (ultra & ~(3 << (2*drive_number))));
- ultra_conf = pci_bus_clock_list_ultra(speed, aec6210_base);
- tmp2 = ((ultra_conf << (2*drive_number)) | (tmp1 & ~(3 << (2*drive_number))));
- pci_write_config_byte(HWIF(drive)->pci_dev, 0x54, tmp2);
-
- err = ide_config_drive_speed(drive, speed);
-
-#if ACARD_DEBUG_DRIVE_INFO
- printk("%s: %s drive%d 0x04%x 0x02%x 0x02%x 0x02%x 0x02%x\n",
- drive->name, ide_xfer_verbose(speed), drive_number,
- drive_conf, ultra, tmp1, ultra_conf, tmp2);
-#endif /* ACARD_DEBUG_DRIVE_INFO */
-
- return(err);
-}
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
-{
- struct hd_driveid *id = drive->id;
- byte speed = -1;
-
- if (drive->media != ide_disk)
- return ((int) ide_dma_off_quietly);
-
- if (((id->dma_ultra & 0x0010) ||
- (id->dma_ultra & 0x0008) ||
- (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) && (ultra)) {
- speed = XFER_UDMA_0;
- } else if (id->dma_mword & 0x0004) {
- speed = XFER_MW_DMA_2;
- } else if (id->dma_mword & 0x0002) {
- speed = XFER_MW_DMA_1;
- } else if (id->dma_mword & 0x0001) {
- speed = XFER_MW_DMA_0;
- } else if (id->dma_1word & 0x0004) {
- speed = XFER_SW_DMA_2;
- } else if (id->dma_1word & 0x0002) {
- speed = XFER_SW_DMA_1;
- } else if (id->dma_1word & 0x0001) {
- speed = XFER_SW_DMA_0;
- } else {
- return ((int) ide_dma_off_quietly);
- }
- (void) aec6210_tune_chipset(drive, speed);
-
- return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off :
- ((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);
-}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-
-static void aec6210_tune_drive (ide_drive_t *drive, byte pio)
-{
- byte speed;
-
- switch(pio) {
- case 5:
- speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
- case 4:
- speed = XFER_PIO_4; break;
- case 3:
- speed = XFER_PIO_3; break;
- case 2:
- speed = XFER_PIO_2; break;
- case 1:
- speed = XFER_PIO_1; break;
- default:
- speed = XFER_PIO_0; break;
- }
- (void) aec6210_tune_chipset(drive, speed);
-}
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_drive_xfer_rate (ide_drive_t *drive)
-{
- struct hd_driveid *id = drive->id;
- ide_dma_action_t dma_func = ide_dma_on;
-
- if (id && (id->capability & 1) && HWIF(drive)->autodma) {
- /* Consult the list of known "bad" drives */
- if (ide_dmaproc(ide_dma_bad_drive, 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 */
- dma_func = config_chipset_for_dma(drive, 1);
- if ((id->field_valid & 2) &&
- (dma_func != ide_dma_on))
- goto try_dma_modes;
- }
- } else if (id->field_valid & 2) {
-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, 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;
- }
- /* 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:
- aec6210_tune_drive(drive, 5);
- }
- return HWIF(drive)->dmaproc(dma_func, drive);
-}
-
-/*
- * aec6210_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
- */
-int aec6210_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
-{
- switch (func) {
- case ide_dma_check:
- return config_drive_xfer_rate(drive);
- default:
- break;
- }
- return ide_dmaproc(func, drive); /* use standard DMA stuff */
-}
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-#endif /* CONFIG_AEC6210_TUNING */
-
-unsigned int __init pci_init_aec6210 (struct pci_dev *dev, const char *name)
-{
- 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);
- }
-
-#if defined(DISPLAY_AEC6210_TIMINGS) && defined(CONFIG_PROC_FS)
- aec6210_proc = 1;
- bmide_dev = dev;
- aec6210_display_info = &aec6210_get_info;
-#endif /* DISPLAY_AEC6210_TIMINGS && CONFIG_PROC_FS */
-
- return dev->irq;
-}
-
-void __init ide_init_aec6210 (ide_hwif_t *hwif)
-{
-#ifdef CONFIG_AEC6210_TUNING
- hwif->tuneproc = &aec6210_tune_drive;
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
-
-#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->dma_base)
- hwif->dmaproc = &aec6210_dmaproc;
-#endif /* CONFIG_BLK_DEV_IDEDMA */
-#endif /* CONFIG_AEC6210_TUNING */
-}
-
-void __init ide_dmacapable_aec6210 (ide_hwif_t *hwif, unsigned long dmabase)
-{
- byte dma_new = 0;
- byte dma_old = inb(dmabase+2);
- byte reg54h = 0;
- byte masterdma = hwif->channel ? 0x30 : 0x03;
- byte slavedma = hwif->channel ? 0xc0 : 0x0c;
- unsigned long flags;
-
- __save_flags(flags); /* local CPU only */
- __cli(); /* local CPU only */
-
- dma_new = dma_old;
-
- pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
-
- if (reg54h & masterdma) dma_new |= 0x20;
- if (reg54h & slavedma) 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/ide/aec62xx.c b/drivers/ide/aec62xx.c
new file mode 100644
index 000000000..0158b4279
--- /dev/null
+++ b/drivers/ide/aec62xx.c
@@ -0,0 +1,553 @@
+/*
+ * linux/drivers/ide/aec62xx.c Version 0.08 Mar. 28, 2000
+ *
+ * Copyright (C) 2000 Andre Hedrick (andre@suse.com)
+ * May be copied or modified under the terms of the GNU General Public License
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ide.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "ide_modes.h"
+
+#define DISPLAY_AEC62XX_TIMINGS
+
+#ifndef HIGH_4
+#define HIGH_4(H) ((H)=(H>>4))
+#endif
+#ifndef LOW_4
+#define LOW_4(L) ((L)=(L-((L>>4)<<4)))
+#endif
+#ifndef SPLIT_BYTE
+#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
+#endif
+#ifndef MAKE_WORD
+#define MAKE_WORD(W,HB,LB) ((W)=((HB<<8)+LB))
+#endif
+
+
+#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int aec62xx_get_info(char *, char **, off_t, int);
+extern int (*aec62xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static struct pci_dev *bmide_dev;
+
+static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count)
+{
+ char *p = buffer;
+
+ u32 bibma = bmide_dev->resource[4].start;
+ u8 c0 = 0, c1 = 0;
+ u8 art = 0, uart = 0;
+
+ switch(bmide_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP850UF:
+ p += sprintf(p, "\n AEC6210 Chipset.\n");
+ break;
+ case PCI_DEVICE_ID_ARTOP_ATP860:
+ p += sprintf(p, "\n AEC6260 No Bios Chipset.\n");
+ break;
+ case PCI_DEVICE_ID_ARTOP_ATP860R:
+ p += sprintf(p, "\n AEC6260 Chipset.\n");
+ break;
+ default:
+ p += sprintf(p, "\n AEC62?? Chipset.\n");
+ break;
+ }
+
+ /*
+ * at that point bibma+0x2 et bibma+0xa are byte registers
+ * to investigate:
+ */
+ c0 = inb_p((unsigned short)bibma + 0x02);
+ c1 = inb_p((unsigned short)bibma + 0x0a);
+
+ p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+ (void) pci_read_config_byte(bmide_dev, 0x4a, &art);
+ p += sprintf(p, " %sabled %sabled\n",
+ (art&0x02)?" en":"dis",(art&0x04)?" en":"dis");
+ p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
+ p += sprintf(p, "DMA enabled: %s %s %s %s\n",
+ (c0&0x20)?"yes":"no ",(c0&0x40)?"yes":"no ",(c1&0x20)?"yes":"no ",(c1&0x40)?"yes":"no ");
+
+ switch(bmide_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP850UF:
+ (void) pci_read_config_byte(bmide_dev, 0x54, &art);
+ p += sprintf(p, "DMA Mode: %s(%s) %s(%s) %s(%s) %s(%s)\n",
+ (c0&0x20)?((art&0x03)?"UDMA":" DMA"):" PIO",
+ (art&0x02)?"2":(art&0x01)?"1":"0",
+ (c0&0x40)?((art&0x0c)?"UDMA":" DMA"):" PIO",
+ (art&0x08)?"2":(art&0x04)?"1":"0",
+ (c1&0x20)?((art&0x30)?"UDMA":" DMA"):" PIO",
+ (art&0x20)?"2":(art&0x10)?"1":"0",
+ (c1&0x40)?((art&0xc0)?"UDMA":" DMA"):" PIO",
+ (art&0x80)?"2":(art&0x40)?"1":"0");
+ (void) pci_read_config_byte(bmide_dev, 0x40, &art);
+ p += sprintf(p, "Active: 0x%02x", art);
+ (void) pci_read_config_byte(bmide_dev, 0x42, &art);
+ p += sprintf(p, " 0x%02x", art);
+ (void) pci_read_config_byte(bmide_dev, 0x44, &art);
+ p += sprintf(p, " 0x%02x", art);
+ (void) pci_read_config_byte(bmide_dev, 0x46, &art);
+ p += sprintf(p, " 0x%02x\n", art);
+ (void) pci_read_config_byte(bmide_dev, 0x41, &art);
+ p += sprintf(p, "Recovery: 0x%02x", art);
+ (void) pci_read_config_byte(bmide_dev, 0x43, &art);
+ p += sprintf(p, " 0x%02x", art);
+ (void) pci_read_config_byte(bmide_dev, 0x45, &art);
+ p += sprintf(p, " 0x%02x", art);
+ (void) pci_read_config_byte(bmide_dev, 0x47, &art);
+ p += sprintf(p, " 0x%02x\n", art);
+ break;
+ case PCI_DEVICE_ID_ARTOP_ATP860:
+ case PCI_DEVICE_ID_ARTOP_ATP860R:
+ (void) pci_read_config_byte(bmide_dev, 0x44, &art);
+ p += sprintf(p, "DMA Mode: %s(%s) %s(%s)",
+ (c0&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO",
+ ((art&0x06)==0x06)?"4":((art&0x05)==0x05)?"4":((art&0x04)==0x04)?"3":((art&0x03)==0x03)?"2":((art&0x02)==0x02)?"1":((art&0x01)==0x01)?"0":"?",
+ (c0&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO",
+ ((art&0x60)==0x60)?"4":((art&0x50)==0x50)?"4":((art&0x40)==0x40)?"3":((art&0x30)==0x30)?"2":((art&0x20)==0x20)?"1":((art&0x10)==0x10)?"0":"?");
+ (void) pci_read_config_byte(bmide_dev, 0x45, &art);
+ p += sprintf(p, " %s(%s) %s(%s)\n",
+ (c1&0x20)?((art&0x07)?"UDMA":" DMA"):" PIO",
+ ((art&0x06)==0x06)?"4":((art&0x05)==0x05)?"4":((art&0x04)==0x04)?"3":((art&0x03)==0x03)?"2":((art&0x02)==0x02)?"1":((art&0x01)==0x01)?"0":"?",
+ (c1&0x40)?((art&0x70)?"UDMA":" DMA"):" PIO",
+ ((art&0x60)==0x60)?"4":((art&0x50)==0x50)?"4":((art&0x40)==0x40)?"3":((art&0x30)==0x30)?"2":((art&0x20)==0x20)?"1":((art&0x10)==0x10)?"0":"?");
+ (void) pci_read_config_byte(bmide_dev, 0x40, &art);
+ p += sprintf(p, "Active: 0x%02x", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x41, &art);
+ p += sprintf(p, " 0x%02x", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x42, &art);
+ p += sprintf(p, " 0x%02x", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x43, &art);
+ p += sprintf(p, " 0x%02x\n", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x40, &art);
+ p += sprintf(p, "Recovery: 0x%02x", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x41, &art);
+ p += sprintf(p, " 0x%02x", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x42, &art);
+ p += sprintf(p, " 0x%02x", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x43, &art);
+ p += sprintf(p, " 0x%02x\n", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x49, &uart);
+ p += sprintf(p, "reg49h = 0x%02x ", uart);
+ (void) pci_read_config_byte(bmide_dev, 0x4a, &uart);
+ p += sprintf(p, "reg4ah = 0x%02x\n", uart);
+ break;
+ default:
+ break;
+ }
+
+ return p-buffer;/* => must be less than 4k! */
+}
+#endif /* defined(DISPLAY_AEC62xx_TIMINGS) && defined(CONFIG_PROC_FS) */
+
+byte aec62xx_proc = 0;
+
+#ifdef CONFIG_AEC62XX_TUNING
+
+struct chipset_bus_clock_list_entry {
+ byte xfer_speed;
+
+ byte chipset_settings_34;
+ byte ultra_settings_34;
+
+ byte chipset_settings_33;
+ byte ultra_settings_33;
+};
+
+struct chipset_bus_clock_list_entry aec62xx_base [] = {
+ { XFER_UDMA_4, 0x41, 0x04, 0x31, 0x05 },
+ { XFER_UDMA_3, 0x41, 0x03, 0x31, 0x04 },
+ { XFER_UDMA_2, 0x41, 0x02, 0x31, 0x03 },
+ { XFER_UDMA_1, 0x41, 0x01, 0x31, 0x02 },
+ { XFER_UDMA_0, 0x41, 0x01, 0x31, 0x01 },
+
+ { XFER_MW_DMA_2, 0x41, 0x00, 0x31, 0x00 },
+ { XFER_MW_DMA_1, 0x42, 0x00, 0x31, 0x00 },
+ { XFER_MW_DMA_0, 0x7a, 0x00, 0x0a, 0x00 },
+
+ { XFER_PIO_4, 0x41, 0x00, 0x31, 0x00 },
+ { XFER_PIO_3, 0x43, 0x00, 0x33, 0x00 },
+ { XFER_PIO_2, 0x78, 0x00, 0x08, 0x00 },
+ { XFER_PIO_1, 0x7a, 0x00, 0x0a, 0x00 },
+ { XFER_PIO_0, 0x70, 0x00, 0x00, 0x00 },
+ { 0, 0x00, 0x00, 0x00, 0x00 }
+};
+
+extern char *ide_xfer_verbose (byte xfer_rate);
+
+/*
+ * TO DO: active tuning and correction of cards without a bios.
+ */
+
+static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
+{
+ for ( ; chipset_table->xfer_speed ; chipset_table++)
+ if (chipset_table->xfer_speed == speed) {
+ return ((byte) ((1) ? chipset_table->chipset_settings_33 : chipset_table->chipset_settings_34));
+ }
+ return 0x00;
+}
+
+static byte pci_bus_clock_list_ultra (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
+{
+ for ( ; chipset_table->xfer_speed ; chipset_table++)
+ if (chipset_table->xfer_speed == speed) {
+ return ((byte) ((1) ? chipset_table->ultra_settings_33 : chipset_table->ultra_settings_34));
+ }
+ return 0x00;
+}
+
+static int aec6210_tune_chipset (ide_drive_t *drive, byte speed)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ byte unit = (drive->select.b.unit & 0x01);
+ int drive_number = ((hwif->channel ? 2 : 0) + unit);
+ int err = 0;
+ unsigned short d_conf = 0x0000;
+ byte ultra = 0x00;
+ byte ultra_conf = 0x00;
+ byte tmp0 = 0x00;
+ byte tmp1 = 0x00;
+ byte tmp2 = 0x00;
+ unsigned long flags;
+
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
+
+ pci_read_config_word(dev, 0x40|(2*drive_number), &d_conf);
+ tmp0 = pci_bus_clock_list(speed, aec62xx_base);
+ SPLIT_BYTE(tmp0,tmp1,tmp2);
+ MAKE_WORD(d_conf,tmp1,tmp2);
+ pci_write_config_word(dev, 0x40|(2*drive_number), d_conf);
+
+ tmp1 = 0x00;
+ tmp2 = 0x00;
+ pci_read_config_byte(dev, 0x54, &ultra);
+ tmp1 = ((0x00 << (2*drive_number)) | (ultra & ~(3 << (2*drive_number))));
+ ultra_conf = pci_bus_clock_list_ultra(speed, aec62xx_base);
+ tmp2 = ((ultra_conf << (2*drive_number)) | (tmp1 & ~(3 << (2*drive_number))));
+ pci_write_config_byte(dev, 0x54, tmp2);
+
+ __restore_flags(flags); /* local CPU only */
+
+ err = ide_config_drive_speed(drive, speed);
+ return(err);
+}
+
+static int aec6260_tune_chipset (ide_drive_t *drive, byte speed)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ byte unit = (drive->select.b.unit & 0x01);
+ int drive_number = ((hwif->channel ? 2 : 0) + unit);
+ byte ultra_pci = hwif->channel ? 0x45 : 0x44;
+ int err = 0;
+ byte drive_conf = 0x00;
+ byte ultra_conf = 0x00;
+ byte ultra = 0x00;
+ byte tmp1 = 0x00;
+ byte tmp2 = 0x00;
+
+ unsigned long flags;
+
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
+
+ pci_read_config_byte(dev, 0x40|drive_number, &drive_conf);
+ drive_conf = pci_bus_clock_list(speed, aec62xx_base);
+ pci_write_config_byte(dev, 0x40|drive_number, drive_conf);
+
+ pci_read_config_byte(dev, ultra_pci, &ultra);
+ tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit))));
+ ultra_conf = pci_bus_clock_list_ultra(speed, aec62xx_base);
+ tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
+ pci_write_config_byte(dev, ultra_pci, tmp2);
+ __restore_flags(flags); /* local CPU only */
+
+ err = ide_config_drive_speed(drive, speed);
+ return(err);
+}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+static int config_aec6210_chipset_for_dma (ide_drive_t *drive, byte ultra)
+{
+ struct hd_driveid *id = drive->id;
+ ide_hwif_t *hwif = HWIF(drive);
+ byte unit = (drive->select.b.unit & 0x01);
+ unsigned long dma_base = hwif->dma_base;
+ byte speed = -1;
+
+ if (drive->media != ide_disk)
+ return ((int) ide_dma_off_quietly);
+
+ if (((id->dma_ultra & 0x0010) ||
+ (id->dma_ultra & 0x0008) ||
+ (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) && (ultra)) {
+ speed = XFER_UDMA_0;
+ } else if (id->dma_mword & 0x0004) {
+ speed = XFER_MW_DMA_2;
+ } else if (id->dma_mword & 0x0002) {
+ speed = XFER_MW_DMA_1;
+ } else if (id->dma_mword & 0x0001) {
+ speed = XFER_MW_DMA_0;
+ } else if (id->dma_1word & 0x0004) {
+ speed = XFER_SW_DMA_2;
+ } else if (id->dma_1word & 0x0002) {
+ speed = XFER_SW_DMA_1;
+ } else if (id->dma_1word & 0x0001) {
+ speed = XFER_SW_DMA_0;
+ } else {
+ return ((int) ide_dma_off_quietly);
+ }
+
+ outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+ (void) aec6210_tune_chipset(drive, speed);
+
+ return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_off :
+ ((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);
+}
+
+static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra)
+{
+ struct hd_driveid *id = drive->id;
+ ide_hwif_t *hwif = HWIF(drive);
+ byte unit = (drive->select.b.unit & 0x01);
+ unsigned long dma_base = hwif->dma_base;
+ byte speed = -1;
+ byte ultra66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0;
+
+ if (drive->media != ide_disk)
+ return ((int) ide_dma_off_quietly);
+
+ if ((id->dma_ultra & 0x0010) && (ultra) && (ultra66)) {
+ speed = XFER_UDMA_4;
+ } else if ((id->dma_ultra & 0x0008) && (ultra) && (ultra66)) {
+ speed = XFER_UDMA_3;
+ } 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) && (ultra)) {
+ speed = XFER_UDMA_0;
+ } else if (id->dma_mword & 0x0004) {
+ speed = XFER_MW_DMA_2;
+ } else if (id->dma_mword & 0x0002) {
+ speed = XFER_MW_DMA_1;
+ } else if (id->dma_mword & 0x0001) {
+ speed = XFER_MW_DMA_0;
+ } else if (id->dma_1word & 0x0004) {
+ speed = XFER_SW_DMA_2;
+ } else if (id->dma_1word & 0x0002) {
+ speed = XFER_SW_DMA_1;
+ } else if (id->dma_1word & 0x0001) {
+ speed = XFER_SW_DMA_0;
+ } else {
+ return ((int) ide_dma_off_quietly);
+ }
+
+ outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+ (void) aec6260_tune_chipset(drive, speed);
+
+ return ((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);
+}
+
+static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
+{
+ switch(HWIF(drive)->pci_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP850UF:
+ return config_aec6210_chipset_for_dma(drive, ultra);
+ case PCI_DEVICE_ID_ARTOP_ATP860:
+ case PCI_DEVICE_ID_ARTOP_ATP860R:
+ return config_aec6260_chipset_for_dma(drive, ultra);
+ default:
+ return ((int) ide_dma_off_quietly);
+ }
+}
+
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+static void aec62xx_tune_drive (ide_drive_t *drive, byte pio)
+{
+ byte speed;
+ byte new_pio = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL);
+
+ switch(pio) {
+ case 5: speed = new_pio; break;
+ case 4: speed = XFER_PIO_4; break;
+ case 3: speed = XFER_PIO_3; break;
+ case 2: speed = XFER_PIO_2; break;
+ case 1: speed = XFER_PIO_1; break;
+ default: speed = XFER_PIO_0; break;
+ }
+
+ switch(HWIF(drive)->pci_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP850UF:
+ (void) aec6210_tune_chipset(drive, speed);
+ case PCI_DEVICE_ID_ARTOP_ATP860:
+ case PCI_DEVICE_ID_ARTOP_ATP860R:
+ (void) aec6260_tune_chipset(drive, speed);
+ default:
+ break;
+ }
+}
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+static int config_drive_xfer_rate (ide_drive_t *drive)
+{
+ struct hd_driveid *id = drive->id;
+ ide_dma_action_t dma_func = ide_dma_on;
+
+ if (id && (id->capability & 1) && HWIF(drive)->autodma) {
+ /* Consult the list of known "bad" drives */
+ if (ide_dmaproc(ide_dma_bad_drive, 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 */
+ dma_func = config_chipset_for_dma(drive, 1);
+ if ((id->field_valid & 2) &&
+ (dma_func != ide_dma_on))
+ goto try_dma_modes;
+ }
+ } else if (id->field_valid & 2) {
+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, 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;
+ }
+ /* 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:
+ aec62xx_tune_drive(drive, 5);
+ }
+ return HWIF(drive)->dmaproc(dma_func, drive);
+}
+
+/*
+ * aec62xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
+ */
+int aec62xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+ switch (func) {
+ case ide_dma_check:
+ return config_drive_xfer_rate(drive);
+ default:
+ break;
+ }
+ return ide_dmaproc(func, drive); /* use standard DMA stuff */
+}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif /* CONFIG_AEC62XX_TUNING */
+
+unsigned int __init pci_init_aec62xx (struct pci_dev *dev, const char *name)
+{
+ 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);
+ }
+
+#if defined(DISPLAY_AEC62XX_TIMINGS) && defined(CONFIG_PROC_FS)
+ if (!aec62xx_proc) {
+ aec62xx_proc = 1;
+ bmide_dev = dev;
+ aec62xx_display_info = &aec62xx_get_info;
+ }
+#endif /* DISPLAY_AEC62XX_TIMINGS && CONFIG_PROC_FS */
+
+ return dev->irq;
+}
+
+unsigned int __init ata66_aec62xx (ide_hwif_t *hwif)
+{
+ byte mask = hwif->channel ? 0x02 : 0x01;
+ byte ata66 = 0;
+
+ pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
+#if 1
+ printk("AEC6260: reg49h=0x%02x ATA-%s Cable Port%d\n", ata66, (ata66 & mask) ? "33" : "66", hwif->channel);
+#endif
+ return ((ata66 & mask) ? 0 : 1);
+}
+
+void __init ide_init_aec62xx (ide_hwif_t *hwif)
+{
+#ifdef CONFIG_AEC62XX_TUNING
+ hwif->tuneproc = &aec62xx_tune_drive;
+
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if (hwif->dma_base)
+ hwif->dmaproc = &aec62xx_dmaproc;
+#else /* !CONFIG_BLK_DEV_IDEDMA */
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+#endif /* CONFIG_AEC62XX_TUNING */
+}
+
+void __init ide_dmacapable_aec62xx (ide_hwif_t *hwif, unsigned long dmabase)
+{
+#ifdef CONFIG_AEC62XX_TUNING
+ unsigned long flags;
+ byte reg54h = 0;
+
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
+
+ pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
+ pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F));
+
+ __restore_flags(flags); /* local CPU only */
+#endif /* CONFIG_AEC62XX_TUNING */
+ ide_setup_dma(hwif, dmabase, 8);
+}
diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c
index ff87917c5..d3bf7b801 100644
--- a/drivers/ide/ali14xx.c
+++ b/drivers/ide/ali14xx.c
@@ -48,6 +48,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
@@ -118,7 +119,7 @@ static void ali14xx_tune_drive (ide_drive_t *drive, byte pio)
byte param1, param2, param3, param4;
unsigned long flags;
ide_pio_data_t d;
- int bus_speed = ide_system_bus_speed();
+ int bus_speed = system_bus_clock();
pio = ide_get_best_pio_mode(drive, pio, ALI_MAX_PIO, &d);
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index b043d6774..c5f570674 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
@@ -249,7 +250,7 @@ static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
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 bus_speed = system_bus_clock();
int port = hwif->index ? 0x5c : 0x58;
int portFIFO = hwif->channel ? 0x55 : 0x54;
byte cd_dma_fifo = 0;
@@ -409,14 +410,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra33)
static byte ali15x3_can_ultra (ide_drive_t *drive)
{
-#ifdef CONFIG_WDC_ALI15X3
+#ifndef CONFIG_WDC_ALI15X3
struct hd_driveid *id = drive->id;
#endif /* CONFIG_WDC_ALI15X3 */
if (m5229_revision <= 0x20) {
return 0;
} else if ((m5229_revision < 0xC2) &&
-#ifdef CONFIG_WDC_ALI15X3
+#ifndef CONFIG_WDC_ALI15X3
((chip_is_1543c_e && strstr(id->model, "WDC ")) ||
(drive->media!=ide_disk))) {
#else /* CONFIG_WDC_ALI15X3 */
diff --git a/drivers/ide/amd7409.c b/drivers/ide/amd7409.c
index 2d44044dd..14a8a83f1 100644
--- a/drivers/ide/amd7409.c
+++ b/drivers/ide/amd7409.c
@@ -17,6 +17,7 @@
#include <linux/hdreg.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ide.h>
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c
index da53155c1..710b6654d 100644
--- a/drivers/ide/buddha.c
+++ b/drivers/ide/buddha.c
@@ -21,6 +21,7 @@
#include <linux/hdreg.h>
#include <linux/zorro.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c
index 7a094d497..3bf129932 100644
--- a/drivers/ide/cmd640.c
+++ b/drivers/ide/cmd640.c
@@ -111,6 +111,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
@@ -595,7 +596,7 @@ static void cmd640_set_mode (unsigned int index, byte pio_mode, unsigned int cyc
{
int setup_time, active_time, recovery_time, clock_time;
byte setup_count, active_count, recovery_count, recovery_count2, cycle_count;
- int bus_speed = ide_system_bus_speed();
+ int bus_speed = system_bus_clock();
if (pio_mode > 5)
pio_mode = 5;
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 2aaf83b26..8e100de3c 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -19,8 +19,10 @@
#include <linux/delay.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
+
#include "ide_modes.h"
#ifndef SPLIT_BYTE
@@ -271,7 +273,7 @@ static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
int setup_time, active_time, recovery_time, clock_time, pio_mode, cycle_time;
byte recovery_count2, cycle_count;
int setup_count, active_count, recovery_count;
- int bus_speed = ide_system_bus_speed();
+ int bus_speed = system_bus_clock();
/*byte b;*/
ide_pio_data_t d;
@@ -645,6 +647,9 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name)
#endif
(void) pci_write_config_byte(dev, DRWTIM23, 0x3f);
(void) pci_write_config_byte(dev, DRWTIM3, 0x3f);
+#ifdef CONFIG_PPC
+ (void) pci_write_config_byte(dev, UDIDETCR0, 0xf0);
+#endif /* CONFIG_PPC */
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
if (!cmd64x_proc) {
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 4498b754b..3ecaa31ec 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -49,6 +49,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
@@ -140,9 +141,8 @@ static int calc_clk (int time, int bus_speed)
static void compute_clocks (byte pio, pio_clocks_t *p_pclk)
{
int clk1, clk2;
- int bus_speed;
+ int bus_speed = system_bus_clock(); /* get speed of PCI bus */
- bus_speed = ide_system_bus_speed(); /* get speed of PCI bus */
/* we don't check against CY82C693's min and max speed,
* so you can play with the idebus=xx parameter
*/
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index 28537d048..16fbceac2 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -15,6 +15,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index 096d75fc0..fa2e4b2ac 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -14,6 +14,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 170bf16f7..748068242 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -15,6 +15,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index 1c0b55dac..3ba8e55ee 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -47,6 +47,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
@@ -203,9 +204,10 @@ static int __init try_to_init_ht6560b(void)
static byte ht_pio2timings(ide_drive_t *drive, byte pio)
{
- int bus_speed, active_time, recovery_time;
+ int active_time, recovery_time;
int active_cycles, recovery_cycles;
ide_pio_data_t d;
+ int bus_speed = system_bus_clock();
if (pio) {
pio = ide_get_best_pio_mode(drive, pio, 5, &d);
@@ -215,7 +217,6 @@ static byte ht_pio2timings(ide_drive_t *drive, byte pio)
* actual cycle time for recovery and activity
* according system bus speed.
*/
- bus_speed = ide_system_bus_speed();
active_time = ide_pio_timings[pio].active_time;
recovery_time = d.cycle_time
- active_time
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 213ddbff0..8ef0f9356 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -19,6 +19,7 @@
#include <linux/errno.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/dma.h>
#include <asm/ecard.h>
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 17cc3eb88..78ad38337 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
- * Copyright (C) 1998, 1999 Jens Axboe <axboe@image.dk>
+ * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -16,8 +16,8 @@
* and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
* (SFF-8020i rev 2.6) standards. These documents can be obtained by
* anonymous ftp from:
- * ftp://fission.dt.wdc.com/pub/standards/SFF/specs/INF-8020.PDF
- * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r01.pdf
+ * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
+ * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
*
* Drives that deviate from these standards will be accomodated as much
* as possible via compile time or command-line options. Since I only have
@@ -272,10 +272,19 @@
* - Fixed a problem with WPI CDS-32X drive - it
* failed the capabilities
*
+ * 4.57 Apr 7, 2000 - Fixed sense reporting.
+ * - Fixed possible oops in ide_cdrom_get_last_session()
+ * - Fix locking mania and make ide_cdrom_reset relock
+ * - Stop spewing errors to log when magicdev polls with
+ * TEST_UNIT_READY on some drives.
+ * - Various fixes from Tobias Ringstrom:
+ * tray if it was locked prior to the reset.
+ * - cdrom_read_capacity returns one frame too little.
+ * - Fix real capacity reporting.
*
*************************************************************************/
-#define IDECD_VERSION "4.56"
+#define IDECD_VERSION "4.57"
#include <linux/config.h>
#include <linux/module.h>
@@ -314,11 +323,12 @@ static void cdrom_saw_media_change (ide_drive_t *drive)
static
-void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf,
- struct packet_command *failed_command)
+void cdrom_analyze_sense_data(ide_drive_t *drive,
+ struct packet_command *failed_command,
+ struct request_sense *sense)
{
- if (reqbuf->sense_key == NOT_READY ||
- reqbuf->sense_key == UNIT_ATTENTION) {
+ if (sense->sense_key == NOT_READY ||
+ sense->sense_key == UNIT_ATTENTION) {
/* Make good and sure we've seen this potential media change.
Some drives (i.e. Creative) fail to present the correct
sense key in the error register. */
@@ -330,13 +340,14 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf,
uses this command to poll the drive, and we don't want
to fill the syslog with useless errors. */
if (failed_command &&
- failed_command->c[0] == GPCMD_READ_SUBCHANNEL)
+ (failed_command->c[0] == GPCMD_READ_SUBCHANNEL ||
+ failed_command->c[0] == GPCMD_TEST_UNIT_READY))
return;
}
- if (reqbuf->error_code == 0x70 && reqbuf->sense_key == 0x02
- && ((reqbuf->asc == 0x3a && reqbuf->ascq == 0x00) ||
- (reqbuf->asc == 0x04 && reqbuf->ascq == 0x01)))
+ if (sense->error_code == 0x70 && sense->sense_key == 0x02
+ && ((sense->asc == 0x3a && sense->ascq == 0x00) ||
+ (sense->asc == 0x04 && sense->ascq == 0x01)))
{
/*
* Suppress the following errors:
@@ -353,30 +364,32 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf,
char buf[80];
printk ("ATAPI device %s:\n", drive->name);
- if (reqbuf->error_code==0x70)
+ if (sense->error_code==0x70)
printk(" Error: ");
- else if (reqbuf->error_code==0x71)
+ else if (sense->error_code==0x71)
printk(" Deferred Error: ");
+ else if (sense->error_code == 0x7f)
+ printk(" Vendor-specific Error: ");
else
printk(" Unknown Error Type: ");
- if ( reqbuf->sense_key < ARY_LEN (sense_key_texts))
- s = sense_key_texts[reqbuf->sense_key];
+ if (sense->sense_key < ARY_LEN(sense_key_texts))
+ s = sense_key_texts[sense->sense_key];
else
s = "bad sense key!";
- printk ("%s -- (Sense key=0x%02x)\n", s, reqbuf->sense_key);
+ printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
- if (reqbuf->asc == 0x40) {
- sprintf (buf, "Diagnostic failure on component 0x%02x",
- reqbuf->ascq);
+ if (sense->asc == 0x40) {
+ sprintf(buf, "Diagnostic failure on component 0x%02x",
+ sense->ascq);
s = buf;
} else {
- int lo=0, mid, hi=ARY_LEN (sense_data_texts);
- unsigned long key = (reqbuf->sense_key << 16);
- key |= (reqbuf->asc << 8);
- if ( ! (reqbuf->ascq >= 0x80 && reqbuf->ascq <= 0xdd) )
- key |= reqbuf->ascq;
+ int lo = 0, mid, hi = ARY_LEN(sense_data_texts);
+ unsigned long key = (sense->sense_key << 16);
+ key |= (sense->asc << 8);
+ if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
+ key |= sense->ascq;
s = NULL;
while (hi > lo) {
@@ -394,14 +407,14 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf,
}
if (s == NULL) {
- if (reqbuf->asc > 0x80)
+ if (sense->asc > 0x80)
s = "(vendor-specific error)";
else
s = "(reserved error code)";
}
- printk (" %s -- (asc=0x%02x, ascq=0x%02x)\n",
- s, reqbuf->asc, reqbuf->ascq);
+ printk(" %s -- (asc=0x%02x, ascq=0x%02x)\n",
+ s, sense->asc, sense->ascq);
if (failed_command != NULL) {
@@ -431,21 +444,21 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf,
* 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->sks[0] & 0x80)) {
- int progress = (reqbuf->sks[1] << 8 | reqbuf->sks[2]) * 100;
+ if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) {
+ int progress = (sense->sks[1] << 8 | sense->sks[2]) * 100;
printk(" Command is %02d%% complete\n", progress / 0xffff);
}
- if (reqbuf->sense_key == ILLEGAL_REQUEST &&
- (reqbuf->sks[0] & 0x80) != 0) {
- printk (" Error in %s byte %d",
- (reqbuf->sks[0] & 0x40) != 0 ?
+ if (sense->sense_key == ILLEGAL_REQUEST &&
+ (sense->sks[0] & 0x80) != 0) {
+ printk(" Error in %s byte %d",
+ (sense->sks[0] & 0x40) != 0 ?
"command packet" : "command data",
- (reqbuf->sks[1] << 8) + reqbuf->sks[2]);
+ (sense->sks[1] << 8) + sense->sks[2]);
- if ((reqbuf->sks[0] & 0x40) != 0)
- printk (" bit %d", reqbuf->sks[0] & 0x07);
+ if ((sense->sks[0] & 0x40) != 0)
+ printk (" bit %d", sense->sks[0] & 0x07);
printk ("\n");
}
@@ -456,45 +469,43 @@ void cdrom_analyze_sense_data (ide_drive_t *drive, struct request_sense *reqbuf,
/* Suppress printing unit attention and `in progress of becoming ready'
errors when we're not being verbose. */
- if (reqbuf->sense_key == UNIT_ATTENTION ||
- (reqbuf->sense_key == NOT_READY && (reqbuf->asc == 4 ||
- reqbuf->asc == 0x3a)))
+ if (sense->sense_key == UNIT_ATTENTION ||
+ (sense->sense_key == NOT_READY && (sense->asc == 4 ||
+ sense->asc == 0x3a)))
return;
- printk ("%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
+ printk("%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
drive->name,
- reqbuf->error_code, reqbuf->sense_key,
- reqbuf->asc, reqbuf->ascq);
+ sense->error_code, sense->sense_key,
+ sense->asc, sense->ascq);
#endif /* not VERBOSE_IDE_CD_ERRORS */
}
-static void cdrom_queue_request_sense (ide_drive_t *drive,
- struct semaphore *sem,
- struct packet_command *failed_command)
+static void cdrom_queue_request_sense(ide_drive_t *drive,
+ struct semaphore *sem,
+ struct request_sense *sense,
+ struct packet_command *failed_command)
{
struct cdrom_info *info = drive->driver_data;
struct request *rq;
- struct packet_command *pc;
+ struct packet_command *pc = &info->request_sense_pc;
- /* Make up a new request to retrieve sense information. */
- pc = &info->request_sense_pc;
- memset(pc, 0, sizeof (*pc));
+ if (sense == NULL)
+ sense = &info->sense_data;
+ memset(pc, 0, sizeof(struct packet_command));
pc->c[0] = GPCMD_REQUEST_SENSE;
-
- /* just get the first 18 bytes of the sense info, there might not
- * be more available */
pc->c[4] = pc->buflen = 18;
- pc->buffer = (char *)&info->sense_data;
- pc->sense_data = (struct request_sense *)failed_command;
+ pc->buffer = (char *) sense;
+ pc->sense = (struct request_sense *) failed_command;
/* stuff the sense request in front of our current request */
rq = &info->request_sense_request;
- ide_init_drive_cmd (rq);
+ ide_init_drive_cmd(rq);
rq->cmd = REQUEST_SENSE_COMMAND;
- rq->buffer = (char *)pc;
+ rq->buffer = (char *) pc;
rq->sem = sem;
- (void) ide_do_drive_cmd (drive, rq, ide_preempt);
+ (void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
@@ -503,11 +514,10 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq;
if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) {
- struct packet_command *pc = (struct packet_command *)
- rq->buffer;
- cdrom_analyze_sense_data (drive,
- (struct request_sense *) (pc->buffer - pc->c[4]),
- (struct packet_command *) pc->sense_data);
+ struct packet_command *pc = (struct packet_command *)rq->buffer;
+ cdrom_analyze_sense_data(drive,
+ (struct packet_command *) pc->sense,
+ (struct request_sense *) (pc->buffer - pc->c[4]));
}
if (rq->cmd == READ && !rq->current_nr_sectors)
uptodate = 1;
@@ -523,7 +533,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
{
struct request *rq = HWGROUP(drive)->rq;
int stat, cmd, err, sense_key;
- struct packet_command *pc = (struct packet_command *) rq->buffer;
+ struct packet_command *pc;
/* Check for errors. */
stat = GET_STAT();
@@ -547,6 +557,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
from the drive (probably while trying
to recover from a former error). Just give up. */
+ pc = (struct packet_command *) rq->buffer;
pc->stat = 1;
cdrom_end_request (1, drive);
*startstop = ide_error (drive, "request sense failure", stat);
@@ -556,6 +567,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
/* All other functions, except for READ. */
struct semaphore *sem = NULL;
+ pc = (struct packet_command *) rq->buffer;
/* Check for tray open. */
if (sense_key == NOT_READY) {
@@ -589,7 +601,8 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
cdrom_end_request (1, drive);
if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense(drive, sem, pc);
+ cdrom_queue_request_sense(drive, sem, pc->sense,
+ pc);
} else {
/* Handle errors from READ requests. */
@@ -628,7 +641,7 @@ static int cdrom_decode_status (ide_startstop_t *startstop, ide_drive_t *drive,
/* If we got a CHECK_CONDITION status,
queue a request sense command. */
if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense(drive, NULL, NULL);
+ cdrom_queue_request_sense(drive, NULL, NULL, NULL);
}
}
@@ -1062,11 +1075,11 @@ static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
pc.c[0] = GPCMD_READ_10;
pc.c[7] = (nframes >> 8);
pc.c[8] = (nframes & 0xff);
- put_unaligned(htonl (frame), (unsigned int *) &pc.c[2]);
+ put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]);
/* Send the command to the drive and return. */
- return cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c),
- &cdrom_read_intr);
+ return cdrom_transfer_packet_command(drive, pc.c, sizeof(pc.c),
+ &cdrom_read_intr);
}
@@ -1178,7 +1191,8 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
*/
/* Forward declarations. */
-static int cdrom_lockdoor(ide_drive_t *drive, int lockflag);
+static int cdrom_lockdoor(ide_drive_t *drive, int lockflag,
+ struct request_sense *sense);
/* Interrupt routine for packet command completion. */
static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
@@ -1186,11 +1200,8 @@ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
int ireason, len, stat, thislen;
struct request *rq = HWGROUP(drive)->rq;
struct packet_command *pc = (struct packet_command *)rq->buffer;
- struct cdrom_info *info = drive->driver_data;
ide_startstop_t startstop;
- pc->sense_data = &info->sense_data;
-
/* Check for errors. */
if (cdrom_decode_status (&startstop, drive, 0, &stat))
return startstop;
@@ -1320,8 +1331,12 @@ void cdrom_sleep (int time)
static
int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
{
- int retries = 10;
+ struct request_sense sense;
struct request req;
+ int retries = 10;
+
+ if (pc->sense == NULL)
+ pc->sense = &sense;
/* Start of retry loop. */
do {
@@ -1337,7 +1352,7 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
/* The request failed. Retry if it was due to a unit
attention status
(usually means media was changed). */
- struct request_sense *reqbuf = pc->sense_data;
+ struct request_sense *reqbuf = pc->sense;
if (reqbuf->sense_key == UNIT_ATTENTION)
cdrom_saw_media_change (drive);
@@ -1358,24 +1373,7 @@ int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
} while (pc->stat != 0 && retries >= 0);
/* Return an error if the command failed. */
- if (pc->stat)
- return -EIO;
-
- /* The command succeeded. If it was anything other than
- a request sense, eject, or door lock command,
- and we think that the door is presently unlocked, lock it
- again. (The door was probably unlocked via an explicit
- CDROMEJECT ioctl.) */
- if (CDROM_STATE_FLAGS (drive)->door_locked == 0 &&
- (pc->c[0] != GPCMD_TEST_UNIT_READY &&
- pc->c[0] != GPCMD_REQUEST_SENSE &&
- pc->c[0] != GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL &&
- pc->c[0] != GPCMD_START_STOP_UNIT &&
- pc->c[0] != GPCMD_MODE_SENSE_10 &&
- pc->c[0] != GPCMD_MODE_SELECT_10)) {
- (void) cdrom_lockdoor (drive, 1);
- }
- return 0;
+ return pc->stat ? -EIO : 0;
}
/****************************************************************************
@@ -1483,13 +1481,14 @@ int msf_to_lba (byte m, byte s, byte f)
return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
}
-static int cdrom_check_status (ide_drive_t *drive)
+static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
{
struct packet_command pc;
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo;
memset(&pc, 0, sizeof(pc));
+ pc.sense = sense;
pc.c[0] = GPCMD_TEST_UNIT_READY;
@@ -1506,24 +1505,26 @@ static int cdrom_check_status (ide_drive_t *drive)
/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
static int
-cdrom_lockdoor(ide_drive_t *drive, int lockflag)
+cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
{
- struct request_sense *sense;
+ struct request_sense my_sense;
struct packet_command pc;
int stat;
+ if (sense == NULL)
+ sense = &my_sense;
+
/* If the drive cannot lock the door, just pretend. */
- if (CDROM_CONFIG_FLAGS (drive)->no_doorlock)
+ if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
stat = 0;
- else {
+ } else {
memset(&pc, 0, sizeof(pc));
+ pc.sense = sense;
pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
pc.c[4] = (lockflag != 0);
stat = cdrom_queue_packet_command (drive, &pc);
}
- sense = pc.sense_data;
-
/* If we got an illegal field error, the drive
probably cannot lock the door. */
if (stat != 0 &&
@@ -1548,7 +1549,8 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag)
/* Eject the disk if EJECTFLAG is 0.
If EJECTFLAG is 1, try to reload the disk. */
-static int cdrom_eject(ide_drive_t *drive, int ejectflag)
+static int cdrom_eject(ide_drive_t *drive, int ejectflag,
+ struct request_sense *sense)
{
struct packet_command pc;
@@ -1560,13 +1562,15 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag)
return 0;
memset(&pc, 0, sizeof (pc));
+ pc.sense = sense;
pc.c[0] = GPCMD_START_STOP_UNIT;
pc.c[4] = 0x02 + (ejectflag != 0);
return cdrom_queue_packet_command (drive, &pc);
}
-static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity)
+static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity,
+ struct request_sense *sense)
{
struct {
__u32 lba;
@@ -1576,7 +1580,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity)
int stat;
struct packet_command pc;
- memset(&pc, 0, sizeof (pc));
+ memset(&pc, 0, sizeof(pc));
+ pc.sense = sense;
pc.c[0] = GPCMD_READ_CDVD_CAPACITY;
pc.buffer = (char *)&capbuf;
@@ -1584,17 +1589,19 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity)
stat = cdrom_queue_packet_command(drive, &pc);
if (stat == 0)
- *capacity = be32_to_cpu(capbuf.lba);
+ *capacity = 1 + be32_to_cpu(capbuf.lba);
return stat;
}
static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
- int format, char *buf, int buflen)
+ int format, char *buf, int buflen,
+ struct request_sense *sense)
{
struct packet_command pc;
memset(&pc, 0, sizeof(pc));
+ pc.sense = sense;
pc.buffer = buf;
pc.buflen = buflen;
@@ -1612,12 +1619,11 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
/* Try to read the entire TOC for the disk into our internal buffer. */
-static int cdrom_read_toc (ide_drive_t *drive)
+static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
{
int stat, ntracks, i;
struct cdrom_info *info = drive->driver_data;
struct atapi_toc *toc = info->toc;
- int minor = drive->select.b.unit << PARTN_BITS;
struct {
struct atapi_toc_header hdr;
struct atapi_toc_entry ent;
@@ -1637,13 +1643,13 @@ static int cdrom_read_toc (ide_drive_t *drive)
/* Check to see if the existing data is still valid.
If it is, just return. */
if (CDROM_STATE_FLAGS (drive)->toc_valid)
- (void) cdrom_check_status(drive);
+ (void) cdrom_check_status(drive, sense);
if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0;
/* First read just the header, so we know how long the TOC is. */
- stat = cdrom_read_tocentry (drive, 0, 1, 0, (char *)&toc->hdr,
- sizeof (struct atapi_toc_header));
+ stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
+ sizeof(struct atapi_toc_header), sense);
if (stat) return stat;
#if ! STANDARD_ATAPI
@@ -1658,10 +1664,11 @@ static int cdrom_read_toc (ide_drive_t *drive)
if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;
/* Now read the whole schmeer. */
- stat = cdrom_read_tocentry (drive, toc->hdr.first_track, 1, 0, (char *)&toc->hdr,
- sizeof (struct atapi_toc_header) +
- (ntracks + 1) *
- sizeof (struct atapi_toc_entry));
+ stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
+ (char *)&toc->hdr,
+ sizeof(struct atapi_toc_header) +
+ (ntracks + 1) *
+ sizeof(struct atapi_toc_entry), sense);
if (stat && toc->hdr.first_track > 1) {
/* Cds with CDI tracks only don't have any TOC entries,
@@ -1674,11 +1681,12 @@ static int cdrom_read_toc (ide_drive_t *drive)
the readable TOC is empty (CDI tracks are not included)
and only holds the Leadout entry. Heiko Eißfeldt */
ntracks = 0;
- stat = cdrom_read_tocentry (drive, CDROM_LEADOUT, 1,
- 0, (char *)&toc->hdr,
- sizeof (struct atapi_toc_header) +
- (ntracks+1) *
- sizeof (struct atapi_toc_entry));
+ stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
+ (char *)&toc->hdr,
+ sizeof(struct atapi_toc_header) +
+ (ntracks + 1) *
+ sizeof(struct atapi_toc_entry),
+ sense);
if (stat) {
return stat;
}
@@ -1722,8 +1730,8 @@ static int cdrom_read_toc (ide_drive_t *drive)
/* Read the multisession information. */
if (toc->hdr.first_track != CDROM_LEADOUT) {
/* Read the multisession information. */
- stat = cdrom_read_tocentry (drive, 0, 1, 1,
- (char *)&ms_tmp, sizeof (ms_tmp));
+ stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
+ sizeof(ms_tmp), sense);
if (stat) return stat;
} else {
ms_tmp.ent.addr.msf.minute = 0;
@@ -1749,45 +1757,23 @@ static int cdrom_read_toc (ide_drive_t *drive)
(long *)&toc->capacity);
if (stat)
#endif
- stat = cdrom_read_capacity (drive, &toc->capacity);
+ stat = cdrom_read_capacity(drive, &toc->capacity, sense);
if (stat) toc->capacity = 0x1fffff;
- /* for general /dev/cdrom like mounting, one big disc */
- drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
- HWIF(drive)->gd->sizes[minor] = (toc->capacity * SECTORS_PER_FRAME) >>
- (BLOCK_SIZE_BITS - 9);
-
/* Remember that we've read this stuff. */
CDROM_STATE_FLAGS (drive)->toc_valid = 1;
- /* should be "if multisession", but it does no harm. */
- if (ntracks == 1)
- return 0;
-
- /* setup each minor to respond to a session */
- minor++;
- i = toc->hdr.first_track;
- while ((i <= ntracks) && ((minor & CD_PART_MASK) < CD_PART_MAX)) {
- drive->part[minor & PARTN_MASK].start_sect = 0;
- drive->part[minor & PARTN_MASK].nr_sects =
- (toc->ent[i].addr.lba *
- SECTORS_PER_FRAME) << (BLOCK_SIZE_BITS - 9);
- HWIF(drive)->gd->sizes[minor] = (toc->ent[i].addr.lba *
- SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
- i++;
- minor++;
- }
-
return 0;
}
static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
- int buflen)
+ int buflen, struct request_sense *sense)
{
struct packet_command pc;
memset(&pc, 0, sizeof(pc));
+ pc.sense = sense;
pc.buffer = buf;
pc.buflen = buflen;
@@ -1802,10 +1788,12 @@ static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
/* ATAPI cdrom drives are free to select the speed you request or any slower
rate :-( Requesting too fast a speed will _not_ produce an error. */
-static int cdrom_select_speed (ide_drive_t *drive, int speed)
+static int cdrom_select_speed(ide_drive_t *drive, int speed,
+ struct request_sense *sense)
{
struct packet_command pc;
memset(&pc, 0, sizeof(pc));
+ pc.sense = sense;
if (speed == 0)
speed = 0xffff; /* set to max */
@@ -1825,7 +1813,7 @@ static int cdrom_select_speed (ide_drive_t *drive, int speed)
pc.c[5] = speed & 0xff;
}
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command(drive, &pc);
}
@@ -1869,10 +1857,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
pc.buffer = cgc->buffer;
pc.buflen = cgc->buflen;
cgc->stat = cdrom_queue_packet_command(drive, &pc);
-
- /* There was an error, assign sense. */
- if (cgc->stat)
- cgc->sense = pc.sense_data;
+ cgc->sense = pc.sense;
return cgc->stat;
}
@@ -1938,7 +1923,7 @@ int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
struct atapi_toc *toc;
/* Make sure our saved TOC is valid. */
- stat = cdrom_read_toc(drive);
+ stat = cdrom_read_toc(drive, NULL);
if (stat) return stat;
toc = info->toc;
@@ -1978,11 +1963,22 @@ static
int ide_cdrom_reset (struct cdrom_device_info *cdi)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ struct request_sense sense;
struct request req;
+ int ret;
ide_init_drive_cmd (&req);
req.cmd = RESET_DRIVE_COMMAND;
- return ide_do_drive_cmd (drive, &req, ide_wait);
+ ret = ide_do_drive_cmd(drive, &req, ide_wait);
+
+ /*
+ * A reset will unlock the door. If it was previously locked,
+ * lock it again.
+ */
+ if (CDROM_STATE_FLAGS(drive)->door_locked)
+ (void) cdrom_lockdoor(drive, 1, &sense);
+
+ return ret;
}
@@ -1990,120 +1986,33 @@ static
int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ struct request_sense sense;
if (position) {
- int stat = cdrom_lockdoor (drive, 0);
+ int stat = cdrom_lockdoor(drive, 0, &sense);
if (stat) return stat;
}
- return cdrom_eject(drive, !position);
+ return cdrom_eject(drive, !position, &sense);
}
static
int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
- return cdrom_lockdoor (drive, lock);
-}
-
-#undef __ACER50__
-
-#ifdef __ACER50__
-/*
- * the buffer struct used by ide_cdrom_get_capabilities()
- */
-struct get_capabilities_buf {
- char pad[8];
- struct atapi_capabilities_page cap; /* this is 4 bytes short of ATAPI standard */
- char extra_cap[4]; /* Acer 50X needs the regulation size buffer */
-};
-
-static
-int ide_cdrom_get_capabilities (struct cdrom_device_info *cdi, struct get_capabilities_buf *buf)
-{
- int stat, attempts = 3, buflen = sizeof(*buf);
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
- struct cdrom_generic_command cgc;
-
- /*
- * Most drives don't care about the buffer size;
- * they return as much info as there's room for.
- * But some older drives (?) had trouble with the
- * standard size, preferring 4 bytes less.
- * And the modern Acer 50X rejects anything smaller
- * than the standard size.
- */
- if (!(drive->id && !strcmp(drive->id->model,"ATAPI CD ROM DRIVE 50X MAX")))
- buflen -= sizeof(buf->extra_cap); /* for all drives except Acer 50X */
-
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
- stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
- if (stat == 0) {
- /*
- * The ACER/AOpen 24X cdrom has the speed
- * fields byte-swapped from the standard.
- */
- if (!(drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4))) {
- buf->cap.curspeed = ntohs(buf->cap.curspeed);
- buf->cap.maxspeed = ntohs(buf->cap.maxspeed);
- }
- CDROM_STATE_FLAGS (drive)->current_speed = (((unsigned int)buf->cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS(drive)->max_speed = (((unsigned int)buf->cap.maxspeed) + (176/2)) / 176;
- return 0;
- }
- } while (--attempts);
- return stat;
+ return cdrom_lockdoor(drive, lock, NULL);
}
-#endif /* __ACER50__ */
static
int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
{
-#ifndef __ACER50__
- int stat, attempts = 3;
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
- struct cdrom_generic_command cgc;
- struct {
- char pad[8];
- struct atapi_capabilities_page cap;
- } buf;
-#else
+ struct request_sense sense;
int stat;
- ide_drive_t *drive = (ide_drive_t*) cdi->handle;
- struct cdrom_generic_command cgc;
- struct get_capabilities_buf buf;
-#endif /* __ACER50__ */
- if ((stat = cdrom_select_speed (drive, speed)) < 0)
+ if ((stat = cdrom_select_speed (drive, speed, &sense)) < 0)
return stat;
- init_cdrom_command(&cgc, &buf, sizeof(buf), CGC_DATA_UNKNOWN);
-
-#ifndef __ACER50__
- /* Now with that done, update the speed fields */
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
- if (attempts-- <= 0)
- return 0;
- stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
- } while (stat);
-
- /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
- if (drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) {
- CDROM_STATE_FLAGS (drive)->current_speed =
- (((unsigned int)buf.cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS (drive)->max_speed =
- (((unsigned int)buf.cap.maxspeed) + (176/2)) / 176;
- } else {
- CDROM_STATE_FLAGS (drive)->current_speed =
- (ntohs(buf.cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS (drive)->max_speed =
- (ntohs(buf.cap.maxspeed) + (176/2)) / 176;
- }
-#else
- if (ide_cdrom_get_capabilities(cdi,&buf))
- return 0;
-#endif /* __ACER50__ */
-
cdi->speed = CDROM_STATE_FLAGS (drive)->current_speed;
return 0;
}
@@ -2112,19 +2021,18 @@ 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 request_sense *sense = &info->sense_data;
- int stat = cdrom_check_status(drive);
- if (stat == 0 || sense->sense_key == UNIT_ATTENTION)
+ struct 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)
+ if (sense.sense_key == NOT_READY && sense.asc == 0x04 &&
+ sense.ascq == 0x04)
return CDS_DISC_OK;
- if (sense->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. */
@@ -2132,9 +2040,8 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
}
return CDS_DRIVE_NOT_READY;
- } else {
- return -EINVAL;
}
+ return -EINVAL;
}
static
@@ -2144,8 +2051,14 @@ int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
struct atapi_toc *toc;
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
struct cdrom_info *info = drive->driver_data;
+ struct request_sense sense;
+ int ret;
toc = info->toc;
+ if (!CDROM_STATE_FLAGS(drive)->toc_valid || toc == NULL)
+ if ((ret = cdrom_read_toc(drive, &sense)))
+ return ret;
+
ms_info->addr.lba = toc->last_session_lba;
ms_info->xa_flag = toc->xa_flag;
@@ -2161,7 +2074,7 @@ int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
/* get MCN */
- if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf))))
+ if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
return stat;
memcpy (mcn_info->medium_catalog_number, mcnbuf+9,
@@ -2183,11 +2096,13 @@ int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
int slot_nr)
{
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ int retval;
if (slot_nr == CDSL_CURRENT) {
- (void) cdrom_check_status(drive);
+ (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;
+ return retval;
} else {
return -EINVAL;
}
@@ -2272,40 +2187,31 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots)
if (!CDROM_CONFIG_FLAGS (drive)->close_tray)
devinfo->mask |= CDC_CLOSE_TRAY;
- devinfo->de = devfs_register (drive->de, "cd", 2, DEVFS_FL_DEFAULT,
- HWIF(drive)->major, minor,
- S_IFBLK | S_IRUGO | S_IWUGO, 0, 0,
- ide_fops, NULL);
+ devinfo->de = devfs_register(drive->de, "cd", 2, DEVFS_FL_DEFAULT,
+ HWIF(drive)->major, minor,
+ S_IFBLK | S_IRUGO | S_IWUGO, 0, 0,
+ ide_fops, NULL);
- return register_cdrom (devinfo);
+ return register_cdrom(devinfo);
}
+/*
+ * the buffer struct used by ide_cdrom_get_capabilities()
+ */
+struct get_capabilities_buf {
+ char pad[8];
+ struct atapi_capabilities_page cap;
+ char extra_cap[4];
+};
static
-int ide_cdrom_probe_capabilities (ide_drive_t *drive)
+int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
{
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo;
-#ifndef __ACER50__
- int stat, nslots = 1, attempts = 3;
- struct cdrom_generic_command cgc;
- struct {
- char pad[8];
- struct atapi_capabilities_page cap;
- } buf;
-#else
- int nslots = 1;
struct cdrom_generic_command cgc;
- struct get_capabilities_buf buf;
-#endif /* __ACER50__ */
-
- if (CDROM_CONFIG_FLAGS (drive)->nec260) {
- CDROM_CONFIG_FLAGS (drive)->no_eject = 0;
- CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
- return nslots;
- }
+ int stat, attempts = 3;
- init_cdrom_command(&cgc, &buf, sizeof(buf), CGC_DATA_UNKNOWN);
/* we have to cheat a little here. the packet will eventually
* be queued with ide_cdrom_packet(), which extracts the
* drive from cdi->handle. Since this device hasn't been
@@ -2314,37 +2220,51 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
*/
cdi->handle = (ide_drive_t *) drive;
cdi->ops = &ide_cdrom_dops;
-#ifndef __ACER50__
- /* we seem to get stat=0x01,err=0x00 the first time (??) */
- do {
- if (attempts-- <= 0)
- return 0;
+ init_cdrom_command(&cgc, cap, sizeof(*cap), CGC_DATA_UNKNOWN);
+ do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
- } while (stat);
-#else
- if (ide_cdrom_get_capabilities(cdi,&buf))
+ if (!stat)
+ break;
+ } while (--attempts);
+ return stat;
+}
+
+static
+int ide_cdrom_probe_capabilities (ide_drive_t *drive)
+{
+ struct cdrom_info *info = drive->driver_data;
+ struct cdrom_device_info *cdi = &info->devinfo;
+ struct atapi_capabilities_page cap;
+ int nslots = 1;
+
+ if (CDROM_CONFIG_FLAGS (drive)->nec260) {
+ CDROM_CONFIG_FLAGS (drive)->no_eject = 0;
+ CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
+ return nslots;
+ }
+
+ if (ide_cdrom_get_capabilities(drive, &cap))
return 0;
-#endif /* __ACER50__ */
- if (buf.cap.lock == 0)
+ if (cap.lock == 0)
CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
- if (buf.cap.eject)
+ if (cap.eject)
CDROM_CONFIG_FLAGS (drive)->no_eject = 0;
- if (buf.cap.cd_r_write)
+ if (cap.cd_r_write)
CDROM_CONFIG_FLAGS (drive)->cd_r = 1;
- if (buf.cap.cd_rw_write)
+ if (cap.cd_rw_write)
CDROM_CONFIG_FLAGS (drive)->cd_rw = 1;
- if (buf.cap.test_write)
+ if (cap.test_write)
CDROM_CONFIG_FLAGS (drive)->test_write = 1;
- if (buf.cap.dvd_ram_read || buf.cap.dvd_r_read || buf.cap.dvd_rom)
+ if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom)
CDROM_CONFIG_FLAGS (drive)->dvd = 1;
- if (buf.cap.dvd_ram_write)
+ if (cap.dvd_ram_write)
CDROM_CONFIG_FLAGS (drive)->dvd_r = 1;
- if (buf.cap.dvd_r_write)
+ if (cap.dvd_r_write)
CDROM_CONFIG_FLAGS (drive)->dvd_ram = 1;
- if (buf.cap.audio_play)
+ if (cap.audio_play)
CDROM_CONFIG_FLAGS (drive)->audio_play = 1;
- if (buf.cap.mechtype == 0)
+ if (cap.mechtype == 0)
CDROM_CONFIG_FLAGS (drive)->close_tray = 0;
#if ! STANDARD_ATAPI
@@ -2355,28 +2275,26 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
else
#endif /* not STANDARD_ATAPI */
- if (buf.cap.mechtype == mechtype_individual_changer ||
- buf.cap.mechtype == mechtype_cartridge_changer) {
+ if (cap.mechtype == mechtype_individual_changer ||
+ cap.mechtype == mechtype_cartridge_changer) {
if ((nslots = cdrom_number_of_slots(cdi)) > 1) {
CDROM_CONFIG_FLAGS (drive)->is_changer = 1;
CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 1;
}
}
-#ifndef __ACER50__
/* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
if (drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) {
CDROM_STATE_FLAGS (drive)->current_speed =
- (((unsigned int)buf.cap.curspeed) + (176/2)) / 176;
+ (((unsigned int)cap.curspeed) + (176/2)) / 176;
CDROM_CONFIG_FLAGS (drive)->max_speed =
- (((unsigned int)buf.cap.maxspeed) + (176/2)) / 176;
+ (((unsigned int)cap.maxspeed) + (176/2)) / 176;
} else {
CDROM_STATE_FLAGS (drive)->current_speed =
- (ntohs(buf.cap.curspeed) + (176/2)) / 176;
+ (ntohs(cap.curspeed) + (176/2)) / 176;
CDROM_CONFIG_FLAGS (drive)->max_speed =
- (ntohs(buf.cap.maxspeed) + (176/2)) / 176;
+ (ntohs(cap.maxspeed) + (176/2)) / 176;
}
-#endif /* __ACER50__ */
/* don't print speed if the drive reported 0.
*/
@@ -2400,7 +2318,7 @@ int ide_cdrom_probe_capabilities (ide_drive_t *drive)
else
printk (" drive");
- printk (", %dkB Cache", be16_to_cpu(buf.cap.buffer_size));
+ printk (", %dkB Cache", be16_to_cpu(cap.buffer_size));
#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
@@ -2601,6 +2519,37 @@ int ide_cdrom_check_media_change (ide_drive_t *drive)
}
static
+void ide_cdrom_revalidate (ide_drive_t *drive)
+{
+ struct cdrom_info *info = drive->driver_data;
+ struct atapi_toc *toc;
+ int minor = drive->select.b.unit << PARTN_BITS;
+ struct request_sense sense;
+
+ cdrom_read_toc(drive, &sense);
+
+ if (!CDROM_STATE_FLAGS(drive)->toc_valid)
+ return;
+
+ toc = info->toc;
+
+ /* for general /dev/cdrom like mounting, one big disc */
+ drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
+ HWIF(drive)->gd->sizes[minor] = toc->capacity * BLOCKS_PER_FRAME;
+
+ blk_size[HWIF(drive)->major] = HWIF(drive)->gd->sizes;
+}
+
+static
+unsigned long ide_cdrom_capacity (ide_drive_t *drive)
+{
+ unsigned capacity;
+
+ capacity = cdrom_read_capacity(drive, &capacity, NULL);
+ return capacity ? 0 : capacity * SECTORS_PER_FRAME;
+}
+
+static
int ide_cdrom_cleanup(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
@@ -2635,13 +2584,14 @@ static ide_driver_t ide_cdrom_driver = {
ide_cdrom_open, /* open */
ide_cdrom_release, /* release */
ide_cdrom_check_media_change, /* media_change */
+ ide_cdrom_revalidate, /* revalidate */
NULL, /* pre_reset */
- NULL, /* capacity */
+ ide_cdrom_capacity, /* capacity */
NULL, /* special */
NULL /* proc */
};
-int ide_cdrom_init (void);
+int ide_cdrom_init(void);
static ide_module_t ide_cdrom_module = {
IDE_DRIVER_MODULE,
ide_cdrom_init,
@@ -2670,7 +2620,7 @@ void __exit ide_cdrom_exit(void)
}
#endif /* MODULE */
-int ide_cdrom_init (void)
+int ide_cdrom_init(void)
{
ide_drive_t *drive;
struct cdrom_info *info;
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 77937dd4b..bf603f596 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -10,6 +10,15 @@
#include <linux/cdrom.h>
#include <asm/byteorder.h>
+/*
+ * Apparently older drives have problems with filling out the entire
+ * mode_sense capability structure. Define this to 1 if your drive isn't
+ * probed correctly.
+ */
+#ifndef BROKEN_CAP_PAGE
+#define BROKEN_CAP_PAGE 0
+#endif
+
/* Turn this on to have the driver print out the meanings of the
ATAPI error codes. This will use up additional kernel-space
memory, though. */
@@ -43,6 +52,8 @@
#define SECTOR_BUFFER_SIZE (CD_FRAMESIZE * 32)
#define SECTORS_BUFFER (SECTOR_BUFFER_SIZE / SECTOR_SIZE)
+#define BLOCKS_PER_FRAME (CD_FRAMESIZE / BLOCK_SIZE)
+
#define MIN(a,b) ((a) < (b) ? (a) : (b))
/* special command codes for strategy routine. */
@@ -103,7 +114,7 @@ struct packet_command {
char *buffer;
int buflen;
int stat;
- struct request_sense *sense_data;
+ struct request_sense *sense;
unsigned char c[12];
};
@@ -187,6 +198,7 @@ struct atapi_cdrom_subchnl {
* generic stuff now in the Mt. Fuji spec.
*/
struct atapi_capabilities_page {
+ struct mode_page_header header;
#if defined(__BIG_ENDIAN_BITFIELD)
__u8 parameters_saveable : 1;
__u8 reserved1 : 1;
@@ -398,9 +410,9 @@ struct atapi_capabilities_page {
unsigned short buffer_size;
/* Current speed (in kB/s). */
unsigned short curspeed;
-
- /* Truncate the structure here, so we don't have headaches reading
- from older drives. */
+#if !BROKEN_CAP_PAGE
+ char pad[4];
+#endif
};
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index e8cfa5c7a..66bf35a70 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -512,6 +512,13 @@ static int idedisk_media_change (ide_drive_t *drive)
return drive->removable; /* if removable, always assume it was changed */
}
+static void idedisk_revalidate (ide_drive_t *drive)
+{
+ grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
+ 1<<PARTN_BITS,
+ current_capacity(drive));
+}
+
/*
* Compute drive->capacity, the full capacity of the drive
* Called with drive->id != NULL.
@@ -726,6 +733,7 @@ static ide_driver_t idedisk_driver = {
idedisk_open, /* open */
idedisk_release, /* release */
idedisk_media_change, /* media_change */
+ idedisk_revalidate, /* revalidate */
idedisk_pre_reset, /* pre_reset */
idedisk_capacity, /* capacity */
idedisk_special, /* special */
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 9caffd2f1..835fa91e3 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -368,7 +368,13 @@ int report_drive_dmaing (ide_drive_t *drive)
}
} else if ((id->field_valid & 4) &&
(id->dma_ultra & (id->dma_ultra >> 8) & 7)) {
- printk(", UDMA(33)"); /* UDMA BIOS-enabled! */
+ if ((id->dma_ultra >> 10) & 1) {
+ printk(", UDMA(33)"); /* UDMA BIOS-enabled! */
+ } else if ((id->dma_ultra >> 9) & 1) {
+ printk(", UDMA(25)"); /* UDMA BIOS-enabled! */
+ } else {
+ printk(", UDMA(16)"); /* UDMA BIOS-enabled! */
+ }
} else if (id->field_valid & 4) {
printk(", (U)DMA"); /* Can be BIOS-enabled! */
} else {
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 55349e92a..1130bd3d5 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -1376,6 +1376,16 @@ static int idefloppy_media_change (ide_drive_t *drive)
}
/*
+ * Revalidate the new media. Should set blk_size[]
+ */
+static void idefloppy_revalidate (ide_drive_t *drive)
+{
+ grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
+ 1<<PARTN_BITS,
+ current_capacity(drive));
+}
+
+/*
* Return the current floppy capacity to ide.c.
*/
static unsigned long idefloppy_capacity (ide_drive_t *drive)
@@ -1604,6 +1614,7 @@ static ide_driver_t idefloppy_driver = {
idefloppy_open, /* open */
idefloppy_release, /* release */
idefloppy_media_change, /* media_change */
+ idefloppy_revalidate, /* media_change */
NULL, /* pre_reset */
idefloppy_capacity, /* capacity */
NULL, /* special */
diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c
index 35ba5cb5f..8d999d91c 100644
--- a/drivers/ide/ide-pci.c
+++ b/drivers/ide/ide-pci.c
@@ -52,6 +52,8 @@
#define DEVID_NS87415 ((ide_pci_devid_t){PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87415})
#define DEVID_HT6565 ((ide_pci_devid_t){PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565})
#define DEVID_AEC6210 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF})
+#define DEVID_AEC6260 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860})
+#define DEVID_AEC6260R ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R})
#define DEVID_W82C105 ((ide_pci_devid_t){PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105})
#define DEVID_UM8673F ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F})
#define DEVID_UM8886A ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A})
@@ -66,17 +68,20 @@
#define IDE_IGNORE ((void *)-1)
-#ifdef CONFIG_BLK_DEV_AEC6210
-extern unsigned int pci_init_aec6210(struct pci_dev *, const char *);
-extern void ide_init_aec6210(ide_hwif_t *);
-extern void ide_dmacapable_aec6210(ide_hwif_t *, unsigned long);
-#define PCI_AEC6210 &pci_init_aec6210
-#define INIT_AEC6210 &ide_init_aec6210
-#define DMA_AEC6210 &ide_dmacapable_aec6210
+#ifdef CONFIG_BLK_DEV_AEC62XX
+extern unsigned int pci_init_aec62xx(struct pci_dev *, const char *);
+extern unsigned int ata66_aec62xx(ide_hwif_t *);
+extern void ide_init_aec62xx(ide_hwif_t *);
+extern void ide_dmacapable_aec62xx(ide_hwif_t *, unsigned long);
+#define PCI_AEC62XX &pci_init_aec62xx
+#define ATA66_AEC62XX &ata66_aec62xx
+#define INIT_AEC62XX &ide_init_aec62xx
+#define DMA_AEC62XX &ide_dmacapable_aec62xx
#else
-#define PCI_AEC6210 NULL
-#define INIT_AEC6210 NULL
-#define DMA_AEC6210 NULL
+#define PCI_AEC62XX NULL
+#define ATA66_AEC62XX NULL
+#define INIT_AEC62XX NULL
+#define DMA_AEC62XX NULL
#endif
#ifdef CONFIG_BLK_DEV_ALI15X3
@@ -318,7 +323,9 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = {
{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, INIT_AEC6210, DMA_AEC6210, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 },
+ {DEVID_AEC6210, "AEC6210", PCI_AEC62XX, NULL, INIT_AEC62XX, DMA_AEC62XX, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 },
+ {DEVID_AEC6260, "AEC6260", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 0 },
+ {DEVID_AEC6260R,"AEC6260R", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 },
{DEVID_W82C105, "W82C105", NULL, NULL, INIT_W82C105, DMA_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 },
{DEVID_UM8673F, "UM8673F", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
@@ -344,6 +351,8 @@ static unsigned int __init ide_special_settings (struct pci_dev *dev, const char
case PCI_DEVICE_ID_PROMISE_20246:
case PCI_DEVICE_ID_PROMISE_20262:
case PCI_DEVICE_ID_ARTOP_ATP850UF:
+ case PCI_DEVICE_ID_ARTOP_ATP860:
+ case PCI_DEVICE_ID_ARTOP_ATP860R:
return dev->irq;
default:
break;
@@ -592,6 +601,7 @@ check_if_enabled:
}
#ifdef CONFIG_BLK_DEV_IDEDMA
if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X))
autodma = 0;
if (autodma)
@@ -599,6 +609,8 @@ check_if_enabled:
if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) ||
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index d8edb89c5..cf49e1a66 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -17,6 +17,8 @@
*/
#include <linux/ide.h>
+#include <linux/init.h>
+
#include <linux/isapnp.h>
#ifndef PREPARE_FUNC
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 200204ee6..7c5130e77 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -204,6 +204,10 @@ static int try_to_identify (ide_drive_t *drive, byte cmd)
hd_status = IDE_STATUS_REG;
}
+ /* set features register for atapi identify command to be sure of reply */
+ if ((cmd == WIN_PIDENTIFY))
+ OUT_BYTE(0,IDE_FEATURE_REG); /* disable dma & overlap */
+
#if CONFIG_BLK_DEV_PDC4030
if (HWIF(drive)->chipset == ide_pdc4030) {
/* DC4030 hosted drives need their own identify... */
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index fd33e4e42..efc0ea717 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -73,10 +73,10 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
-#ifdef CONFIG_BLK_DEV_AEC6210
-extern byte aec6210_proc;
-int (*aec6210_display_info)(char *, char **, off_t, int) = NULL;
-#endif /* CONFIG_BLK_DEV_AEC6210 */
+#ifdef CONFIG_BLK_DEV_AEC62XX
+extern byte aec62xx_proc;
+int (*aec62xx_display_info)(char *, char **, off_t, int) = NULL;
+#endif /* CONFIG_BLK_DEV_AEC62XX */
#ifdef CONFIG_BLK_DEV_ALI15X3
extern byte ali_proc;
int (*ali_display_info)(char *, char **, off_t, int) = NULL;
@@ -801,10 +801,10 @@ void proc_ide_create(void)
create_proc_read_entry("drivers", 0, proc_ide_root,
proc_ide_read_drivers, NULL);
-#ifdef CONFIG_BLK_DEV_AEC6210
- if ((aec6210_display_info) && (aec6210_proc))
- create_proc_info_entry("aec6210", 0, proc_ide_root, aec6210_display_info);
-#endif /* CONFIG_BLK_DEV_AEC6210 */
+#ifdef CONFIG_BLK_DEV_AEC62XX
+ if ((aec62xx_display_info) && (aec62xx_proc))
+ create_proc_info_entry("aec62xx", 0, proc_ide_root, aec62xx_display_info);
+#endif /* CONFIG_BLK_DEV_AEC62XX */
#ifdef CONFIG_BLK_DEV_ALI15X3
if ((ali_display_info) && (ali_proc))
create_proc_info_entry("ali", 0, proc_ide_root, ali_display_info);
@@ -853,10 +853,10 @@ 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_AEC6210
- if ((aec6210_display_info) && (aec6210_proc))
- remove_proc_entry("ide/aec6210",0);
-#endif /* CONFIG_BLK_DEV_AEC6210 */
+#ifdef CONFIG_BLK_DEV_AEC62XX
+ if ((aec62xx_display_info) && (aec62xx_proc))
+ remove_proc_entry("ide/aec62xx",0);
+#endif /* CONFIG_BLK_DEV_AEC62XX */
#ifdef CONFIG_BLK_DEV_ALI15X3
if ((ali_display_info) && (ali_proc))
remove_proc_entry("ide/ali",0);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index c4424cf90..22fdcbfe5 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -5900,6 +5900,7 @@ static ide_driver_t idetape_driver = {
idetape_blkdev_open, /* open */
idetape_blkdev_release, /* release */
NULL, /* media_change */
+ NULL, /* revalidate */
idetape_pre_reset, /* pre_reset */
NULL, /* capacity */
NULL, /* special */
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index fb24fb0a5..712ec7502 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -343,7 +343,7 @@ int ide_system_bus_speed (void)
system_bus_speed = idebus_parameter; /* user supplied value */
#ifdef CONFIG_PCI
else if (pci_present())
- system_bus_speed = 40; /* safe default value for PCI */
+ system_bus_speed = 33; /* safe default value for PCI */
#endif /* CONFIG_PCI */
else
system_bus_speed = 50; /* safe default value for VESA and PCI */
@@ -1091,11 +1091,9 @@ static ide_startstop_t start_request (ide_drive_t *drive)
#endif
block = rq->sector;
blockend = block + rq->nr_sectors;
-#if 0
+
if ((rq->cmd == READ || rq->cmd == WRITE) &&
- (drive->media == ide_disk || drive->media == ide_floppy))
-#endif
- {
+ (drive->media == ide_disk || drive->media == ide_floppy)) {
if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) {
printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name,
(minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors);
@@ -1777,10 +1775,8 @@ int ide_revalidate_disk (kdev_t i_rdev)
drive->part[p].nr_sects = 0;
};
- grok_partitions(HWIF(drive)->gd, drive->select.b.unit,
- (drive->media != ide_disk &&
- drive->media != ide_floppy) ? 1 : 1<<PARTN_BITS,
- current_capacity(drive));
+ if (DRIVER(drive)->revalidate)
+ DRIVER(drive)->revalidate(drive);
drive->busy = 0;
wake_up(&drive->wqueue);
@@ -2095,7 +2091,9 @@ void ide_unregister (unsigned int index)
hwif->config_data = old_hwif.config_data;
hwif->select_data = old_hwif.select_data;
hwif->proc = old_hwif.proc;
+#ifndef CONFIG_BLK_DEV_IDECS
hwif->irq = old_hwif.irq;
+#endif /* CONFIG_BLK_DEV_IDECS */
hwif->major = old_hwif.major;
hwif->chipset = old_hwif.chipset;
hwif->autodma = old_hwif.autodma;
@@ -2447,8 +2445,18 @@ int ide_wait_cmd (ide_drive_t *drive, int cmd, int nsect, int feature, int secto
*/
void ide_delay_50ms (void)
{
+#if 0
unsigned long timeout = jiffies + ((HZ + 19)/20) + 1;
while (0 < (signed long)(timeout - jiffies));
+#else
+ __set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ/20);
+#endif
+}
+
+int system_bus_clock (void)
+{
+ return((int) ((!system_bus_speed) ? ide_system_bus_speed() : system_bus_speed ));
}
static int ide_ioctl (struct inode *inode, struct file *file,
@@ -3350,7 +3358,7 @@ static void default_pre_reset (ide_drive_t *drive)
static unsigned long default_capacity (ide_drive_t *drive)
{
- return 0x7fffffff; /* cdrom or tape */
+ return 0x7fffffff;
}
static ide_startstop_t default_special (ide_drive_t *drive)
@@ -3578,6 +3586,8 @@ EXPORT_SYMBOL(hwif_unregister);
EXPORT_SYMBOL(get_info_ptr);
EXPORT_SYMBOL(current_capacity);
+EXPORT_SYMBOL(system_bus_clock);
+
/*
* This is gets invoked once during initialization, to set *everything* up
*/
@@ -3589,7 +3599,7 @@ int __init ide_init (void)
if (!banner_printed) {
printk(KERN_INFO "Uniform Multi-Platform E-IDE driver " REVISION "\n");
ide_devfs_handle = devfs_mk_dir (NULL, "ide", 3, NULL);
- (void) ide_system_bus_speed();
+ system_bus_speed = ide_system_bus_speed();
banner_printed = 1;
}
diff --git a/drivers/ide/ide_modes.h b/drivers/ide/ide_modes.h
index ff71b2c2c..766145dd6 100644
--- a/drivers/ide/ide_modes.h
+++ b/drivers/ide/ide_modes.h
@@ -124,8 +124,11 @@ static struct ide_pio_info {
{ "QUANTUM LPS540A", 3 },
{ "QUANTUM LIGHTNING 540A", 3 },
{ "QUANTUM LIGHTNING 730A", 3 },
- { "QUANTUM FIREBALL", 3 }, /* For models 540/640/1080/1280 */
- /* 1080A works fine in mode4 with triton */
+
+ { "QUANTUM FIREBALL_540", 3 }, /* Older Quantum Fireballs don't work */
+ { "QUANTUM FIREBALL_640", 3 },
+ { "QUANTUM FIREBALL_1080", 3 },
+ { "QUANTUM FIREBALL_1280", 3 },
{ NULL, 0 }
};
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c
index 46a14ba19..26e4bfae0 100644
--- a/drivers/ide/macide.c
+++ b/drivers/ide/macide.c
@@ -18,6 +18,7 @@
#include <linux/hdreg.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/machw.h>
#include <asm/macintosh.h>
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 7a24fce25..70f185108 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -20,6 +20,7 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c
index 277f2f490..f11c41d99 100644
--- a/drivers/ide/opti621.c
+++ b/drivers/ide/opti621.c
@@ -215,8 +215,9 @@ typedef struct pio_clocks_s {
static void compute_clocks(int pio, pio_clocks_t *clks)
{
if (pio != PIO_NOT_EXIST) {
- int adr_setup, data_pls, bus_speed;
- bus_speed = ide_system_bus_speed();
+ int adr_setup, data_pls;
+ int bus_speed = system_bus_clock();
+
adr_setup = ide_pio_timings[pio].setup_time;
data_pls = ide_pio_timings[pio].active_time;
clks->address_time = cmpt_clk(adr_setup, bus_speed);
diff --git a/drivers/ide/pdc4030.c b/drivers/ide/pdc4030.c
index f42c4946f..5fe8c06a8 100644
--- a/drivers/ide/pdc4030.c
+++ b/drivers/ide/pdc4030.c
@@ -82,6 +82,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index fa453e7d5..fafd0533f 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -61,6 +61,7 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/delay.h>
+#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/ide/qd6580.c b/drivers/ide/qd6580.c
index bccf1eb6a..ad56c295c 100644
--- a/drivers/ide/qd6580.c
+++ b/drivers/ide/qd6580.c
@@ -20,6 +20,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/ide/rapide.c b/drivers/ide/rapide.c
index baa293467..a842a3287 100644
--- a/drivers/ide/rapide.c
+++ b/drivers/ide/rapide.c
@@ -13,6 +13,7 @@
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/ecard.h>
diff --git a/drivers/ide/rz1000.c b/drivers/ide/rz1000.c
index 5bd3db7d5..244d15e27 100644
--- a/drivers/ide/rz1000.c
+++ b/drivers/ide/rz1000.c
@@ -28,6 +28,7 @@
#include <linux/hdreg.h>
#include <linux/pci.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index 37da5577a..581992c63 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -170,7 +170,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
reg2, reg3);
rc = pci_read_config_byte(bmide_dev, 0x4b, &reg);
- p += sprintf(p, "Drvie 0: Postwrite %s \t \t Postwrite %s\n",
+ p += sprintf(p, "Drive 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",
@@ -194,7 +194,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
rc = pci_read_config_byte(bmide_dev, 0x4b, &reg);
- p += sprintf(p, "Drvie 1: Postwrite %s \t \t Postwrite %s\n",
+ p += sprintf(p, "Drive 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",
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c
index 5c1168972..296d001f2 100644
--- a/drivers/ide/umc8672.c
+++ b/drivers/ide/umc8672.c
@@ -48,6 +48,7 @@
#include <linux/blkdev.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/init.h>
#include <asm/io.h>
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index bf8e27640..f9d96a865 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/via82cxxx.c Version 0.08 Mar. 18, 2000
+ * linux/drivers/ide/via82cxxx.c Version 0.09 Apr. 02, 2000
*
* Copyright (C) 1998-99 Michel Aubry, Maintainer
* Copyright (C) 1999 Jeff Garzik, MVP4 Support
@@ -93,27 +93,127 @@
#include <asm/io.h>
+#include "ide_modes.h"
+
static struct pci_dev *host_dev = NULL;
static struct pci_dev *isa_dev = NULL;
+struct chipset_bus_clock_list_entry {
+ byte xfer_speed;
+
+ byte chipset_settings_25;
+ byte ultra_settings_25;
+ byte chipset_settings_33;
+ byte ultra_settings_33;
+ byte chipset_settings_37;
+ byte ultra_settings_37;
+ byte chipset_settings_41;
+ byte ultra_settings_41;
+};
+
+static struct chipset_bus_clock_list_entry * via82cxxx_table = NULL;
+
+struct chipset_bus_clock_list_entry via82cxxx_type_one [] = {
+ /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
+ { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { XFER_UDMA_3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { XFER_UDMA_2, 0x60, 0x20, 0x60, 0x20, 0x60, 0x21, 0x00, 0x00 },
+ { XFER_UDMA_1, 0x61, 0x20, 0x61, 0x20, 0x61, 0x21, 0x00, 0x00 },
+ { XFER_UDMA_0, 0x62, 0x20, 0x62, 0x20, 0x62, 0x21, 0x00, 0x00 },
+
+ { XFER_MW_DMA_2, 0x03, 0x20, 0x03, 0x20, 0x03, 0x21, 0x00, 0x00 },
+ { XFER_MW_DMA_1, 0x03, 0x31, 0x03, 0x31, 0x03, 0x32, 0x00, 0x00 },
+ { XFER_MW_DMA_0, 0x03, 0x31, 0x03, 0x31, 0x03, 0x32, 0x00, 0x00 },
+
+ { XFER_PIO_4, 0x03, 0x20, 0x03, 0x20, 0x03, 0x21, 0x00, 0x00 },
+ { XFER_PIO_3, 0x03, 0x31, 0x03, 0x31, 0x03, 0x32, 0x00, 0x00 },
+ { XFER_PIO_2, 0x03, 0x65, 0x03, 0x65, 0x03, 0x76, 0x00, 0x00 },
+ { XFER_PIO_1, 0x03, 0x65, 0x03, 0x65, 0x03, 0x76, 0x00, 0x00 },
+ { XFER_PIO_0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 },
+ { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 }
+};
+
+struct chipset_bus_clock_list_entry via82cxxx_type_two [] = {
+ /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
+ { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { XFER_UDMA_3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { XFER_UDMA_2, 0xE0, 0x20, 0xE0, 0x20, 0xE1, 0x31, 0xE1, 0x32 },
+ { XFER_UDMA_1, 0xE1, 0x20, 0xE1, 0x20, 0xE2, 0x31, 0xE2, 0x32 },
+ { XFER_UDMA_0, 0xE2, 0x20, 0xE2, 0x20, 0xE2, 0x31, 0xE2, 0x32 },
+
+ { XFER_MW_DMA_2, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 },
+ { XFER_MW_DMA_1, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 },
+ { XFER_MW_DMA_0, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 },
+
+ { XFER_PIO_4, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 },
+ { XFER_PIO_3, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 },
+ { XFER_PIO_2, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 },
+ { XFER_PIO_1, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 },
+ { XFER_PIO_0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE },
+ { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE }
+};
+
+struct chipset_bus_clock_list_entry via82cxxx_type_three [] = {
+ /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
+ { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { XFER_UDMA_3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { XFER_UDMA_2, 0xE0, 0x20, 0xE0, 0x20, 0xE1, 0x31, 0xE1, 0x32 },
+ { XFER_UDMA_1, 0xE1, 0x20, 0xE1, 0x20, 0xE2, 0x31, 0xE2, 0x32 },
+ { XFER_UDMA_0, 0xE2, 0x20, 0xE2, 0x20, 0xE2, 0x31, 0xE2, 0x32 },
+
+ { XFER_MW_DMA_2, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 },
+ { XFER_MW_DMA_1, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 },
+ { XFER_MW_DMA_0, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 },
+
+ { XFER_PIO_4, 0x03, 0x20, 0x03, 0x20, 0x03, 0x31, 0x03, 0x32 },
+ { XFER_PIO_3, 0x03, 0x31, 0x03, 0x31, 0x03, 0x42, 0x03, 0x53 },
+ { XFER_PIO_2, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 },
+ { XFER_PIO_1, 0x03, 0x65, 0x03, 0x65, 0x03, 0x87, 0x03, 0xA8 },
+ { XFER_PIO_0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE },
+ { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE }
+};
+
+struct chipset_bus_clock_list_entry via82cxxx_type_four [] = {
+ /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */
+ { XFER_UDMA_4, 0x00, 0x00, 0xE0, 0x20, 0xE1, 0x31, 0x00, 0x00 },
+ { XFER_UDMA_3, 0x00, 0x00, 0xE1, 0x20, 0xE2, 0x31, 0x00, 0x00 },
+ { XFER_UDMA_2, 0x00, 0x00, 0xE2, 0x20, 0xE4, 0x31, 0x00, 0x00 },
+ { XFER_UDMA_1, 0x00, 0x00, 0xE4, 0x20, 0xE6, 0x31, 0x00, 0x00 },
+ { XFER_UDMA_0, 0x00, 0x00, 0xE6, 0x20, 0xE6, 0x31, 0x00, 0x00 },
+
+ { XFER_MW_DMA_2, 0x00, 0x00, 0x03, 0x20, 0x03, 0x31, 0x00, 0x00 },
+ { XFER_MW_DMA_1, 0x00, 0x00, 0x03, 0x31, 0x03, 0x42, 0x00, 0x00 },
+ { XFER_MW_DMA_0, 0x00, 0x00, 0x03, 0x31, 0x03, 0x42, 0x00, 0x00 },
+
+ { XFER_PIO_4, 0x00, 0x00, 0x03, 0x20, 0x03, 0x31, 0x00, 0x00 },
+ { XFER_PIO_3, 0x00, 0x00, 0x03, 0x31, 0x03, 0x42, 0x00, 0x00 },
+ { XFER_PIO_2, 0x00, 0x00, 0x03, 0x65, 0x03, 0x87, 0x00, 0x00 },
+ { XFER_PIO_1, 0x00, 0x00, 0x03, 0x65, 0x03, 0x87, 0x00, 0x00 },
+ { XFER_PIO_0, 0x00, 0x00, 0x03, 0xA8, 0x03, 0xDB, 0x00, 0x00 },
+ { 0, 0x00, 0x00, 0x03, 0xA8, 0x03, 0xDB, 0x00, 0x00 }
+};
+
static const struct {
const char *name;
+ unsigned short vendor_id;
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 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, },
- { "VT 8371", PCI_DEVICE_ID_VIA_8371_0, },
- { "VT 8601", PCI_DEVICE_ID_VIA_8601_0, },
+ { "VT 82C585 Apollo VP1/VPX", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C585, },
+ { "VT 82C595 Apollo VP2", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C595, },
+ { "VT 82C597 Apollo VP3", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, },
+ { "VT 82C598 Apollo MVP3", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_0, },
+ { "VT 82C598 Apollo MVP3", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C598_0, },
+ { "VT 82C680 Apollo P6", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C680, },
+ { "VT 82C691 Apollo Pro", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C691, },
+ { "VT 82C693 Apollo Pro Plus", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C693, },
+ { "Apollo MVP4", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8501_0, },
+ { "VT 8371", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_0, },
+ { "VT 8601", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, },
+ { "AMD IronGate", PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_7006, },
};
#define NUM_APOLLO_ISA_CHIP_DEVICES 2
+#define VIA_FLAG_NULL 0x00000000
#define VIA_FLAG_CHECK_REV 0x00000001
#define VIA_FLAG_ATA_66 0x00000002
@@ -121,18 +221,20 @@ static const struct {
unsigned short host_id;
unsigned short isa_id;
unsigned int flags;
+ struct chipset_bus_clock_list_entry * chipset_table;
} 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, VIA_FLAG_ATA_66 },
- { 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 },
- { PCI_DEVICE_ID_VIA_8371_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66 },
- { PCI_DEVICE_ID_VIA_8601_0, PCI_DEVICE_ID_VIA_8231, VIA_FLAG_ATA_66 },
+ { PCI_DEVICE_ID_VIA_82C585, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_82C595, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_82C597_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_82C598_0, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_NULL, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_82C680, PCI_DEVICE_ID_VIA_82C586_1, VIA_FLAG_CHECK_REV, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_82C691, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_ATA_66, via82cxxx_type_two },
+ { PCI_DEVICE_ID_VIA_82C693, PCI_DEVICE_ID_VIA_82C596, VIA_FLAG_NULL, via82cxxx_type_one },
+ { PCI_DEVICE_ID_VIA_8501_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66, via82cxxx_type_two },
+ { PCI_DEVICE_ID_VIA_8371_0, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66, via82cxxx_type_two },
+ { PCI_DEVICE_ID_VIA_8601_0, PCI_DEVICE_ID_VIA_8231, VIA_FLAG_ATA_66, via82cxxx_type_two },
+ { PCI_DEVICE_ID_AMD_FE_GATE_7006, PCI_DEVICE_ID_VIA_82C686, VIA_FLAG_ATA_66, via82cxxx_type_two },
};
#define arraysize(x) (sizeof(x)/sizeof(*(x)))
@@ -515,69 +617,40 @@ static int via_set_fifoconfig(ide_hwif_t *hwif)
}
#ifdef CONFIG_VIA82CXXX_TUNING
+static byte pci_bus_clock_list (byte speed, int ide_clock, struct chipset_bus_clock_list_entry * chipset_table)
+{
+ for ( ; chipset_table->xfer_speed ; chipset_table++)
+ if (chipset_table->xfer_speed == speed) {
+ switch(ide_clock) {
+ case 25: return chipset_table->chipset_settings_25;
+ case 33: return chipset_table->chipset_settings_33;
+ case 37: return chipset_table->chipset_settings_37;
+ case 41: return chipset_table->chipset_settings_41;
+ default: break;
+ }
+ }
+ return 0x00;
+}
-struct chipset_bus_clock_list_entry {
- unsigned short bus_speed;
- byte xfer_speed;
- byte chipset_settings;
-};
-
-PCI_DEVICE_ID_VIA_82C586_1
-PCI_DEVICE_ID_VIA_82C596
-PCI_DEVICE_ID_VIA_82C686
-PCI_DEVICE_ID_VIA_8231
-
-PCI_DEVICE_ID_VIA_82C586_1 TYPE_1
-PCI_DEVICE_ID_VIA_82C596 TYPE_2
-PCI_DEVICE_ID_VIA_82C686 TYPE_2
-PCI_DEVICE_ID_VIA_82C596 TYPE_3
-PCI_DEVICE_ID_VIA_82C686 TYPE_3
-PCI_DEVICE_ID_VIA_8231 TYPE_4
-
-struct chipset_bus_clock_list_entry ultra_33_base [] = {
-{ TYPE_1,25,0x00,0x00,0x60,0x61,0x62,0x03,0x20,0x31,0x65,0x65,0xA8 },
-{ TYPE_1,33,0x00,0x00,0x60,0x61,0x62,0x03,0x20,0x31,0x65,0x65,0xA8 },
-{ TYPE_1,37,0x00,0x00,0x60,0x61,0x62,0x03,0x21,0x32,0x76,0x76,0xA9 },
-{ TYPE_2,25,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
-{ TYPE_2,33,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
-{ TYPE_2,37,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x31,0x42,0x87,0x87,0xDB },
-{ TYPE_2,41,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x32,0x53,0xA8,0xA8,0xFE },
-{ TYPE_3,25,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
-{ TYPE_3,33,0x00,0x00,0xE0,0xE1,0xE2,0x03,0x20,0x31,0x65,0x65,0xA8 },
-{ TYPE_3,37,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x31,0x42,0x87,0x87,0xDB },
-{ TYPE_3,41,0x00,0x00,0xE1,0xE2,0xE2,0x03,0x32,0x53,0xA8,0xA8,0xFE },
-{ TYPE_4,0,0,0,0,0,0,0,0,0,0,0,0 },
-{ 0,0,0,0,0,0,0,0,0,0,0,0,0 }
-};
-
-struct chipset_bus_clock_list_entry timing_66_base [] = {
- { 37, XFER_PIO_4, 0x21 },
- { 37, XFER_PIO_3, 0x32 },
- { 37, XFER_PIO_2, 0x76 },
- { 37, XFER_PIO_1, 0x76 },
- { 37, XFER_PIO_0, 0xA9 },
- { ANY, XFER_PIO_4, 0x20 },
- { ANY, XFER_PIO_3, 0x31 },
- { ANY, XFER_PIO_2, 0x65 },
- { ANY, XFER_PIO_1, 0x65 },
- { ANY, XFER_PIO_0, 0xA8 },
-};
-
-static byte pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table)
+static byte pci_bus_clock_list_ultra (byte speed, int ide_clock, struct chipset_bus_clock_list_entry * chipset_table)
{
for ( ; chipset_table->xfer_speed ; chipset_table++)
if (chipset_table->xfer_speed == speed) {
- return chipset_table->chipset_settings;
+ switch(ide_clock) {
+ case 25: return chipset_table->ultra_settings_25;
+ case 33: return chipset_table->ultra_settings_33;
+ case 37: return chipset_table->ultra_settings_37;
+ case 41: return chipset_table->ultra_settings_41;
+ default: break;
+ }
}
- return 0x01208585;
+ return 0x00;
}
static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
{
- struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- unsigned long dma_base = hwif->dma_base;
byte unit = (drive->select.b.unit & 0x01);
int drive_number = ((hwif->channel ? 2 : 0) + unit);
@@ -587,43 +660,23 @@ static int via82cxxx_tune_chipset (ide_drive_t *drive, byte speed)
byte ultra = 0x00;
int err;
- int bus_speed = ide_system_bus_speed();
+ int bus_speed = system_bus_clock();
switch(drive_number) {
- case 0: ata2_pci = 0x48; ata3_pci = 0x50; break;
- case 1: ata2_pci = 0x49; ata3_pci = 0x51; break;
- case 2: ata2_pci = 0x4a; ata3_pci = 0x52; break;
- case 3: ata2_pci = 0x4b; ata3_pci = 0x53; break;
+ case 0: ata2_pci = 0x4b; ata3_pci = 0x53; break;
+ case 1: ata2_pci = 0x4a; ata3_pci = 0x52; break;
+ case 2: ata2_pci = 0x49; ata3_pci = 0x51; break;
+ case 3: ata2_pci = 0x48; ata3_pci = 0x50; break;
default:
return -1;
}
pci_read_config_byte(dev, ata2_pci, &timing);
- pci_read_config_byte(dev, ata3_pci, &ultra);
-
- switch(speed) {
- case XFER_UDMA_4:
- case XFER_UDMA_3:
- case XFER_UDMA_2:
- case XFER_UDMA_1:
- case XFER_UDMA_0:
- case XFER_MW_DMA_2:
- case XFER_MW_DMA_1:
- case XFER_MW_DMA_0:
- case XFER_SW_DMA_2:
- case XFER_SW_DMA_1:
- case XFER_SW_DMA_0:
- case XFER_PIO_4:
- case XFER_PIO_3:
- case XFER_PIO_2:
- case XFER_PIO_1:
- case XFER_PIO_0:
- case XFER_PIO_SLOW:
- default:
- break;
- }
-
+ timing = pci_bus_clock_list(speed, bus_speed, via82cxxx_table);
pci_write_config_byte(dev, ata2_pci, timing);
+
+ pci_read_config_byte(dev, ata3_pci, &ultra);
+ ultra = pci_bus_clock_list_ultra(speed, bus_speed, via82cxxx_table);
pci_write_config_byte(dev, ata3_pci, ultra);
err = ide_config_drive_speed(drive, speed);
@@ -830,6 +883,8 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
if (ata33 | ata66)
printk(" Chipset Core ATA-%s", ata66 ? "66" : "33");
+
+ via82cxxx_table = ApolloISAChipInfo[j].chipset_table;
}
printk("\n");
}
@@ -847,8 +902,11 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name)
unsigned int __init ata66_via82cxxx (ide_hwif_t *hwif)
{
- /* (Jeff Garzik) FIXME!!! for MVP4 */
- return 0;
+ byte ata66 = 0;
+ byte ata66reg = hwif->channel ? 0x50 : 0x52;
+ pci_read_config_byte(hwif->pci_dev, ata66reg, &ata66);
+
+ return ((ata66 & 0x04) ? 1 : 0);
}
void __init ide_init_via82cxxx (ide_hwif_t *hwif)