diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-04-28 01:09:25 +0000 |
commit | b9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch) | |
tree | 42d07b0c7246ae2536a702e7c5de9e2732341116 /drivers/ide | |
parent | 7406b0a326f2d70ade2671c37d1beef62249db97 (diff) |
Merge with 2.3.99-pre6.
Diffstat (limited to 'drivers/ide')
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, ®54h); - - 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, ®54h); + 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, ®); - 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, ®); - 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) |