diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
commit | 6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch) | |
tree | 0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /drivers/ide | |
parent | ecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff) |
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine
status unknown.
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/Config.in | 31 | ||||
-rw-r--r-- | drivers/ide/Makefile | 24 | ||||
-rw-r--r-- | drivers/ide/aec62xx.c | 28 | ||||
-rw-r--r-- | drivers/ide/alim15x3.c | 50 | ||||
-rw-r--r-- | drivers/ide/amd7409.c | 74 | ||||
-rw-r--r-- | drivers/ide/cmd64x.c | 85 | ||||
-rw-r--r-- | drivers/ide/cs5530.c | 4 | ||||
-rw-r--r-- | drivers/ide/cy82c693.c | 4 | ||||
-rw-r--r-- | drivers/ide/gayle.c | 24 | ||||
-rw-r--r-- | drivers/ide/hd.c | 2 | ||||
-rw-r--r-- | drivers/ide/hpt34x.c | 10 | ||||
-rw-r--r-- | drivers/ide/hpt366.c | 436 | ||||
-rw-r--r-- | drivers/ide/icside.c | 6 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 32 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 19 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 53 | ||||
-rw-r--r-- | drivers/ide/ide-features.c | 48 | ||||
-rw-r--r-- | drivers/ide/ide-geometry.c | 4 | ||||
-rw-r--r-- | drivers/ide/ide-pci.c | 54 | ||||
-rw-r--r-- | drivers/ide/ide-pmac.c | 6 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 6 | ||||
-rw-r--r-- | drivers/ide/ide.c | 76 | ||||
-rw-r--r-- | drivers/ide/ns87415.c | 2 | ||||
-rw-r--r-- | drivers/ide/pdc202xx.c | 159 | ||||
-rw-r--r-- | drivers/ide/piix.c | 35 | ||||
-rw-r--r-- | drivers/ide/qd6580.c | 332 | ||||
-rw-r--r-- | drivers/ide/sis5513.c | 22 | ||||
-rw-r--r-- | drivers/ide/trm290.c | 4 | ||||
-rw-r--r-- | drivers/ide/via82cxxx.c | 48 |
29 files changed, 1096 insertions, 582 deletions
diff --git a/drivers/ide/Config.in b/drivers/ide/Config.in index b591b3563..2719f6f80 100644 --- a/drivers/ide/Config.in +++ b/drivers/ide/Config.in @@ -1,6 +1,8 @@ # # IDE ATA ATAPI Block device driver configuration # +# Andre Hedrick <andre@linux-ide.org> +# mainmenu_option next_comment comment 'IDE, ATA and ATAPI Block devices' @@ -21,6 +23,9 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_mbool ' Seagate Vendor Specific' CONFIG_BLK_DEV_IDEDISK_SEAGATE $CONFIG_BLK_DEV_IDEDISK_VENDOR dep_mbool ' Western Digital Vendor Specific' CONFIG_BLK_DEV_IDEDISK_WD $CONFIG_BLK_DEV_IDEDISK_VENDOR + define_bool CONFIG_BLK_DEV_COMMERIAL n + dep_mbool ' TiVo Commerial Application Specific' CONFIG_BLK_DEV_TIVO $CONFIG_BLK_DEV_COMMERIAL + dep_tristate ' PCMCIA IDE support' CONFIG_BLK_DEV_IDECS $CONFIG_BLK_DEV_IDE $CONFIG_PCMCIA 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 @@ -44,32 +49,28 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then 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 ' 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_mbool ' AEC62XX Tuning support' CONFIG_AEC62XX_TUNING $CONFIG_BLK_DEV_AEC62XX 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 dep_mbool ' AMD Viper ATA-66 Override (WIP)' CONFIG_AMD7409_OVERRIDE $CONFIG_BLK_DEV_AMD7409 $CONFIG_IDEDMA_PCI_WIP dep_bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X $CONFIG_BLK_DEV_IDEDMA_PCI - dep_mbool ' CMD64X chipset RAID (WIP)' CONFIG_CMD64X_RAID $CONFIG_BLK_DEV_CMD64X $CONFIG_IDEDMA_PCI_WIP - dep_bool ' CY82C693 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI + dep_bool ' CY82C693 chipset support' CONFIG_BLK_DEV_CY82C693 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Cyrix CS5530 MediaGX chipset support' CONFIG_BLK_DEV_CS5530 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' HPT34X chipset support' CONFIG_BLK_DEV_HPT34X $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' HPT34X AUTODMA support (WIP)' CONFIG_HPT34X_AUTODMA $CONFIG_BLK_DEV_HPT34X $CONFIG_IDEDMA_PCI_WIP dep_bool ' HPT366 chipset support' CONFIG_BLK_DEV_HPT366 $CONFIG_BLK_DEV_IDEDMA_PCI - dep_bool ' HPT366 Fast Interrupts (WIP)' CONFIG_HPT366_FIP $CONFIG_BLK_DEV_HPT366 $CONFIG_IDEDMA_PCI_WIP - dep_mbool ' HPT366 mode Three (WIP)' CONFIG_HPT366_MODE3 $CONFIG_BLK_DEV_HPT366 $CONFIG_IDEDMA_PCI_WIP if [ "$CONFIG_X86" = "y" -o "$CONFIG_IA64" = "y" ]; then dep_mbool ' Intel PIIXn chipsets support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI dep_mbool ' PIIXn Tuning support' CONFIG_PIIX_TUNING $CONFIG_BLK_DEV_PIIX $CONFIG_IDEDMA_PCI_AUTO fi dep_bool ' NS87415 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_NS87415 $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' OPTi 82C621 chipset enhanced support (EXPERIMENTAL)' CONFIG_BLK_DEV_OPTI621 $CONFIG_EXPERIMENTAL - dep_bool ' PROMISE PDC20246/PDC20262 support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI + dep_bool ' PROMISE PDC20246/PDC20262/PDC20267 support' CONFIG_BLK_DEV_PDC202XX $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Special UDMA Feature' CONFIG_PDC202XX_BURST $CONFIG_BLK_DEV_PDC202XX - dep_mbool ' Special Mode Feature (WIP)' CONFIG_PDC202XX_MASTER $CONFIG_BLK_DEV_PDC202XX $CONFIG_IDEDMA_PCI_WIP 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_bool ' VIA82CXXX chipset support' 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 @@ -81,14 +82,13 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then dep_bool ' PowerMac IDE DMA support' CONFIG_BLK_DEV_IDEDMA_PMAC $CONFIG_BLK_DEV_IDE_PMAC dep_bool ' Use DMA by default' CONFIG_IDEDMA_PMAC_AUTO $CONFIG_BLK_DEV_IDEDMA_PMAC define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PMAC - define_bool CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_BLK_DEV_IDEDMA_PMAC + define_bool CONFIG_BLK_DEV_IDEPCI $CONFIG_BLK_DEV_IDEDMA_PMAC fi if [ "$CONFIG_ARCH_ACORN" = "y" ]; then dep_bool ' ICS IDE interface support' CONFIG_BLK_DEV_IDE_ICSIDE $CONFIG_ARCH_ACORN dep_bool ' ICS DMA support' CONFIG_BLK_DEV_IDEDMA_ICS $CONFIG_BLK_DEV_IDE_ICSIDE dep_bool ' Use ICS DMA by default' CONFIG_IDEDMA_ICS_AUTO $CONFIG_BLK_DEV_IDEDMA_ICS define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS - define_bool CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_BLK_DEV_IDEDMA_ICS dep_bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN fi if [ "$CONFIG_AMIGA" = "y" ]; then @@ -132,6 +132,17 @@ else define_bool CONFIG_IDEDMA_AUTO n fi +if [ "$CONFIG_BLK_DEV_IDEDMA_PCI" = "y" -o \ + "$CONFIG_BLK_DEV_IDEDMA_PMAC" = "y" -o \ + "$CONFIG_BLK_DEV_IDEDMA_ICS" = "y" ]; then + bool ' IGNORE word93 Validation BITS' CONFIG_IDEDMA_IVB +fi + +if [ "$CONFIG_BLK_DEV_TIVO" = "y" ]; then + define_bool CONFIG_DMA_NONPCI y +else + define_bool CONFIG_DMA_NONPCI n +fi if [ "$CONFIG_IDE_CHIPSETS" = "y" -o \ "$CONFIG_BLK_DEV_AEC62XX" = "y" -o \ "$CONFIG_BLK_DEV_ALI15X3" = "y" -o \ diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 028dbcffe..2ffc5855e 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -18,11 +18,11 @@ SUB_DIRS := MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) -L_TARGET := ide.a -L_OBJS := ide-geometry.o +O_TARGET := idedriver.o +O_OBJS := ide-geometry.o M_OBJS := MOD_LIST_NAME := IDE_MODULES -LX_OBJS := +OX_OBJS := MX_OBJS := ifeq ($(CONFIG_BLK_DEV_AEC62XX),y) @@ -78,7 +78,7 @@ IDE_OBJS += q40ide.o endif ifeq ($(CONFIG_BLK_DEV_HD),y) -L_OBJS += hd.o +O_OBJS += hd.o endif ifeq ($(CONFIG_BLK_DEV_HPT34X),y) @@ -97,7 +97,7 @@ ifeq ($(CONFIG_BLK_DEV_IDE_ICSIDE),y) IDE_OBJS += icside.o endif -ifeq ($(CONFIG_BLK_DEV_IDEDMA_PCI),y) +ifeq ($(CONFIG_BLK_DEV_IDEDMA),y) IDE_OBJS += ide-dma.o endif @@ -178,8 +178,8 @@ endif ###Collect ifeq ($(CONFIG_BLK_DEV_IDE),y) - LX_OBJS += ide.o ide-features.o - L_OBJS += ide-probe.o $(IDE_OBJS) + OX_OBJS += ide.o ide-features.o + O_OBJS += ide-probe.o $(IDE_OBJS) else ifeq ($(CONFIG_BLK_DEV_IDE),m) MIX_OBJS += ide.o ide-features.o $(IDE_OBJS) @@ -190,7 +190,7 @@ endif ############ ifeq ($(CONFIG_BLK_DEV_IDECS),y) -L_OBJS += ide-cs.o +O_OBJS += ide-cs.o else ifeq ($(CONFIG_BLK_DEV_IDECS),m) M_OBJS += ide-cs.o @@ -198,7 +198,7 @@ else endif ifeq ($(CONFIG_BLK_DEV_IDEDISK),y) -L_OBJS += ide-disk.o +O_OBJS += ide-disk.o else ifeq ($(CONFIG_BLK_DEV_IDEDISK),m) M_OBJS += ide-disk.o @@ -206,7 +206,7 @@ else endif ifeq ($(CONFIG_BLK_DEV_IDECD),y) -L_OBJS += ide-cd.o +O_OBJS += ide-cd.o else ifeq ($(CONFIG_BLK_DEV_IDECD),m) M_OBJS += ide-cd.o @@ -214,7 +214,7 @@ else endif ifeq ($(CONFIG_BLK_DEV_IDETAPE),y) -L_OBJS += ide-tape.o +O_OBJS += ide-tape.o else ifeq ($(CONFIG_BLK_DEV_IDETAPE),m) M_OBJS += ide-tape.o @@ -222,7 +222,7 @@ else endif ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),y) -L_OBJS += ide-floppy.o +O_OBJS += ide-floppy.o else ifeq ($(CONFIG_BLK_DEV_IDEFLOPPY),m) M_OBJS += ide-floppy.o diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c index 75b3153b7..2f3d2fc3a 100644 --- a/drivers/ide/aec62xx.c +++ b/drivers/ide/aec62xx.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/aec62xx.c Version 0.08 Mar. 28, 2000 + * linux/drivers/ide/aec62xx.c Version 0.09 June. 9, 2000 * - * Copyright (C) 2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick (andre@linux-ide.org) * May be copied or modified under the terms of the GNU General Public License * */ @@ -55,7 +55,7 @@ static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; u8 art = 0, uart = 0; @@ -358,7 +358,7 @@ static int config_aec6260_chipset_for_dma (ide_drive_t *drive, byte ultra) 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; + byte ultra66 = eighty_ninty_three(drive); if (drive->media != ide_disk) return ((int) ide_dma_off_quietly); @@ -497,6 +497,23 @@ int aec62xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_lostirq: + case ide_dma_timeout: + switch(HWIF(drive)->pci_dev->device) { + case PCI_DEVICE_ID_ARTOP_ATP860: + case PCI_DEVICE_ID_ARTOP_ATP860R: +// { +// int i = 0; +// byte reg49h = 0; +// pci_read_config_byte(HWIF(drive)->pci_dev, 0x49, ®49h); +// for (i=0;i<256;i++) +// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h|0x10); +// pci_write_config_byte(HWIF(drive)->pci_dev, 0x49, reg49h & ~0x10); +// } +// return 0; + default: + break; + } default: break; } @@ -529,9 +546,6 @@ unsigned int __init ata66_aec62xx (ide_hwif_t *hwif) 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); } diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c index 02af0a0f8..41768bb90 100644 --- a/drivers/ide/alim15x3.c +++ b/drivers/ide/alim15x3.c @@ -1,17 +1,15 @@ /* - * linux/drivers/ide/alim15x3.c Version 0.09 Mar. 18, 2000 + * linux/drivers/ide/alim15x3.c Version 0.10 Jun. 9, 2000 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer + * Copyright (C) 1999-2000 CJ, cjtsai@ali.com.tw, Maintainer * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org) * May be copied or modified under the terms of the GNU General Public License * * (U)DMA capable version of ali 1533/1543(C), 1535(D) * - * version: 1.0 beta2 (Sep. 2, 1999) - * e-mail your problems to cjtsai@ali.com.tw - * ********************************************************************** * 9/7/99 --Parts from the above author are included and need to be * converted into standard interface, once I finish the thought. @@ -237,7 +235,6 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count) static byte m5229_revision = 0; static byte chip_is_1543c_e = 0; -static byte cable_80_pin[2] = { 0, 0 }; byte ali_proc = 0; static struct pci_dev *isa_dev; @@ -346,7 +343,7 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, byte speed) /* * enable ultra dma and set timing */ - tmpbyte |= ((0x08 | (4-speed)) << (unit << 2)); + tmpbyte |= ((0x08 | ((4-speed)&0x07)) << (unit << 2)); pci_write_config_byte(dev, m5229_udma, tmpbyte); if (speed >= XFER_UDMA_3) { pci_read_config_byte(dev, 0x4b, &tmpbyte); @@ -370,12 +367,14 @@ static void config_chipset_for_pio (ide_drive_t *drive) static int config_chipset_for_dma (ide_drive_t *drive, byte ultra33) { struct hd_driveid *id = drive->id; - ide_hwif_t *hwif = HWIF(drive); byte speed = 0x00; - byte ultra66 = ((hwif->udma_four) && (id->hw_config & 0x2000)) ? 1 : 0; + byte ultra66 = eighty_ninty_three(drive); + byte ultra100 = (m5229_revision>=0xc4) ? 1 : 0; int rval; - if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) { + if ((id->dma_ultra & 0x0020) && (ultra100) && (ultra66) && (ultra33)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra66) && (ultra33)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (ultra66) && (ultra33)) { speed = XFER_UDMA_3; @@ -454,7 +453,7 @@ static int ali15x3_config_drive_for_dma(ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, can_ultra_dma); if ((id->field_valid & 2) && @@ -508,13 +507,13 @@ static int ali15x3_dmaproc (ide_dma_action_t func, ide_drive_t *drive) unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) { - unsigned long fixdma_base = dev->resource[4].start; + unsigned long fixdma_base = pci_resource_start(dev, 4); pci_read_config_byte(dev, PCI_REVISION_ID, &m5229_revision); isa_dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); - if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + if (!fixdma_base) { /* * */ @@ -539,11 +538,16 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name) return 0; } +/* + * This checks if the controller and the cable are capable + * of UDMA66 transfers. It doesn't check the drives. + * But see note 2 below! + */ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - byte ata66mask = hwif->channel ? 0x02 : 0x01; unsigned int ata66 = 0; + byte cable_80_pin[2] = { 0, 0 }; unsigned long flags; byte tmpbyte; @@ -575,7 +579,7 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) * 1543C-B0 (m1533, 0x79, bit 2) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); - } else if (m5229_revision == 0xC3) { + } else if (m5229_revision >= 0xC3) { /* * 1553/1535 (m1533, 0x79, bit 1) */ @@ -596,6 +600,10 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) * has 80-pin (from host view) */ if (!(tmpbyte & 0x02)) cable_80_pin[1] = 1; + /* + * Allow ata66 if cable of current channel has 80 pins + */ + ata66 = (hwif->channel)?cable_80_pin[1]:cable_80_pin[0]; } else { /* * revision 0x20 (1543-E, 1543-F) @@ -625,18 +633,6 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) pci_write_config_byte(dev, 0x53, tmpbyte); - /* - * Ultra66 cable detection (from Host View) - * m5229, 0x4a, bit0: primary, bit1: secondary 80 pin - * - * 0x4a, bit0 is 0 => primary channel - * has 80-pin (from host view) - * - * 0x4a, bit1 is 0 => secondary channel - * has 80-pin (from host view) - */ - pci_read_config_byte(dev, 0x4a, &tmpbyte); - ata66 = (!(tmpbyte & ata66mask)) ? 1 : 0; __restore_flags(flags); return(ata66); diff --git a/drivers/ide/amd7409.c b/drivers/ide/amd7409.c index d54a240d4..ca23d3af4 100644 --- a/drivers/ide/amd7409.c +++ b/drivers/ide/amd7409.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/amd7409.c Version 0.04 Mar. 18, 2000 + * linux/drivers/ide/amd7409.c Version 0.05 June 9, 2000 * - * Copyright (C) 2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * */ @@ -40,7 +40,7 @@ static struct pci_dev *bmide_dev; static int amd7409_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* @@ -71,6 +71,20 @@ byte amd7409_proc = 0; extern char *ide_xfer_verbose (byte xfer_rate); +static unsigned int amd7409_swdma_check (struct pci_dev *dev) +{ + unsigned int class_rev; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + return ((int) (class_rev >= 7) ? 1 : 0); +} + +static int amd7409_swdma_error(ide_drive_t *drive) +{ + printk("%s: single-word DMA not support (revision < C4)\n", drive->name); + return 0; +} + /* * Here is where all the hard work goes to program the chipset. * @@ -122,64 +136,68 @@ static int amd7409_tune_chipset (ide_drive_t *drive, byte speed) case XFER_UDMA_4: ultra_timing |= 0x45; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_3: ultra_timing |= 0x44; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_2: ultra_timing |= 0x40; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_1: ultra_timing |= 0x41; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_UDMA_0: ultra_timing |= 0x42; dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_MW_DMA_2: dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_MW_DMA_1: dma_pio_timing |= 0x21; - pio_timing |= (0x03 << drive->dn); break; case XFER_MW_DMA_0: dma_pio_timing |= 0x77; - pio_timing |= (0x03 << drive->dn); + break; + case XFER_SW_DMA_2: + if (!amd7409_swdma_check(dev)) + return amd7409_swdma_error(drive); + dma_pio_timing |= 0x42; + break; + case XFER_SW_DMA_1: + if (!amd7409_swdma_check(dev)) + return amd7409_swdma_error(drive); + dma_pio_timing |= 0x65; + break; + case XFER_SW_DMA_0: + if (!amd7409_swdma_check(dev)) + return amd7409_swdma_error(drive); + dma_pio_timing |= 0xA8; break; #endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: dma_pio_timing |= 0x20; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_3: dma_pio_timing |= 0x22; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_2: dma_pio_timing |= 0x42; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_1: dma_pio_timing |= 0x65; - pio_timing |= (0x03 << drive->dn); break; case XFER_PIO_0: default: dma_pio_timing |= 0xA8; - pio_timing |= (0x03 << drive->dn); break; } + pio_timing |= (0x03 << drive->dn); + if (!drive->init_speed) drive->init_speed = speed; @@ -268,12 +286,14 @@ static void amd7409_tune_drive (ide_drive_t *drive, byte pio) static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - byte udma_66 = ((id->hw_config & 0x2000) && - (HWIF(drive)->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); + byte udma_100 = 0; byte speed = 0x00; int rval; - if ((id->dma_ultra & 0x0010) && (udma_66)) { + if ((id->dma_ultra & 0x0020) && (udma_66)&& (udma_100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (udma_66)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (udma_66)) { speed = XFER_UDMA_3; @@ -318,7 +338,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && @@ -327,12 +347,15 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } } else if (id->field_valid & 2) { try_dma_modes: - if (id->dma_mword & 0x0007) { + if ((id->dma_mword & 0x0007) || + ((id->dma_1word & 0x007) && + (amd7409_swdma_check(HWIF(drive)->pci_dev)))) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); 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; @@ -372,9 +395,14 @@ int amd7409_dmaproc (ide_dma_action_t func, ide_drive_t *drive) unsigned int __init pci_init_amd7409 (struct pci_dev *dev, const char *name) { - unsigned long fixdma_base = dev->resource[4].start; + unsigned long fixdma_base = pci_resource_start(dev, 4); + +#ifdef CONFIG_BLK_DEV_IDEDMA + if (!amd7409_swdma_check(dev)) + printk("%s: disabling single-word DMA support (revision < C4)\n", name); +#endif /* CONFIG_BLK_DEV_IDEDMA */ - if (!fixdma_base || fixdma_base == PCI_BASE_ADDRESS_IO_MASK) { + if (!fixdma_base) { /* * */ diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 7e9f0c7ee..6e45bf0e0 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c @@ -1,6 +1,6 @@ /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 * - * linux/drivers/ide/cmd64x.c Version 1.21 Mar. 18, 2000 + * linux/drivers/ide/cmd64x.c Version 1.22 June 9, 2000 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Note, this driver is not used at all on other systems because @@ -10,7 +10,7 @@ * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 David S. Miller (davem@redhat.com) - * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> */ #include <linux/config.h> @@ -41,6 +41,8 @@ * CMD64x specific registers definition. */ +#define CFR 0x50 +#define CFR_INTR_CH0 0x02 #define CNTRL 0x51 #define CNTRL_DIS_RA0 0x40 #define CNTRL_DIS_RA1 0x80 @@ -52,6 +54,7 @@ #define ARTTIM1 0x55 #define DRWTIM1 0x56 #define ARTTIM23 0x57 +#define ARTTIM23_INTR_CH1 0x04 #define ARTTIM23_DIS_RA2 0x04 #define ARTTIM23_DIS_RA3 0x08 #define ARTTIM2 0x57 @@ -63,6 +66,10 @@ #define BMIDECR0 0x70 #define MRDMODE 0x71 +#define MRDMODE_INTR_CH0 0x04 +#define MRDMODE_INTR_CH1 0x08 +#define MRDMODE_BLK_CH0 0x10 +#define MRDMODE_BLK_CH1 0x20 #define BMIDESR0 0x72 #define UDIDETCR0 0x73 #define DTPR0 0x74 @@ -90,9 +97,13 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) u8 reg57 = 0, reg58 = 0, reg5b; /* secondary */ u8 reg72 = 0, reg73 = 0; /* primary */ u8 reg7a = 0, reg7b = 0; /* secondary */ + u8 reg50 = 0, reg71 = 0; /* extra */ u8 hi_byte = 0, lo_byte = 0; switch(bmide_dev->device) { + case PCI_DEVICE_ID_CMD_649: + p += sprintf(p, "\n CMD649 Chipset.\n"); + break; case PCI_DEVICE_ID_CMD_648: p += sprintf(p, "\n CMD648 Chipset.\n"); break; @@ -106,6 +117,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, "\n CMD64? Chipse.\n"); break; } + (void) pci_read_config_byte(bmide_dev, CFR, ®50); (void) pci_read_config_byte(bmide_dev, ARTTIM0, ®53); (void) pci_read_config_byte(bmide_dev, DRWTIM0, ®54); (void) pci_read_config_byte(bmide_dev, ARTTIM1, ®55); @@ -113,6 +125,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) (void) pci_read_config_byte(bmide_dev, ARTTIM2, ®57); (void) pci_read_config_byte(bmide_dev, DRWTIM2, ®58); (void) pci_read_config_byte(bmide_dev, DRWTIM3, ®5b); + (void) pci_read_config_byte(bmide_dev, MRDMODE, ®71); (void) pci_read_config_byte(bmide_dev, BMIDESR0, ®72); (void) pci_read_config_byte(bmide_dev, UDIDETCR0, ®73); (void) pci_read_config_byte(bmide_dev, BMIDESR1, ®7a); @@ -128,42 +141,42 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) (reg72&0x20)?((reg73&0x01)?"UDMA":" DMA"):" PIO", (reg72&0x20)?( ((reg73&0x30)==0x30)?(((reg73&0x35)==0x35)?"3":"0"): ((reg73&0x20)==0x20)?(((reg73&0x25)==0x25)?"3":"1"): - ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"):"X"):"?", + ((reg73&0x10)==0x10)?(((reg73&0x15)==0x15)?"4":"2"): + ((reg73&0x00)==0x00)?(((reg73&0x05)==0x05)?"5":"2"):"X"):"?", (reg72&0x40)?((reg73&0x02)?"UDMA":" DMA"):" PIO", (reg72&0x40)?( ((reg73&0xC0)==0xC0)?(((reg73&0xC5)==0xC5)?"3":"0"): ((reg73&0x80)==0x80)?(((reg73&0x85)==0x85)?"3":"1"): - ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"):"X"):"?", + ((reg73&0x40)==0x40)?(((reg73&0x4A)==0x4A)?"4":"2"): + ((reg73&0x00)==0x00)?(((reg73&0x0A)==0x0A)?"5":"2"):"X"):"?", (reg7a&0x20)?((reg7b&0x01)?"UDMA":" DMA"):" PIO", (reg7a&0x20)?( ((reg7b&0x30)==0x30)?(((reg7b&0x35)==0x35)?"3":"0"): ((reg7b&0x20)==0x20)?(((reg7b&0x25)==0x25)?"3":"1"): - ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"):"X"):"?", + ((reg7b&0x10)==0x10)?(((reg7b&0x15)==0x15)?"4":"2"): + ((reg7b&0x00)==0x00)?(((reg7b&0x05)==0x05)?"5":"2"):"X"):"?", (reg7a&0x40)?((reg7b&0x02)?"UDMA":" DMA"):" PIO", (reg7a&0x40)?( ((reg7b&0xC0)==0xC0)?(((reg7b&0xC5)==0xC5)?"3":"0"): ((reg7b&0x80)==0x80)?(((reg7b&0x85)==0x85)?"3":"1"): - ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"):"X"):"?" ); + ((reg7b&0x40)==0x40)?(((reg7b&0x4A)==0x4A)?"4":"2"): + ((reg7b&0x00)==0x00)?(((reg7b&0x0A)==0x0A)?"5":"2"):"X"):"?" ); p += sprintf(p, "PIO Mode: %s %s %s %s\n", "?", "?", "?", "?"); - p += sprintf(p, "PIO\n"); - - SPLIT_BYTE(reg53, hi_byte, lo_byte); - p += sprintf(p, "ARTTIM0 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg53, hi_byte, lo_byte); - SPLIT_BYTE(reg54, hi_byte, lo_byte); - p += sprintf(p, "DRWTIM0 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg54, hi_byte, lo_byte); - SPLIT_BYTE(reg55, hi_byte, lo_byte); - p += sprintf(p, "ARTTIM1 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg55, hi_byte, lo_byte); - SPLIT_BYTE(reg56, hi_byte, lo_byte); - p += sprintf(p, "DRWTIM1 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg56, hi_byte, lo_byte); + p += sprintf(p, " %s %s\n", + (reg50 & CFR_INTR_CH0) ? "interrupting" : "polling ", + (reg57 & ARTTIM23_INTR_CH1) ? "interrupting" : "polling"); + p += sprintf(p, " %s %s\n", + (reg71 & MRDMODE_INTR_CH0) ? "pending" : "clear ", + (reg71 & MRDMODE_INTR_CH1) ? "pending" : "clear"); + p += sprintf(p, " %s %s\n", + (reg71 & MRDMODE_BLK_CH0) ? "blocked" : "enabled", + (reg71 & MRDMODE_BLK_CH1) ? "blocked" : "enabled"); + + SPLIT_BYTE(reg50, hi_byte, lo_byte); + p += sprintf(p, "CFR = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg50, hi_byte, lo_byte); SPLIT_BYTE(reg57, hi_byte, lo_byte); p += sprintf(p, "ARTTIM23 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg57, hi_byte, lo_byte); - SPLIT_BYTE(reg58, hi_byte, lo_byte); - p += sprintf(p, "DRWTIM2 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg58, hi_byte, lo_byte); - SPLIT_BYTE(reg5b, hi_byte, lo_byte); - p += sprintf(p, "DRWTIM3 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg5b, hi_byte, lo_byte); - SPLIT_BYTE(reg73, hi_byte, lo_byte); - p += sprintf(p, "UDIDETCR0 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg73, hi_byte, lo_byte); - SPLIT_BYTE(reg7b, hi_byte, lo_byte); - p += sprintf(p, "UDIDETCR1 = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg7b, hi_byte, lo_byte); + SPLIT_BYTE(reg71, hi_byte, lo_byte); + p += sprintf(p, "MRDMODE = 0x%02x, HI = 0x%02x, LOW = 0x%02x\n", reg71, hi_byte, lo_byte); return p-buffer; /* => must be less than 4k! */ } @@ -349,9 +362,9 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) #ifdef CONFIG_BLK_DEV_IDEDMA ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - byte unit = (drive->select.b.unit & 0x01); int err = 0; + byte unit = (drive->select.b.unit & 0x01); u8 pciU = (hwif->channel) ? UDIDETCR1 : UDIDETCR0; u8 pciD = (hwif->channel) ? BMIDESR1 : BMIDESR0; u8 regU = 0; @@ -369,6 +382,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) (void) pci_read_config_byte(dev, pciD, ®D); (void) pci_read_config_byte(dev, pciU, ®U); switch(speed) { + case XFER_UDMA_5: regU |= (unit ? 0x0A : 0x05); break; case XFER_UDMA_4: regU |= (unit ? 0x4A : 0x15); break; case XFER_UDMA_3: regU |= (unit ? 0x8A : 0x25); break; case XFER_UDMA_2: regU |= (unit ? 0x42 : 0x11); break; @@ -383,7 +397,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) #else int err = 0; - switch(speed) { + switch(speed) { #endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: cmd64x_tuneproc(drive, 4); break; case XFER_PIO_3: cmd64x_tuneproc(drive, 3); break; @@ -394,6 +408,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte speed) default: return 1; } + #ifdef CONFIG_BLK_DEV_IDEDMA (void) pci_write_config_byte(dev, pciU, regU); #endif /* CONFIG_BLK_DEV_IDEDMA */ @@ -420,10 +435,12 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul byte speed = 0x00; byte set_pio = 0x00; byte udma_33 = ((rev >= 0x05) || (ultra_66)) ? 1 : 0; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); + byte udma_100 = 0; int rval; switch(dev->device) { + case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break; case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_646: case PCI_DEVICE_ID_CMD_643: @@ -446,7 +463,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul * in the 646U2. * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. */ - if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { + if ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) { speed = XFER_UDMA_3; @@ -483,7 +502,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ul if (cmd64x_tune_chipset(drive, speed)) return ((int) ide_dma_off); - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + rval = (int)( ((id->dma_ultra >> 11) & 7) ? 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 : @@ -500,12 +519,15 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) unsigned int class_rev = 0; byte can_ultra_33 = 0; byte can_ultra_66 = 0; + byte can_ultra_100 = 0; ide_dma_action_t dma_func = ide_dma_on; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; switch(dev->device) { + case PCI_DEVICE_ID_CMD_649: + can_ultra_100 = 1; case PCI_DEVICE_ID_CMD_648: can_ultra_66 = 1; case PCI_DEVICE_ID_CMD_643: @@ -514,6 +536,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) case PCI_DEVICE_ID_CMD_646: can_ultra_33 = (class_rev >= 0x05) ? 1 : 0; can_ultra_66 = 0; + can_ultra_100 = 0; break; default: return hwif->dmaproc(ide_dma_off, drive); @@ -528,7 +551,7 @@ static int cmd64x_config_drive_for_dma (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if ((id->field_valid & 4) && (can_ultra_33)) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66); if ((id->field_valid & 2) && @@ -636,6 +659,7 @@ unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name) printk("\n"); break; case PCI_DEVICE_ID_CMD_648: + case PCI_DEVICE_ID_CMD_649: break; default: break; @@ -714,6 +738,7 @@ void __init ide_init_cmd64x (ide_hwif_t *hwif) #ifdef CONFIG_BLK_DEV_IDEDMA switch(dev->device) { + case PCI_DEVICE_ID_CMD_649: case PCI_DEVICE_ID_CMD_648: case PCI_DEVICE_ID_CMD_643: hwif->dmaproc = &cmd64x_dmaproc; diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c index b160d7716..fb531e813 100644 --- a/drivers/ide/cs5530.c +++ b/drivers/ide/cs5530.c @@ -1,7 +1,7 @@ /* * linux/drivers/ide/cs5530.c Version 0.6 Mar. 18, 2000 * - * Copyright (C) 2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Ditto of GNU General Public License. * * Copyright (C) 2000 Mark Lord <mlord@pobox.com> @@ -43,7 +43,7 @@ static struct pci_dev *bmide_dev; static int cs5530_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c index 3ecaa31ec..3e4961cbe 100644 --- a/drivers/ide/cy82c693.c +++ b/drivers/ide/cy82c693.c @@ -1,8 +1,8 @@ /* * linux/drivers/ide/cy82c693.c Version 0.34 Dec. 13, 1999 * - * Copyright (C) 1998-99 Andreas S. Krebs (akrebs@altavista.net), Maintainer - * Copyright (C) 1998-99 Andre Hedrick, Integrater + * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>, Integrater * * CYPRESS CY82C693 chipset IDE controller * diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index 748068242..2011b6a26 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c @@ -67,11 +67,13 @@ static int __init gayle_offsets[IDE_NR_PORTS] = { #define GAYLE_NUM_HWIFS 1 #define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS #define GAYLE_HAS_CONTROL_REG 1 +#define GAYLE_IDEREG_SIZE 0x2000 #else /* CONFIG_BLK_DEV_IDEDOUBLER */ #define GAYLE_NUM_HWIFS 2 #define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \ GAYLE_NUM_HWIFS-1) #define GAYLE_HAS_CONTROL_REG (!ide_doubler) +#define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) int ide_doubler = 0; /* support IDE doublers? */ #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ @@ -121,23 +123,27 @@ void __init gayle_init(void) ide_ack_intr_t *ack_intr; hw_regs_t hw; int index; + unsigned long phys_base, res_start, res_n; if (a4000) { - base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000); + phys_base = GAYLE_BASE_4000; irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000); ack_intr = gayle_ack_intr_a4000; } else { - base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200); + phys_base = GAYLE_BASE_1200; irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200); ack_intr = gayle_ack_intr_a1200; } + phys_base += i*GAYLE_NEXT_PORT; - if (GAYLE_HAS_CONTROL_REG) - ctrlport = base + GAYLE_CONTROL; - else - ctrlport = 0; + res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); + res_n = GAYLE_IDEREG_SIZE; - base += i*GAYLE_NEXT_PORT; + if (!request_mem_region(res_start, res_n, "IDE")) + continue; + + base = (ide_ioreg_t)ZTWO_VADDR(phys_base); + ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; ide_setup_ports(&hw, base, gayle_offsets, ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS); @@ -155,7 +161,9 @@ void __init gayle_init(void) break; #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ } - } + } else + release_mem_region(res_start, res_n); + #if 1 /* TESTING */ if (i == 1) { volatile u_short *addr = (u_short *)base; diff --git a/drivers/ide/hd.c b/drivers/ide/hd.c index eb73c2445..6fd109c83 100644 --- a/drivers/ide/hd.c +++ b/drivers/ide/hd.c @@ -889,7 +889,7 @@ static int parse_hd_setup (char *line) { (void) get_options(line, ARRAY_SIZE(ints), ints); hd_setup(NULL, ints); - return 0; + return 1; } __setup("hd=", parse_hd_setup); diff --git a/drivers/ide/hpt34x.c b/drivers/ide/hpt34x.c index 911068f78..cbd71e60a 100644 --- a/drivers/ide/hpt34x.c +++ b/drivers/ide/hpt34x.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/hpt34x.c Version 0.30 Mar. 18, 2000 + * linux/drivers/ide/hpt34x.c Version 0.31 June. 9, 2000 * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * @@ -62,7 +62,7 @@ static struct pci_dev *bmide_dev; static int hpt34x_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u8 c0 = 0, c1 = 0; /* @@ -360,7 +360,7 @@ int hpt34x_dmaproc (ide_dma_action_t func, ide_drive_t *drive) unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name) { int i = 0; - unsigned long hpt34xIoBase = dev->resource[4].start; + unsigned long hpt34xIoBase = pci_resource_start(dev, 4); unsigned short cmd; unsigned long flags; @@ -371,7 +371,7 @@ unsigned int __init pci_init_hpt34x (struct pci_dev *dev, const char *name) pci_read_config_word(dev, PCI_COMMAND, &cmd); if (cmd & PCI_COMMAND_MEMORY) { - if (dev->resource[PCI_ROM_RESOURCE].start) { + if (pci_resource_start(dev, PCI_ROM_RESOURCE)) { pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", dev->resource[PCI_ROM_RESOURCE].start); } diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c index 28232b576..74d3018c5 100644 --- a/drivers/ide/hpt366.c +++ b/drivers/ide/hpt366.c @@ -1,13 +1,16 @@ /* - * linux/drivers/ide/hpt366.c Version 0.17 Mar. 18, 2000 + * linux/drivers/ide/hpt366.c Version 0.18 June. 9, 2000 * - * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Thanks to HighPoint Technologies for their assistance, and hardware. * Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his * donation of an ABit BP6 mainboard, processor, and memory acellerated * development and support. + * + * Note that final HPT370 support was done by force extraction of GPL. + * */ #include <linux/config.h> @@ -30,13 +33,26 @@ #include "ide_modes.h" -#undef DISPLAY_HPT366_TIMINGS +#define DISPLAY_HPT366_TIMINGS #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> #endif /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */ +extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc); + +const char *quirk_drives[] = { + "QUANTUM FIREBALLlct08 08", + "QUANTUM FIREBALLP KA6.4", + "QUANTUM FIREBALLP LM20.5", + NULL +}; + +const char *bad_ata100_5[] = { + NULL +}; + const char *bad_ata66_4[] = { "WDC AC310200R", NULL @@ -60,70 +76,92 @@ const char *bad_ata33[] = { struct chipset_bus_clock_list_entry { byte xfer_speed; - unsigned int chipset_settings; + unsigned int chipset_settings_write; + unsigned int chipset_settings_read; }; struct chipset_bus_clock_list_entry forty_base [] = { - { XFER_UDMA_4 , 0x900fd943 }, - { XFER_UDMA_3 , 0x900ad943 }, - { XFER_UDMA_2 , 0x900bd943 }, - { XFER_UDMA_1 , 0x9008d943 }, - { XFER_UDMA_0 , 0x9008d943 }, - - { XFER_MW_DMA_2 , 0xa008d943 }, - { XFER_MW_DMA_1 , 0xa010d955 }, - { XFER_MW_DMA_0 , 0xa010d9fc }, - - { XFER_PIO_4 , 0xc008d963 }, - { XFER_PIO_3 , 0xc010d974 }, - { XFER_PIO_2 , 0xc010d997 }, - { XFER_PIO_1 , 0xc010d9c7 }, - { XFER_PIO_0 , 0xc018d9d9 }, - { 0 , 0x0120d9d9 } + { XFER_UDMA_4, 0x900fd943, 0x900fd943 }, + { XFER_UDMA_3, 0x900ad943, 0x900ad943 }, + { XFER_UDMA_2, 0x900bd943, 0x900bd943 }, + { XFER_UDMA_1, 0x9008d943, 0x9008d943 }, + { XFER_UDMA_0, 0x9008d943, 0x9008d943 }, + + { XFER_MW_DMA_2, 0xa008d943, 0xa008d943 }, + { XFER_MW_DMA_1, 0xa010d955, 0xa010d955 }, + { XFER_MW_DMA_0, 0xa010d9fc, 0xa010d9fc }, + + { XFER_PIO_4, 0xc008d963, 0xc008d963 }, + { XFER_PIO_3, 0xc010d974, 0xc010d974 }, + { XFER_PIO_2, 0xc010d997, 0xc010d997 }, + { XFER_PIO_1, 0xc010d9c7, 0xc010d9c7 }, + { XFER_PIO_0, 0xc018d9d9, 0xc018d9d9 }, + { 0, 0x0120d9d9, 0x0120d9d9 } }; struct chipset_bus_clock_list_entry thirty_three_base [] = { - { XFER_UDMA_4 , 0x90c9a731 }, - { XFER_UDMA_3 , 0x90cfa731 }, - { XFER_UDMA_2 , 0x90caa731 }, - { XFER_UDMA_1 , 0x90cba731 }, - { XFER_UDMA_0 , 0x90c8a731 }, - - { XFER_MW_DMA_2 , 0xa0c8a731 }, - { XFER_MW_DMA_1 , 0xa0c8a732 }, /* 0xa0c8a733 */ - { XFER_MW_DMA_0 , 0xa0c8a797 }, - - { XFER_PIO_4 , 0xc0c8a731 }, - { XFER_PIO_3 , 0xc0c8a742 }, - { XFER_PIO_2 , 0xc0d0a753 }, - { XFER_PIO_1 , 0xc0d0a7a3 }, /* 0xc0d0a793 */ - { XFER_PIO_0 , 0xc0d0a7aa }, /* 0xc0d0a7a7 */ - { 0 , 0x0120a7a7 } + { XFER_UDMA_4, 0x90c9a731, 0x90c9a731 }, + { XFER_UDMA_3, 0x90cfa731, 0x90cfa731 }, + { XFER_UDMA_2, 0x90caa731, 0x90caa731 }, + { XFER_UDMA_1, 0x90cba731, 0x90cba731 }, + { XFER_UDMA_0, 0x90c8a731, 0x90c8a731 }, + + { XFER_MW_DMA_2, 0xa0c8a731, 0xa0c8a731 }, + { XFER_MW_DMA_1, 0xa0c8a732, 0xa0c8a732 }, /* 0xa0c8a733 */ + { XFER_MW_DMA_0, 0xa0c8a797, 0xa0c8a797 }, + + { XFER_PIO_4, 0xc0c8a731, 0xc0c8a731 }, + { XFER_PIO_3, 0xc0c8a742, 0xc0c8a742 }, + { XFER_PIO_2, 0xc0d0a753, 0xc0d0a753 }, + { XFER_PIO_1, 0xc0d0a7a3, 0xc0d0a7a3 }, /* 0xc0d0a793 */ + { XFER_PIO_0, 0xc0d0a7aa, 0xc0d0a7aa }, /* 0xc0d0a7a7 */ + { 0, 0x0120a7a7, 0x0120a7a7 } }; struct chipset_bus_clock_list_entry twenty_five_base [] = { - { XFER_UDMA_4 , 0x90c98521 }, - { XFER_UDMA_3 , 0x90cf8521 }, - { XFER_UDMA_2 , 0x90cf8521 }, - { XFER_UDMA_1 , 0x90cb8521 }, - { XFER_UDMA_0 , 0x90cb8521 }, - - { XFER_MW_DMA_2 , 0xa0ca8521 }, - { XFER_MW_DMA_1 , 0xa0ca8532 }, - { XFER_MW_DMA_0 , 0xa0ca8575 }, - - { XFER_PIO_4 , 0xc0ca8521 }, - { XFER_PIO_3 , 0xc0ca8532 }, - { XFER_PIO_2 , 0xc0ca8542 }, - { XFER_PIO_1 , 0xc0d08572 }, - { XFER_PIO_0 , 0xc0d08585 }, - { 0 , 0x01208585 } + { XFER_UDMA_4, 0x90c98521, 0x90c98521 }, + { XFER_UDMA_3, 0x90cf8521, 0x90cf8521 }, + { XFER_UDMA_2, 0x90cf8521, 0x90cf8521 }, + { XFER_UDMA_1, 0x90cb8521, 0x90cb8521 }, + { XFER_UDMA_0, 0x90cb8521, 0x90cb8521 }, + + { XFER_MW_DMA_2, 0xa0ca8521, 0xa0ca8521 }, + { XFER_MW_DMA_1, 0xa0ca8532, 0xa0ca8532 }, + { XFER_MW_DMA_0, 0xa0ca8575, 0xa0ca8575 }, + + { XFER_PIO_4, 0xc0ca8521, 0xc0ca8521 }, + { XFER_PIO_3, 0xc0ca8532, 0xc0ca8532 }, + { XFER_PIO_2, 0xc0ca8542, 0xc0ca8542 }, + { XFER_PIO_1, 0xc0d08572, 0xc0d08572 }, + { XFER_PIO_0, 0xc0d08585, 0xc0d08585 }, + { 0, 0x01208585, 0x01208585 } +}; + +struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = { + { XFER_UDMA_5, 0x1A85F442, 0x16454e31 }, + { XFER_UDMA_4, 0x16454e31, 0x16454e31 }, + { XFER_UDMA_3, 0x166d4e31, 0x166d4e31 }, + { XFER_UDMA_2, 0x16494e31, 0x16494e31 }, + { XFER_UDMA_1, 0x164d4e31, 0x164d4e31 }, + { XFER_UDMA_0, 0x16514e31, 0x16514e31 }, + + { XFER_MW_DMA_2, 0x26514e21, 0x26514e21 }, + { XFER_MW_DMA_1, 0x26514e33, 0x26514e33 }, + { XFER_MW_DMA_0, 0x26514e97, 0x26514e97 }, + + { XFER_PIO_4, 0x06514e21, 0x06514e21 }, + { XFER_PIO_3, 0x06514e22, 0x06514e22 }, + { XFER_PIO_2, 0x06514e33, 0x06514e33 }, + { XFER_PIO_1, 0x06914e43, 0x06914e43 }, + { XFER_PIO_0, 0x06914e57, 0x06914e57 }, + { 0, 0x06514e57, 0x06514e57 } }; #define HPT366_DEBUG_DRIVE_INFO 0 +#define HPT370_ALLOW_ATA100_5 1 #define HPT366_ALLOW_ATA66_4 1 #define HPT366_ALLOW_ATA66_3 1 @@ -139,7 +177,12 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) char *p = buffer; u32 bibma = bmide_dev->resource[4].start; u32 bibma2 = bmide2_dev->resource[4].start; + char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; u8 c0 = 0, c1 = 0; + u32 class_rev; + + pci_read_config_dword(bmide_dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; /* * at that point bibma+0x2 et bibma+0xa are byte registers @@ -149,7 +192,7 @@ static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count) if (bmide2_dev) c1 = inb_p((unsigned short)bibma2 + 0x02); - p += sprintf(p, "\n HPT366 Chipset.\n"); + p += sprintf(p, "\n %s Chipset.\n", chipset_names[class_rev]); p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n"); p += sprintf(p, " %sabled %sabled\n", (c0&0x80) ? "dis" : " en", @@ -173,74 +216,74 @@ extern char *ide_xfer_verbose (byte xfer_rate); byte hpt363_shared_irq = 0; byte hpt363_shared_pin = 0; -static unsigned int pci_rev_check_hpt366 (struct pci_dev *dev) +static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev) { unsigned int class_rev; pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; - return ((int) (class_rev == 0x03) ? 1 : 0); + return ((int) (class_rev > 0x02) ? 1 : 0); } static int check_in_drive_lists (ide_drive_t *drive, const char **list) { struct hd_driveid *id = drive->id; -#if HPT366_DEBUG_DRIVE_INFO - printk("check_in_drive_lists(%s, %p)\n", drive->name, list); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - while (*list) { - if (!strcmp(*list++,id->model)) { -#ifdef DEBUG - printk("%s: Broken ASIC, BackSpeeding (U)DMA for %s\n", drive->name, id->model); -#endif /* DEBUG */ - return 1; + if (quirk_drives == list) { + while (*list) { + if (strstr(id->model, *list++)) { + return 1; + } + } + } else { + while (*list) { + if (!strcmp(*list++,id->model)) { + return 1; + } } } return 0; } -static unsigned int pci_bus_clock_list (byte speed, struct chipset_bus_clock_list_entry * chipset_table) +static unsigned int pci_bus_clock_list (byte speed, int direction, struct chipset_bus_clock_list_entry * chipset_table) { -#if HPT366_DEBUG_DRIVE_INFO - printk("pci_bus_clock_list(speed=0x%02x, table=%p)\n", speed, chipset_table); -#endif /* HPT366_DEBUG_DRIVE_INFO */ for ( ; chipset_table->xfer_speed ; chipset_table++) if (chipset_table->xfer_speed == speed) { -#if HPT366_DEBUG_DRIVE_INFO - printk("pci_bus_clock_list: found match: 0x%08x\n", chipset_table->chipset_settings); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - return chipset_table->chipset_settings; + return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read; } -#if HPT366_DEBUG_DRIVE_INFO - printk("pci_bus_clock_list: using default: 0x%08x\n", 0x01208585); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - return 0x01208585; + return (direction) ? chipset_table->chipset_settings_write : chipset_table->chipset_settings_read; } -static int hpt366_tune_chipset (ide_drive_t *drive, byte speed) +static void hpt366_tune_chipset (ide_drive_t *drive, byte speed, int direction) { - int err; byte regtime = (drive->select.b.unit & 0x01) ? 0x44 : 0x40; + byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; + /* + * since the channel is always 0 it does not matter. + */ + unsigned int reg1 = 0; unsigned int reg2 = 0; + byte drive_fast = 0; -#if HPT366_DEBUG_DRIVE_INFO - printk("hpt366_tune_chipset(%s, speed=0x%02x)\n", drive->name, speed); -#endif /* HPT366_DEBUG_DRIVE_INFO */ + /* + * Disable the "fast interrupt" prediction. + */ + pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast); + if (drive_fast & 0x02) + pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x20); pci_read_config_dword(HWIF(drive)->pci_dev, regtime, ®1); /* detect bus speed by looking at control reg timing: */ switch((reg1 >> 8) & 7) { case 5: - reg2 = pci_bus_clock_list(speed, forty_base); + reg2 = pci_bus_clock_list(speed, direction, forty_base); break; case 9: - reg2 = pci_bus_clock_list(speed, twenty_five_base); + reg2 = pci_bus_clock_list(speed, direction, twenty_five_base); break; default: - printk("hpt366: assuming 33Mhz PCI bus\n"); case 7: - reg2 = pci_bus_clock_list(speed, thirty_three_base); + reg2 = pci_bus_clock_list(speed, direction, thirty_three_base); break; } /* @@ -254,18 +297,56 @@ static int hpt366_tune_chipset (ide_drive_t *drive, byte speed) reg2 &= ~0x80000000; pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2); - err = ide_config_drive_speed(drive, speed); +} + +static void hpt370_tune_chipset (ide_drive_t *drive, byte speed, int direction) +{ + byte regfast = (HWIF(drive)->channel) ? 0x55 : 0x51; + byte reg5bh = (speed != XFER_UDMA_5) ? 0x22 : (direction) ? 0x20 : 0x22; + unsigned int list_conf = pci_bus_clock_list(speed, direction, thirty_three_base_hpt370); + unsigned int drive_conf = 0; + unsigned int conf_mask = (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000; + byte drive_pci = 0; + byte drive_fast = 0; + + switch (drive->dn) { + case 0: drive_pci = 0x40; break; + case 1: drive_pci = 0x44; break; + case 2: drive_pci = 0x48; break; + case 3: drive_pci = 0x4c; break; + default: return; + } + /* + * Disable the "fast interrupt" prediction. + */ + pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast); + if (drive_fast & 0x80) + pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x80); + + pci_read_config_dword(HWIF(drive)->pci_dev, drive_pci, &drive_conf); + pci_write_config_byte(HWIF(drive)->pci_dev, 0x5b, reg5bh); + + list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask); + /* + * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later) + */ + list_conf &= ~0x80000000; + + pci_write_config_dword(HWIF(drive)->pci_dev, drive_pci, list_conf); +} +static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed) +{ if (!drive->init_speed) drive->init_speed = speed; -#if HPT366_DEBUG_DRIVE_INFO - printk("%s: speed=0x%02x(%s), drive%d, old=0x%08x, new=0x%08x, err=0x%04x\n", - drive->name, speed, ide_xfer_verbose(speed), - drive->dn, reg1, reg2, err); -#endif /* HPT366_DEBUG_DRIVE_INFO */ + if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { + hpt370_tune_chipset(drive, speed, 0); + } else { + hpt366_tune_chipset(drive, speed, 0); + } drive->current_speed = speed; - return(err); + return ((int) ide_config_drive_speed(drive, speed)); } static void config_chipset_for_pio (ide_drive_t *drive) @@ -274,9 +355,6 @@ static void config_chipset_for_pio (ide_drive_t *drive) unsigned short xfer_pio = drive->id->eide_pio_modes; byte timing, speed, pio; -#if HPT366_DEBUG_DRIVE_INFO - printk("%s: config_chipset_for_pio\n", drive->name); -#endif /* HPT366_DEBUG_DRIVE_INFO */ pio = ide_get_best_pio_mode(drive, 255, 5, NULL); if (xfer_pio> 4) @@ -306,13 +384,10 @@ static void config_chipset_for_pio (ide_drive_t *drive) speed = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; break; } -#if HPT366_DEBUG_DRIVE_INFO - printk("%s: config_chipset_for_pio: speed=0x%04x\n", drive->name, speed); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - (void) hpt366_tune_chipset(drive, speed); + (void) hpt3xx_tune_chipset(drive, speed); } -static void hpt366_tune_drive (ide_drive_t *drive, byte pio) +static void hpt3xx_tune_drive (ide_drive_t *drive, byte pio) { byte speed; switch(pio) { @@ -322,7 +397,7 @@ static void hpt366_tune_drive (ide_drive_t *drive, byte pio) case 1: speed = XFER_PIO_1;break; default: speed = XFER_PIO_0;break; } - (void) hpt366_tune_chipset(drive, speed); + (void) hpt3xx_tune_chipset(drive, speed); } #ifdef CONFIG_BLK_DEV_IDEDMA @@ -341,18 +416,24 @@ static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; byte speed = 0x00; - byte reg51h = 0; + byte ultra66 = eighty_ninty_three(drive); int rval; - if ((id->dma_ultra & 0x0010) && - (!check_in_drive_lists(drive, bad_ata66_4)) && - (HPT366_ALLOW_ATA66_4) && - (HWIF(drive)->udma_four)) { + if ((id->dma_ultra & 0x0020) && + (!check_in_drive_lists(drive, bad_ata100_5)) && + (HPT370_ALLOW_ATA100_5) && + (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) && + (ultra66)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && + (!check_in_drive_lists(drive, bad_ata66_4)) && + (HPT366_ALLOW_ATA66_4) && + (ultra66)) { speed = XFER_UDMA_4; } else if ((id->dma_ultra & 0x0008) && (!check_in_drive_lists(drive, bad_ata66_3)) && (HPT366_ALLOW_ATA66_3) && - (HWIF(drive)->udma_four)) { + (ultra66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra && (!check_in_drive_lists(drive, bad_ata33))) { if (id->dma_ultra & 0x0004) { @@ -368,52 +449,56 @@ static int config_chipset_for_dma (ide_drive_t *drive) 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 { -#if HPT366_DEBUG_DRIVE_INFO - printk("%s: config_chipset_for_dma: returning 'ide_dma_off_quietly'\n", drive->name); -#endif /* HPT366_DEBUG_DRIVE_INFO */ + } else { return ((int) ide_dma_off_quietly); } - pci_read_config_byte(HWIF(drive)->pci_dev, 0x51, ®51h); + (void) hpt3xx_tune_chipset(drive, speed); -#ifdef CONFIG_HPT366_FIP - /* - * Some drives prefer/allow for the method of handling interrupts. - */ - if (!(reg51h & 0x80)) - pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h|0x80); -#else /* ! CONFIG_HPT366_FIP */ - /* - * Disable the "fast interrupt" prediction. - * Instead, always wait for the real interrupt from the drive! - */ - if (reg51h & 0x80) - pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, reg51h & ~0x80); -#endif /* CONFIG_HPT366_FIP */ -#if HPT366_DEBUG_DRIVE_INFO - printk("%s: config_chipset_for_dma: speed=0x%04x\n", drive->name, speed); -#endif /* HPT366_DEBUG_DRIVE_INFO */ - (void) hpt366_tune_chipset(drive, speed); - - rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + rval = (int)( ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : - ((id->dma_1word >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); - -#if HPT366_DEBUG_DRIVE_INFO - printk("%s: config_chipset_for_dma: returning %d (%s)\n", drive->name, rval, rval == ide_dma_on ? "dma_on" : "dma_off"); -#endif /* HPT366_DEBUG_DRIVE_INFO */ return rval; } +int hpt3xx_quirkproc (ide_drive_t *drive) +{ + return ((int) check_in_drive_lists(drive, quirk_drives)); +} + +void hpt3xx_intrproc (ide_drive_t *drive) +{ +} + +void hpt3xx_maskproc (ide_drive_t *drive, int mask) +{ + if (drive->quirk_list) { + if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) { + byte reg5a = 0; + pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5a); + if (((reg5a & 0x10) >> 4) != mask) + pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, mask ? (reg5a | 0x10) : (reg5a & ~0x10)); + } else { + if (mask) { + disable_irq(HWIF(drive)->irq); + } else { + enable_irq(HWIF(drive)->irq); + } + } + } else { + if (IDE_CONTROL_REG) + OUT_BYTE(mask ? (drive->ctl | 2) : (drive->ctl & ~2), IDE_CONTROL_REG); + } +} + +void hpt370_rw_proc (ide_drive_t *drive, ide_dma_action_t func) +{ + if ((func != ide_dma_write) || (func != ide_dma_read)) + return; + hpt370_tune_chipset(drive, drive->current_speed, (func == ide_dma_write)); +} + static int config_drive_xfer_rate (ide_drive_t *drive) { struct hd_driveid *id = drive->id; @@ -427,7 +512,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && @@ -436,8 +521,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } } else if (id->field_valid & 2) { try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { + if (id->dma_mword & 0x0007) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) @@ -472,24 +556,39 @@ no_dma_set: */ int hpt366_dmaproc (ide_dma_action_t func, ide_drive_t *drive) { - byte reg50h = 0; + byte reg50h = 0, reg52h = 0, reg5ah = 0; switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); case ide_dma_lostirq: -#if 0 - pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); - pci_write_config_byte(HWIF(drive)->pci_dev, 0x50, reg50h|0x03); pci_read_config_byte(HWIF(drive)->pci_dev, 0x50, ®50h); - /* ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); */ -#endif + pci_read_config_byte(HWIF(drive)->pci_dev, 0x52, ®52h); + pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, ®5ah); + printk("%s: (%s) reg50h=0x%02x, reg52h=0x%02x, reg5ah=0x%02x\n", + drive->name, + ide_dmafunc_verbose(func), + reg50h, reg52h, reg5ah); + if (reg5ah & 0x10) + pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10); + break; case ide_dma_timeout: default: break; } return ide_dmaproc(func, drive); /* use standard DMA stuff */ } + +int hpt370_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 */ unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name) @@ -519,7 +618,7 @@ unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name) if (!hpt366_proc) { hpt366_proc = 1; bmide_dev = dev; - if (pci_rev_check_hpt366(dev)) + if (pci_rev_check_hpt3xx(dev)) bmide2_dev = dev; hpt366_display_info = &hpt366_get_info; } @@ -546,14 +645,24 @@ unsigned int __init ata66_hpt366 (ide_hwif_t *hwif) void __init ide_init_hpt366 (ide_hwif_t *hwif) { - if (pci_rev_check_hpt366(hwif->pci_dev)) return; - - hwif->tuneproc = &hpt366_tune_drive; - hwif->speedproc = &hpt366_tune_chipset; + hwif->tuneproc = &hpt3xx_tune_drive; + hwif->speedproc = &hpt3xx_tune_chipset; + hwif->quirkproc = &hpt3xx_quirkproc; + hwif->intrproc = &hpt3xx_intrproc; + hwif->maskproc = &hpt3xx_maskproc; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { - hwif->dmaproc = &hpt366_dmaproc; + if (pci_rev_check_hpt3xx(hwif->pci_dev)) { + byte reg5ah = 0; + pci_read_config_byte(hwif->pci_dev, 0x5a, ®5ah); + if (reg5ah & 0x10) /* interrupt force enable */ + pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10); + hwif->dmaproc = &hpt370_dmaproc; + hwif->rwproc = &hpt370_rw_proc; + } else { + hwif->dmaproc = &hpt366_dmaproc; + } hwif->autodma = 1; } else { hwif->autodma = 0; @@ -571,19 +680,16 @@ void ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase) { byte masterdma = 0, slavedma = 0; byte dma_new = 0, dma_old = inb(dmabase+2); + byte primary = hwif->channel ? 0x4b : 0x43; + byte secondary = hwif->channel ? 0x4f : 0x47; unsigned long flags; - if (pci_rev_check_hpt366(hwif->pci_dev)) { - ide_setup_dma(hwif, dmabase, 8); - return; - } - __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ dma_new = dma_old; - pci_read_config_byte(hwif->pci_dev, 0x43, &masterdma); - pci_read_config_byte(hwif->pci_dev, 0x47, &slavedma); + pci_read_config_byte(hwif->pci_dev, primary, &masterdma); + pci_read_config_byte(hwif->pci_dev, secondary, &slavedma); if (masterdma & 0x30) dma_new |= 0x20; if (slavedma & 0x30) dma_new |= 0x40; diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index dcc50362f..7d5bfaedf 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c @@ -351,7 +351,7 @@ icside_config_if(ide_drive_t *drive, int xfer_mode) static int icside_set_speed(ide_drive_t *drive, byte speed) { - return ((int) icside_config_if(drive, (int) speed)); + return icside_config_if(drive, speed); } static int @@ -508,9 +508,9 @@ icside_setup_dma(ide_hwif_t *hwif, int autodma) goto failed; } - hwif->dmaproc = &icside_dmaproc; + hwif->speedproc = icside_set_speed; + hwif->dmaproc = icside_dmaproc; hwif->autodma = autodma; - hwif->speedproc = &icside_set_speed; printk(" capable%s\n", autodma ? ", auto-enable" : ""); diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index d209c29ff..ab4d3afbb 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -426,11 +426,13 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, while (hi > lo) { mid = (lo + hi) / 2; - if (packet_command_texts[mid].packet_command == failed_command->c[0]) { + if (packet_command_texts[mid].packet_command == + failed_command->c[0]) { s = packet_command_texts[mid].text; break; } - else if (packet_command_texts[mid].packet_command > failed_command->c[0]) + if (packet_command_texts[mid].packet_command > + failed_command->c[0]) hi = mid; else lo = mid+1; @@ -1524,7 +1526,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) memset(&pc, 0, sizeof(pc)); pc.sense = sense; pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; - pc.c[4] = lockflag ? 3 : 0; + pc.c[4] = lockflag ? 1 : 0; stat = cdrom_queue_packet_command (drive, &pc); } @@ -1624,7 +1626,8 @@ 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, struct request_sense *sense) { - int stat, ntracks, i; + int minor, stat, ntracks, i; + kdev_t dev; struct cdrom_info *info = drive->driver_data; struct atapi_toc *toc = info->toc; struct { @@ -1663,8 +1666,10 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) #endif /* not STANDARD_ATAPI */ ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; - if (ntracks <= 0) return -EIO; - if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS; + if (ntracks <= 0) + return -EIO; + if (ntracks > MAX_TRACKS) + ntracks = MAX_TRACKS; /* Now read the whole schmeer. */ stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, @@ -1755,13 +1760,13 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track); /* Now try to get the total cdrom capacity. */ -#if 0 - stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor), - (long *)&toc->capacity); + minor = (drive->select.b.unit) << PARTN_BITS; + dev = MKDEV(HWIF(drive)->major, minor); + stat = cdrom_get_last_written(dev, (long *)&toc->capacity); if (stat) -#endif - stat = cdrom_read_capacity(drive, &toc->capacity, sense); - if (stat) toc->capacity = 0x1fffff; + stat = cdrom_read_capacity(drive, &toc->capacity, sense); + if (stat) + toc->capacity = 0x1fffff; /* Remember that we've read this stuff. */ CDROM_STATE_FLAGS (drive)->toc_valid = 1; @@ -2552,7 +2557,8 @@ unsigned long ide_cdrom_capacity (ide_drive_t *drive) { unsigned capacity; - return cdrom_read_capacity(drive, &capacity, NULL) ? 0 : capacity * SECTORS_PER_FRAME; + return cdrom_read_capacity(drive, &capacity, NULL) + ? 0 : capacity * SECTORS_PER_FRAME; } static diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 4e2952018..ae9f62768 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1,14 +1,13 @@ /* - * linux/drivers/ide/ide-disk.c Version 1.09 April 23, 1999 + * linux/drivers/ide/ide-disk.c Version 1.10 June 9, 2000 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ /* * Mostly written by Mark Lord <mlord@pobox.com> - * and Gadi Oxman <gadio@netvision.net.il> - * - * See linux/MAINTAINERS for address of current maintainer. + * and Gadi Oxman <gadio@netvision.net.il> + * and Andre Hedrick <andre@linux-ide.org> * * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c. * @@ -27,9 +26,10 @@ * the entire disk. * Version 1.09 added increment of rq->sector in ide_multwrite * added UDMA 3/4 reporting + * Version 1.10 request queue changes, Ultra DMA 100 */ -#define IDEDISK_VERSION "1.09" +#define IDEDISK_VERSION "1.10" #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -140,11 +140,8 @@ static ide_startstop_t read_intr (ide_drive_t *drive) int i; unsigned int msect, nsect; struct request *rq; -#if 0 - if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { - return ide_error(drive, "read_intr", stat); - } -#else /* new way for dealing with premature shared PCI interrupts */ + + /* new way for dealing with premature shared PCI interrupts */ if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { if (stat & (ERR_STAT|DRQ_STAT)) { return ide_error(drive, "read_intr", stat); @@ -153,7 +150,6 @@ static ide_startstop_t read_intr (ide_drive_t *drive) ide_set_handler(drive, &read_intr, WAIT_CMD, NULL); return ide_started; } -#endif msect = drive->mult_count; read_next: @@ -688,7 +684,6 @@ static int set_nowerr(ide_drive_t *drive, int arg) { if (ide_spin_wait_hwgroup(drive)) return -EBUSY; - drive->nowerr = arg; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; spin_unlock_irq(&io_request_lock); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 835fa91e3..e9a34afc1 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/ide-dma.c Version 4.09 April 23, 1999 + * linux/drivers/ide/ide-dma.c Version 4.10 June 9, 2000 * - * Copyright (c) 1999 Andre Hedrick + * Copyright (c) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License */ @@ -70,12 +70,11 @@ * * And, yes, Intel Zappa boards really *do* use both PIIX IDE ports. * - * ACARD ATP850UF Chipset "Modified SCSI Class" with other names - * AEC6210 U/UF - * SIIG's UltraIDE Pro CN-2449 - * TTI HPT343 Chipset "Modified SCSI Class" but reports as an - * unknown storage device. - * NEW check_drive_lists(ide_drive_t *drive, int good_bad) + * check_drive_lists(ide_drive_t *drive, int good_bad) + * + * ATA-66/100 and recovery functions, I forgot the rest...... + * SELECT_READ_WRITE(hwif,drive,func) for active tuning based on IO direction. + * */ #include <linux/config.h> @@ -358,10 +357,11 @@ int report_drive_dmaing (ide_drive_t *drive) { struct hd_driveid *id = drive->id; - if ((id->field_valid & 4) && (id->hw_config & 0x2000) && - (HWIF(drive)->udma_four) && - (id->dma_ultra & (id->dma_ultra >> 11) & 3)) { - if ((id->dma_ultra >> 12) & 1) { + if ((id->field_valid & 4) && (eighty_ninty_three(drive)) && + (id->dma_ultra & (id->dma_ultra >> 11) & 7)) { + if ((id->dma_ultra >> 13) & 1) { + printk(", UDMA(100)"); /* UDMA BIOS-enabled! */ + } else if ((id->dma_ultra >> 12) & 1) { printk(", UDMA(66)"); /* UDMA BIOS-enabled! */ } else { printk(", UDMA(44)"); /* UDMA BIOS-enabled! */ @@ -393,9 +393,9 @@ static int config_drive_for_dma (ide_drive_t *drive) if (ide_dmaproc(ide_dma_bad_drive, drive)) return hwif->dmaproc(ide_dma_off, drive); - /* Enable DMA on any drive that has UltraDMA (mode 3/4) enabled */ - if ((id->field_valid & 4) && (hwif->udma_four) && (id->hw_config & 0x2000)) - if ((id->dma_ultra & (id->dma_ultra >> 11) & 3)) + /* Enable DMA on any drive that has UltraDMA (mode 3/4/5) enabled */ + if ((id->field_valid & 4) && (eighty_ninty_three(drive))) + if ((id->dma_ultra & (id->dma_ultra >> 11) & 7)) return hwif->dmaproc(ide_dma_on, drive); /* Enable DMA on any drive that has UltraDMA (mode 0/1/2) enabled */ if (id->field_valid & 4) /* UltraDMA */ @@ -413,6 +413,22 @@ static int config_drive_for_dma (ide_drive_t *drive) } /* + * 1 dmaing, 2 error, 4 intr + */ +static int dma_timer_expiry (ide_drive_t *drive) +{ + byte dma_stat = inb(HWIF(drive)->dma_base+2); + +#ifdef DEBUG + printk("%s: dma_timer_expiry: dma status == 0x%02x\n", drive->name, dma_stat); +#endif /* DEBUG */ + + if (dma_stat & 1) /* DMAing */ + return WAIT_CMD; + return 0; +} + +/* * ide_dmaproc() initiates/aborts DMA read/write operations on a drive. * * The caller is assumed to have selected the drive and programmed the drive's @@ -451,6 +467,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) case ide_dma_read: reading = 1 << 3; case ide_dma_write: + SELECT_READ_WRITE(hwif,drive,func); if (!(count = ide_build_dmatable(drive, func))) return 1; /* try PIO instead of DMA */ outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */ @@ -459,7 +476,7 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; - ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); /* issue cmd to drive */ + ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); case ide_dma_begin: /* Note that this is done *after* the cmd has @@ -570,8 +587,8 @@ unsigned long __init ide_get_or_set_dma_base (ide_hwif_t *hwif, int extra, const if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { - dma_base = dev->resource[4].start; - if (!dma_base || dma_base == PCI_BASE_ADDRESS_IO_MASK) { + dma_base = pci_resource_start(dev, 4); + if (!dma_base) { printk("%s: dma_base is invalid (0x%04lx)\n", name, dma_base); dma_base = 0; } diff --git a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c index cb3790fa6..967b91e55 100644 --- a/drivers/ide/ide-features.c +++ b/drivers/ide/ide-features.c @@ -1,14 +1,16 @@ /* - * linux/drivers/block/ide-features.c Version 0.03 Feb. 10, 2000 + * linux/drivers/block/ide-features.c Version 0.04 June 9, 2000 * * Copyright (C) 1999-2000 Linus Torvalds & authors (see below) * - * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * * Extracts if ide.c to address the evolving transfer rate code for * the SETFEATURES_XFER callouts. Various parts of any given function * are credited to previous ATA-IDE maintainers. * + * Auto-CRC downgrade for Ultra DMA(ing) + * * May be copied or modified under the terms of the GNU General Public License */ @@ -115,6 +117,10 @@ char *ide_dmafunc_verbose (ide_dma_action_t dmafunc) */ byte ide_auto_reduce_xfer (ide_drive_t *drive) { + if (!drive->crc_count) + return drive->current_speed; + drive->crc_count = 0; + switch(drive->current_speed) { case XFER_UDMA_7: return XFER_UDMA_6; case XFER_UDMA_6: return XFER_UDMA_5; @@ -164,6 +170,7 @@ int ide_driveid_update (ide_drive_t *drive) probe_irq_off(probe_irq_on()); irqs = probe_irq_on(); + SELECT_MASK(HWIF(drive), drive, 1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); ide_delay_50ms(); @@ -173,17 +180,20 @@ int ide_driveid_update (ide_drive_t *drive) if (0 < (signed long)(jiffies - timeout)) { if (irqs) (void) probe_irq_off(irqs); + SELECT_MASK(HWIF(drive), drive, 0); return 0; /* drive timed-out */ } ide_delay_50ms(); /* give drive a breather */ } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { + SELECT_MASK(HWIF(drive), drive, 0); printk("%s: CHECK for good STATUS\n", drive->name); return 0; } __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only; some systems need this */ + SELECT_MASK(HWIF(drive), drive, 0); id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); ide_input_data(drive, id, SECTOR_WORDS); (void) GET_STAT(); /* clear drive IRQ */ @@ -214,11 +224,15 @@ int ide_ata66_check (ide_drive_t *drive, byte cmd, byte nsect, byte feature) (nsect > XFER_UDMA_2) && (feature == SETFEATURES_XFER)) { if (!HWIF(drive)->udma_four) { - printk("%s: Speed warnings UDMA 3/4 is not functional.\n", HWIF(drive)->name); + printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", HWIF(drive)->name); return 1; } +#ifndef CONFIG_IDEDMA_IVB + if ((drive->id->hw_config & 0x6000) == 0) { +#else /* !CONFIG_IDEDMA_IVB */ if ((drive->id->hw_config & 0x2000) == 0) { - printk("%s: Speed warnings UDMA 3/4 is not functional.\n", drive->name); +#endif /* CONFIG_IDEDMA_IVB */ + printk("%s: Speed warnings UDMA 3/4/5 is not functional.\n", drive->name); return 1; } } @@ -244,6 +258,18 @@ int set_transfer (ide_drive_t *drive, byte cmd, byte nsect, byte feature) } /* + * All hosts that use the 80c ribbon mus use! + */ +byte eighty_ninty_three (ide_drive_t *drive) +{ + return ((byte) ((HWIF(drive)->udma_four) && +#ifndef CONFIG_IDEDMA_IVB + (drive->id->hw_config & 0x4000) && +#endif /* CONFIG_IDEDMA_IVB */ + (drive->id->hw_config & 0x2000)) ? 1 : 0); +} + +/* * Similar to ide_wait_stat(), except it never calls ide_error internally. * This is a kludge to handle the new ide_config_drive_speed() function, * and should not otherwise be used anywhere. Eventually, the tuneproc's @@ -260,10 +286,11 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) int i, error = 1; byte stat; -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) byte unit = (drive->select.b.unit & 0x01); outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ + /* * Don't use ide_wait_cmd here - it will * attempt to set_geometry and recalibrate, @@ -276,6 +303,7 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) disable_irq(hwif->irq); /* disable_irq_nosync ?? */ udelay(1); SELECT_DRIVE(HWIF(drive), drive); + SELECT_MASK(HWIF(drive), drive, 0); udelay(1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG); @@ -315,6 +343,8 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) } } + SELECT_MASK(HWIF(drive), drive, 0); + enable_irq(hwif->irq); if (error) { @@ -326,13 +356,13 @@ int ide_config_drive_speed (ide_drive_t *drive, byte speed) drive->id->dma_mword &= ~0x0F00; drive->id->dma_1word &= ~0x0F00; -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (speed > XFER_PIO_4) { outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); } else { outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); } -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ switch(speed) { case XFER_UDMA_7: drive->id->dma_ultra |= 0x8080; break; @@ -358,5 +388,5 @@ EXPORT_SYMBOL(ide_auto_reduce_xfer); EXPORT_SYMBOL(ide_driveid_update); EXPORT_SYMBOL(ide_ata66_check); EXPORT_SYMBOL(set_transfer); +EXPORT_SYMBOL(eighty_ninty_three); EXPORT_SYMBOL(ide_config_drive_speed); - diff --git a/drivers/ide/ide-geometry.c b/drivers/ide/ide-geometry.c index a29178597..639d4c6f1 100644 --- a/drivers/ide/ide-geometry.c +++ b/drivers/ide/ide-geometry.c @@ -3,7 +3,7 @@ */ #include <linux/config.h> -#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD) +#if defined(CONFIG_IDE) && !defined(CONFIG_BLK_DEV_HD_ONLY) #include <linux/ide.h> #include <asm/io.h> @@ -211,4 +211,4 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, int ptheads, const char *msg) drive->bios_cyl, drive->bios_head, drive->bios_sect); return ret; } -#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD) */ +#endif /* (CONFIG_IDE) && !(CONFIG_BLK_DEV_HD_ONLY) */ diff --git a/drivers/ide/ide-pci.c b/drivers/ide/ide-pci.c index c10ae4b51..8c9354394 100644 --- a/drivers/ide/ide-pci.c +++ b/drivers/ide/ide-pci.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-pci.c Version 1.04 July 27, 1999 + * linux/drivers/ide/ide-pci.c Version 1.05 June 9, 2000 * * Copyright (c) 1998-2000 Andre Hedrick <andre@linux-ide.org> * @@ -33,10 +33,13 @@ #define DEVID_PIIX4E2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1}) #define DEVID_PIIX4U ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1}) #define DEVID_PIIX4U2 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1}) +#define DEVID_PIIX4NX ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX}) +#define DEVID_PIIX4U3 ((ide_pci_devid_t){PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_5}) #define DEVID_VIA_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C561}) #define DEVID_VP_IDE ((ide_pci_devid_t){PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1}) #define DEVID_PDC20246 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246}) #define DEVID_PDC20262 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20262}) +#define DEVID_PDC20267 ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20267}) #define DEVID_RZ1000 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000}) #define DEVID_RZ1001 ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001}) #define DEVID_SAMURAI ((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_SAMURAI_IDE}) @@ -44,6 +47,7 @@ #define DEVID_CMD643 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_643}) #define DEVID_CMD646 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_646}) #define DEVID_CMD648 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_648}) +#define DEVID_CMD649 ((ide_pci_devid_t){PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_649}) #define DEVID_SIS5513 ((ide_pci_devid_t){PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513}) #define DEVID_OPTI621 ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C621}) #define DEVID_OPTI621V ((ide_pci_devid_t){PCI_VENDOR_ID_OPTI, PCI_DEVICE_ID_OPTI_82C558}) @@ -65,6 +69,7 @@ #define DEVID_CY82C693 ((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693}) #define DEVID_HINT ((ide_pci_devid_t){0x3388, 0x8013}) #define DEVID_CS5530 ((ide_pci_devid_t){PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE}) +#define DEVID_AMD7403 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_COBRA_7403}) #define DEVID_AMD7409 ((ide_pci_devid_t){PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7409}) #define IDE_IGNORE ((void *)-1) @@ -288,7 +293,7 @@ typedef struct ide_pci_enablebit_s { typedef struct ide_pci_device_s { ide_pci_devid_t devid; - const char *name; + char *name; unsigned int (*init_chipset)(struct pci_dev *dev, const char *name); unsigned int (*ata66_check)(ide_hwif_t *hwif); void (*init_hwif)(ide_hwif_t *hwif); @@ -307,10 +312,13 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_PIIX4E2, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4U, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_PIIX4U2, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX4NX, "PIIX4", PCI_PIIX, NULL, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, + {DEVID_PIIX4U3, "PIIX4", PCI_PIIX, ATA66_PIIX, INIT_PIIX, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_VIA_IDE, "VIA_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_VP_IDE, "VP_IDE", PCI_VIA82CXXX, ATA66_VIA82CXXX,INIT_VIA82CXXX, DMA_VIA82CXXX, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0 }, {DEVID_PDC20246,"PDC20246", PCI_PDC202XX, NULL, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 16 }, {DEVID_PDC20262,"PDC20262", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, + {DEVID_PDC20267,"PDC20267", PCI_PDC202XX, ATA66_PDC202XX, INIT_PDC202XX, NULL, {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, OFF_BOARD, 48 }, {DEVID_RZ1000, "RZ1000", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_RZ1001, "RZ1001", NULL, NULL, INIT_RZ1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_SAMURAI, "SAMURAI", NULL, NULL, INIT_SAMURAI, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, @@ -320,6 +328,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CMD643, "CMD643", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CMD646, "CMD646", PCI_CMD64X, NULL, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x51,0x80,0x80}}, ON_BOARD, 0 }, {DEVID_CMD648, "CMD648", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_CMD649, "CMD649", PCI_CMD64X, ATA66_CMD64X, INIT_CMD64X, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HT6565, "HT6565", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_OPTI621, "OPTI621", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, {DEVID_OPTI621X,"OPTI621X", NULL, NULL, INIT_OPTI621, NULL, {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, ON_BOARD, 0 }, @@ -338,6 +347,7 @@ static ide_pci_device_t ide_pci_chipsets[] __initdata = { {DEVID_CY82C693,"CY82C693", PCI_CY82C693, NULL, INIT_CY82C693, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_HINT, "HINT_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_CS5530, "CS5530", PCI_CS5530, NULL, INIT_CS5530, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, + {DEVID_AMD7403, "AMD7403", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }, {DEVID_AMD7409, "AMD7409", PCI_AMD7409, ATA66_AMD7409, INIT_AMD7409, DMA_AMD7409, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0 }, {IDE_PCI_DEVID_NULL, "PCI_IDE", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 }}; @@ -352,6 +362,7 @@ static unsigned int __init ide_special_settings (struct pci_dev *dev, const char case PCI_DEVICE_ID_TTI_HPT366: case PCI_DEVICE_ID_PROMISE_20246: case PCI_DEVICE_ID_PROMISE_20262: + case PCI_DEVICE_ID_PROMISE_20267: case PCI_DEVICE_ID_ARTOP_ATP850UF: case PCI_DEVICE_ID_ARTOP_ATP860: case PCI_DEVICE_ID_ARTOP_ATP860R: @@ -510,6 +521,14 @@ check_if_enabled: pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { + /* see comments in hpt34x.c on why..... */ + char *chipset_names[] = {"HPT343", "HPT345"}; + strcpy(d->name, chipset_names[(pcicmd & PCI_COMMAND_MEMORY)]); + d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; + } + printk("%s: chipset revision %d\n", d->name, class_rev); /* @@ -541,10 +560,7 @@ check_if_enabled: printk("%s: 100%% native mode on irq %d\n", d->name, pciirq); #endif } - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) { - /* see comments in hpt34x.c on why..... */ - d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; - } + /* * Set up the IDE ports */ @@ -553,14 +569,14 @@ check_if_enabled: ide_pci_enablebit_t *e = &(d->enablebits[port]); if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || (tmp & e->mask) != e->val)) continue; /* port not enabled */ - if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev != 0x03)) + if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) && (port) && (class_rev < 0x03)) return; if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE || (dev->class & (port ? 4 : 1)) != 0) { ctl = dev->resource[(2*port)+1].start; base = dev->resource[2*port].start; if (!(ctl & PCI_BASE_ADDRESS_IO_MASK) || !(base & PCI_BASE_ADDRESS_IO_MASK)) { - printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@suse.com>.\n", d->name); + printk("%s: IO baseregs (BIOS) are reported as MEM, report to <andre@linux-ide.org>.\n", d->name); #if 0 /* FIXME! This really should check that it really gets the IO/MEM part right! */ continue; @@ -603,19 +619,21 @@ check_if_enabled: goto bypass_umc_dma; } if (hwif->udma_four) { - printk("%s: ATA-66 forced bit set (WARNING)!!\n", d->name); + printk("%s: ATA-66/100 forced bit set (WARNING)!!\n", d->name); } else { hwif->udma_four = (d->ata66_check) ? d->ata66_check(hwif) : 0; } #ifdef CONFIG_BLK_DEV_IDEDMA if (IDE_PCI_DEVID_EQ(d->devid, DEVID_SIS5513) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PIIX4NX) || IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X)) autodma = 0; if (autodma) hwif->autodma = 1; if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20246) || IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20262) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20267) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) || IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) || @@ -625,6 +643,7 @@ check_if_enabled: IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) || IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD648) || + IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD649) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { unsigned long dma_base = ide_get_or_set_dma_base(hwif, (!mate && d->extra) ? d->extra : 0, d->name); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { @@ -665,6 +684,7 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic ide_pci_device_t *d2; unsigned char pin1 = 0, pin2 = 0; unsigned int class_rev; + char *chipset_names[] = {"HPT366", "HPT366", "HPT368", "HPT370", "HPT370A"}; if (PCI_FUNC(dev->devfn) & 1) return; @@ -672,8 +692,13 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; + strcpy(d->name, chipset_names[class_rev]); + switch(class_rev) { - case 3: return; + case 4: + case 3: printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn); + ide_setup_pci_device(dev, d); + return; default: break; } @@ -700,15 +725,6 @@ static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_devic return; d2 = d; printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn); - if (hpt363_shared_pin && !hpt363_shared_irq) { - printk("%s: IDE controller run unsupported mode three!!!\n", d2->name); -#ifndef CONFIG_HPT366_MODE3 - printk("%s: IDE controller report to <andre@suse.com>\n", d->name); - return; -#else /* CONFIG_HPT366_MODE3 */ - printk("%s: OVERRIDE IDE controller not advisable this mode!!!\n", d2->name); -#endif /* CONFIG_HPT366_MODE3 */ - } ide_setup_pci_device(dev2, d2); } diff --git a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c index 45bbe77ac..83cea6ba2 100644 --- a/drivers/ide/ide-pmac.c +++ b/drivers/ide/ide-pmac.c @@ -813,12 +813,6 @@ pmac_ide_dma_onoff(ide_drive_t *drive, int enable) return 0; } -static int -pmac_ide_tune_chipset(ide_drive_t *drive, byte speed) -{ - return 0; -} - int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index ddf6c8dae..dd5f660fe 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide-probe.c Version 1.05 July 3, 1999 + * linux/drivers/ide/ide-probe.c Version 1.06 June 9, 2000 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -7,6 +7,7 @@ /* * Mostly written by Mark Lord <mlord@pobox.com> * and Gadi Oxman <gadio@netvision.net.il> + * and Andre Hedrick <andre@linux-ide.org> * * See linux/MAINTAINERS for address of current maintainer. * @@ -23,6 +24,7 @@ * added ide6/7/8/9 * allowed for secondary flash card to be detectable * with new flag : drive->ata_flash : 1; + * Version 1.06 stream line request queue and prep for cascade project. */ #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -41,6 +43,7 @@ #include <linux/malloc.h> #include <linux/delay.h> #include <linux/ide.h> +#include <linux/spinlock.h> #include <asm/byteorder.h> #include <asm/irq.h> @@ -167,6 +170,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) } drive->media = ide_disk; printk("ATA DISK drive\n"); + QUIRK_LIST(HWIF(drive),drive); return; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index a3394807b..932c6f114 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/ide.c Version 6.30 Dec 28, 1999 + * linux/drivers/ide/ide.c Version 6.31 June 9, 2000 * * Copyright (C) 1994-1998 Linus Torvalds & authors (see below) */ @@ -7,6 +7,7 @@ /* * Mostly written by Mark Lord <mlord@pobox.com> * and Gadi Oxman <gadio@netvision.net.il> + * and Andre Hedrick <andre@linux-ide.org> * * See linux/MAINTAINERS for address of current maintainer. * @@ -109,6 +110,9 @@ * Version 6.21 Fixing/Fixed SMP spinlock issue with insight from an old * hat that clarified original low level driver design. * Version 6.30 Added SMP support; fixed multmode issues. -ml + * Version 6.31 Debug Share INTR's and request queue streaming + * Native ATA-100 support + * Prep for Cascades Project * * Some additional driver compile-time options are in ./include/linux/ide.h * @@ -117,8 +121,8 @@ * */ -#define REVISION "Revision: 6.30" -#define VERSION "Id: ide.c 6.30 1999/12/28" +#define REVISION "Revision: 6.31" +#define VERSION "Id: ide.c 6.31 2000/06/09" #undef REALLY_SLOW_IO /* most systems can safely undef this */ @@ -482,7 +486,8 @@ static inline int drive_is_ready (ide_drive_t *drive) #if 0 udelay(1); /* need to guarantee 400ns since last command was issued */ #endif - if (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */ +// if (GET_STAT() & BUSY_STAT) /* Note: this may clear a pending IRQ!! */ + if (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT) return 0; /* drive busy: definitely not interrupting */ return 1; /* drive ready: *might* be interrupting */ } @@ -651,6 +656,19 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) return ide_stopped; } +static void check_dma_crc (ide_drive_t *drive) +{ + if (drive->crc_count) { + (void) HWIF(drive)->dmaproc(ide_dma_off_quietly, drive); + if ((HWIF(drive)->speedproc) != NULL) + HWIF(drive)->speedproc(drive, ide_auto_reduce_xfer(drive)); + if (drive->current_speed >= XFER_SW_DMA_0) + (void) HWIF(drive)->dmaproc(ide_dma_on, drive); + } else { + (void) HWIF(drive)->dmaproc(ide_dma_off, drive); + } +} + static void pre_reset (ide_drive_t *drive) { if (drive->driver != NULL) @@ -658,12 +676,15 @@ static void pre_reset (ide_drive_t *drive) if (!drive->keep_settings) { if (drive->using_dma) { - (void) HWIF(drive)->dmaproc(ide_dma_off, drive); + check_dma_crc(drive); } else { drive->unmask = 0; drive->io_32bit = 0; } + return; } + if (drive->using_dma) + check_dma_crc(drive); } /* @@ -902,9 +923,9 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat) if (err == ABRT_ERR) { if (drive->select.b.lba && IN_BYTE(IDE_COMMAND_REG) == WIN_SPECIFY) return ide_stopped; /* some newer drives don't support WIN_SPECIFY */ - } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) - ; /* UDMA crc error -- just retry the operation */ - else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */ + } else if ((err & (ABRT_ERR | ICRC_ERR)) == (ABRT_ERR | ICRC_ERR)) { + drive->crc_count++; /* UDMA crc error -- just retry the operation */ + } else if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */ rq->errors = ERROR_MAX; else if (err & TRK0_ERR) /* help it find track zero */ rq->errors |= ERROR_RECAL; @@ -941,6 +962,7 @@ void ide_cmd (ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler) ide_set_handler (drive, handler, WAIT_CMD, NULL); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* clear nIEN */ + SELECT_MASK(HWIF(drive),drive,0); OUT_BYTE(nsect,IDE_NSECTOR_REG); OUT_BYTE(cmd,IDE_COMMAND_REG); } @@ -1298,7 +1320,7 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) hwif = HWIF(drive); if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif && hwif->io_ports[IDE_CONTROL_OFFSET]) { /* set nIEN for previous hwif */ - OUT_BYTE(hwgroup->drive->ctl|2, hwgroup->hwif->io_ports[IDE_CONTROL_OFFSET]); + SELECT_INTERRUPT(hwif, drive); } hwgroup->hwif = hwif; hwgroup->drive = drive; @@ -1316,13 +1338,13 @@ static void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq) * happens anyway when any interrupt comes in, IDE or otherwise * -- the kernel masks the IRQ while it is being handled. */ - if (hwif->irq != masked_irq) + if (masked_irq && hwif->irq != masked_irq) disable_irq_nosync(hwif->irq); spin_unlock(&io_request_lock); ide__sti(); /* allow other IRQs while we start this request */ startstop = start_request(drive); spin_lock_irq(&io_request_lock); - if (hwif->irq != masked_irq) + if (masked_irq && hwif->irq != masked_irq) enable_irq(hwif->irq); if (startstop == ide_stopped) hwgroup->busy = 0; @@ -1404,7 +1426,11 @@ void ide_timer_expiry (unsigned long data) */ spin_unlock(&io_request_lock); hwif = HWIF(drive); +#if DISABLE_IRQ_NOSYNC + disable_irq_nosync(hwif->irq); +#else disable_irq(hwif->irq); /* disable_irq_nosync ?? */ +#endif /* DISABLE_IRQ_NOSYNC */ __cli(); /* local CPU only, as if we were handling an interrupt */ if (hwgroup->poll_timeout != 0) { startstop = handler(drive); @@ -2008,12 +2034,12 @@ void ide_unregister (unsigned int index) else hwgroup->hwif = HWIF(hwgroup->drive); -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (hwif->dma_base) { (void) ide_release_dma(hwif); hwif->dma_base = 0; } -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ /* * Remove us from the kernel's knowledge @@ -2048,6 +2074,10 @@ void ide_unregister (unsigned int index) hwif->speedproc = old_hwif.speedproc; hwif->selectproc = old_hwif.selectproc; hwif->resetproc = old_hwif.resetproc; + hwif->intrproc = old_hwif.intrproc; + hwif->maskproc = old_hwif.maskproc; + hwif->quirkproc = old_hwif.quirkproc; + hwif->rwproc = old_hwif.rwproc; hwif->dmaproc = old_hwif.dmaproc; hwif->dma_base = old_hwif.dma_base; hwif->dma_extra = old_hwif.dma_extra; @@ -2275,17 +2305,18 @@ int ide_spin_wait_hwgroup (ide_drive_t *drive) unsigned long timeout = jiffies + (3 * HZ); spin_lock_irq(&io_request_lock); + while (hwgroup->busy) { - unsigned long flags; + unsigned long lflags; spin_unlock_irq(&io_request_lock); - __save_flags(flags); /* local CPU only */ + __save_flags(lflags); /* local CPU only */ __sti(); /* local CPU only; needed for jiffies */ if (0 < (signed long)(jiffies - timeout)) { - __restore_flags(flags); + __restore_flags(lflags); /* local CPU only */ printk("%s: channel busy\n", drive->name); return -EBUSY; } - __restore_flags(flags); /* local CPU only */ + __restore_flags(lflags); /* local CPU only */ spin_lock_irq(&io_request_lock); } return 0; @@ -2422,13 +2453,13 @@ int ide_wait_cmd_task (ide_drive_t *drive, byte *buf) */ void ide_delay_50ms (void) { -#if 0 +#ifndef CONFIG_BLK_DEV_IDECS 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 +#endif /* CONFIG_BLK_DEV_IDECS */ } int system_bus_clock (void) @@ -2576,7 +2607,6 @@ static int ide_ioctl (struct inode *inode, struct file *file, err = -EFAULT; return err; } - case HDIO_SCAN_HWIF: { int args[3]; @@ -3266,6 +3296,7 @@ void __init ide_init_builtin_drivers (void) if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) { ide_get_lock(&ide_lock, NULL, NULL); /* for atari only */ disable_irq(ide_hwifs[0].irq); /* disable_irq_nosync ?? */ +// disable_irq_nosync(ide_hwifs[0].irq); } #endif /* __mc68000__ || CONFIG_APUS */ @@ -3619,10 +3650,10 @@ void cleanup_module (void) for (index = 0; index < MAX_HWIFS; ++index) { ide_unregister(index); -#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) if (ide_hwifs[index].dma_base) (void) ide_release_dma(&ide_hwifs[index]); -#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ +#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ } #ifdef CONFIG_PROC_FS @@ -3636,6 +3667,7 @@ void cleanup_module (void) static int parse_ide_setup (char *line) { parse_options(line); + /* We MUST return 0 as otherwise no subsequent __setup option works... */ return 0; } __setup("", parse_ide_setup); diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c index 70f185108..1837f01e0 100644 --- a/drivers/ide/ns87415.c +++ b/drivers/ide/ns87415.c @@ -3,7 +3,7 @@ * * Copyright (C) 1997-1998 Mark Lord <mlord@pobox.com> * Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be> - * Copyright (C) 1999-2000 Andre Hedrick <andre@suse.com> + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * * Inspired by an earlier effort from David S. Miller <davem@redhat.com> */ diff --git a/drivers/ide/pdc202xx.c b/drivers/ide/pdc202xx.c index f16d33921..66a123841 100644 --- a/drivers/ide/pdc202xx.c +++ b/drivers/ide/pdc202xx.c @@ -1,7 +1,7 @@ /* * linux/drivers/ide/pdc202xx.c Version 0.30 Mar. 18, 2000 * - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this @@ -12,6 +12,8 @@ * Promise Ultra66 cards with BIOS v1.11 this * compiled into the kernel if you have more than one card installed. * + * Promise Ultra100 cards. + * * The latest chipset code will support the following :: * Three Ultra33 controllers and 12 drives. * 8 are UDMA supported and 4 are limited to DMA mode 2 multi-word. @@ -51,6 +53,10 @@ #define DISPLAY_PDC202XX_TIMINGS +#ifndef SPLIT_BYTE +#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4))) +#endif + #if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> @@ -99,10 +105,25 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0; u16 reg50h = 0, pmask = (1<<10), smask = (1<<11); - u8 c0 = 0, c1 = 0; + u8 hi = 0, lo = 0; + + /* + * at that point bibma+0x2 et bibma+0xa are byte registers + * to investigate: + */ + u8 c0 = inb_p((unsigned short)bibma + 0x02); + u8 c1 = inb_p((unsigned short)bibma + 0x0a); + + u8 sc11 = inb_p((unsigned short)bibma + 0x11); + u8 sc1a = inb_p((unsigned short)bibma + 0x1a); + u8 sc1b = inb_p((unsigned short)bibma + 0x1b); + u8 sc1c = inb_p((unsigned short)bibma + 0x1c); + u8 sc1d = inb_p((unsigned short)bibma + 0x1d); + u8 sc1e = inb_p((unsigned short)bibma + 0x1e); + u8 sc1f = inb_p((unsigned short)bibma + 0x1f); pci_read_config_word(bmide_dev, 0x50, ®50h); pci_read_config_dword(bmide_dev, 0x60, ®60h); @@ -110,14 +131,10 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count pci_read_config_dword(bmide_dev, 0x68, ®68h); pci_read_config_dword(bmide_dev, 0x6c, ®6ch); - /* - * 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); - - switch(bmide_dev->device) { + switch(bmide_dev->device) { + case PCI_DEVICE_ID_PROMISE_20267: + p += sprintf(p, "\n PDC20267 Chipset.\n"); + break; case PCI_DEVICE_ID_PROMISE_20262: p += sprintf(p, "\n PDC20262 Chipset.\n"); break; @@ -130,9 +147,40 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count break; } + p += sprintf(p, "------------------------------- General Status ---------------------------------\n"); + p += sprintf(p, "Burst Mode : %sabled\n", (sc1f & 0x01) ? "en" : "dis"); + p += sprintf(p, "Host Mode : %s\n", (sc1f & 0x08) ? "Tri-Stated" : "Normal"); + p += sprintf(p, "Bus Clocking : %s\n", + ((sc1f & 0xC0) == 0xC0) ? "100 External" : + ((sc1f & 0x80) == 0x80) ? "66 External" : + ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); + p += sprintf(p, "IO pad select : %s mA\n", + ((sc1c & 0x03) == 0x03) ? "10" : + ((sc1c & 0x02) == 0x02) ? "8" : + ((sc1c & 0x01) == 0x01) ? "6" : + ((sc1c & 0x00) == 0x00) ? "4" : "??"); + SPLIT_BYTE(sc1e, hi, lo); + p += sprintf(p, "Status Polling Period : %d\n", hi); + p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); 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, " %s %s\n", + (c0&0x80)?"disabled":"enabled ", + (c1&0x80)?"disabled":"enabled "); + p += sprintf(p, "66 Clocking %s %s\n", + (sc11&0x02)?"enabled ":"disabled", + (sc11&0x08)?"enabled ":"disabled"); + p += sprintf(p, " Mode %s Mode %s\n", + (sc1a & 0x01) ? "MASTER" : "PCI ", + (sc1b & 0x01) ? "MASTER" : "PCI "); + p += sprintf(p, " %s %s\n", + (sc1d & 0x08) ? "Error " : + (sc1d & 0x04) ? "Interrupting" : + (sc1d & 0x02) ? "FIFO Full " : + (sc1d & 0x01) ? "FIFO Empty " : "????????????", + (sc1d & 0x80) ? "Error " : + (sc1d & 0x40) ? "Interrupting" : + (sc1d & 0x20) ? "FIFO Full " : + (sc1d & 0x10) ? "FIFO Empty " : "????????????"); 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 "); @@ -141,9 +189,13 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)), pdc202xx_ultra_verbose(reg68h, (reg50h & smask)), pdc202xx_ultra_verbose(reg6ch, (reg50h & smask))); - p += sprintf(p, " PIO Mode: %s %s %s %s\n", + p += sprintf(p, "PIO Mode: %s %s %s %s\n", pdc202xx_pio_verbose(reg60h),pdc202xx_pio_verbose(reg64h), pdc202xx_pio_verbose(reg68h),pdc202xx_pio_verbose(reg6ch)); +#if 0 + p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n"); +#endif + return p-buffer; /* => must be less than 4k! */ } #endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */ @@ -324,6 +376,7 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed) switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA + case XFER_UDMA_5: case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */ case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */ case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */ @@ -408,7 +461,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); @@ -418,8 +471,9 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte AP; unsigned short EP; byte CLKSPD = IN_BYTE(high_16 + 0x11); - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; byte udma_33 = ultra ? (inb(high_16 + 0x001f) & 1) : 0; + byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0; + byte udma_100 = ((dev->device == PCI_DEVICE_ID_PROMISE_20267) && udma_66) ? 1 : 0; /* * Set the control register to use the 66Mhz system @@ -436,11 +490,15 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) byte mask = hwif->channel ? 0x08 : 0x02; unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10); - byte ultra_66 = ((id->dma_ultra & 0x0010) || (id->dma_ultra & 0x0008)) ? 1 : 0; + byte ultra_66 = ((id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008)) ? 1 : 0; + byte ultra_100 = ((id->dma_ultra & 0x0020) || + (id->dma_ultra & 0x0010) || + (id->dma_ultra & 0x0008)) ? 1 : 0; pci_read_config_word(dev, 0x50, &EP); - if ((ultra_66) && (EP & c_mask)) { + if (((ultra_66) || (ultra_100)) && (EP & c_mask)) { #ifdef DEBUG printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary", "Primary"); printk(" Switching to Ultra33 mode.\n"); @@ -449,13 +507,14 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) /* Secondary : zero out fourth bit */ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11)); } else { - if (ultra_66) { + if ((ultra_66) || (ultra_100)) { /* * check to make sure drive on same channel * is u66 capable */ if (hwif->drives[!(drive->dn%2)].id) { - if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || + if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) || + (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) || (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) { OUT_BYTE(CLKSPD | mask, (high_16 + 0x11)); } else { @@ -517,17 +576,18 @@ chipset_is_set: if (drive->media == ide_disk) /* PREFETCH_EN */ pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN); - if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) speed = XFER_UDMA_4; - else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) speed = XFER_UDMA_3; - else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; - else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; - else if ((id->dma_ultra & 0x0001) && (udma_33)) 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; + if ((id->dma_ultra & 0x0020) && (udma_100)) speed = XFER_UDMA_5; + else if ((id->dma_ultra & 0x0010) && (udma_66)) speed = XFER_UDMA_4; + else if ((id->dma_ultra & 0x0008) && (udma_66)) speed = XFER_UDMA_3; + else if ((id->dma_ultra & 0x0004) && (udma_33)) speed = XFER_UDMA_2; + else if ((id->dma_ultra & 0x0002) && (udma_33)) speed = XFER_UDMA_1; + else if ((id->dma_ultra & 0x0001) && (udma_33)) 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 { /* restore original pci-config space */ pci_write_config_dword(dev, drive_pci, drive_conf); @@ -537,7 +597,7 @@ chipset_is_set: outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2); (void) pdc202xx_tune_chipset(drive, speed); - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + return ((int) ((id->dma_ultra >> 11) & 7) ? 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 : @@ -558,7 +618,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive, 1); if ((id->field_valid & 2) && @@ -603,6 +663,10 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); + case ide_dma_lostirq: + case ide_dma_timeout: + if (HWIF(drive)->resetproc != NULL) + HWIF(drive)->resetproc(drive); default: break; } @@ -610,14 +674,29 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive) } #endif /* CONFIG_BLK_DEV_IDEDMA */ +void pdc202xx_reset (ide_drive_t *drive) +{ + unsigned long high_16 = pci_resource_start(HWIF(drive)->pci_dev, 4); + byte udma_speed_flag = inb(high_16 + 0x001f); + int i = 0; + + OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f); + ide_delay_50ms(); + ide_delay_50ms(); + OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f); + for (i = 0; i < 40; i++) + ide_delay_50ms(); +} + unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) { - unsigned long high_16 = dev->resource[4].start & PCI_BASE_ADDRESS_IO_MASK; + unsigned long high_16 = pci_resource_start(dev, 4); byte udma_speed_flag = inb(high_16 + 0x001f); byte primary_mode = inb(high_16 + 0x001a); byte secondary_mode = inb(high_16 + 0x001b); - if (dev->device == PCI_DEVICE_ID_PROMISE_20262) { + if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (dev->device == PCI_DEVICE_ID_PROMISE_20267)) { int i = 0; /* * software reset - this is required because the bios @@ -646,7 +725,7 @@ unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name) byte irq = 0, irq2 = 0; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2); /* 0xbc */ - if (irq != irq2) { + if ((irq != irq2) && (dev->device != PCI_DEVICE_ID_PROMISE_20267)) { pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ printk("%s: pci-config space interrupt mirror fixed.\n", name); } @@ -705,8 +784,12 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif) void __init ide_init_pdc202xx (ide_hwif_t *hwif) { - hwif->tuneproc = &pdc202xx_tune_drive; - hwif->speedproc = &pdc202xx_tune_chipset; + hwif->tuneproc = &pdc202xx_tune_drive; + hwif->speedproc = &pdc202xx_tune_chipset; + + if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) || + (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) + hwif->resetproc = &pdc202xx_reset; #ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 56c185236..0dbb8d883 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c @@ -1,8 +1,8 @@ /* - * linux/drivers/ide/piix.c Version 0.31 Mar. 18, 2000 + * linux/drivers/ide/piix.c Version 0.32 June 9, 2000 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * PIO mode setting function for Intel chipsets. @@ -83,7 +83,7 @@ static struct pci_dev *bmide_dev; static int piix_get_info (char *buffer, char **addr, off_t offset, int count) { char *p = buffer; - u32 bibma = bmide_dev->resource[4].start; + u32 bibma = pci_resource_start(bmide_dev, 4); u16 reg40 = 0, psitre = 0, reg42 = 0, ssitre = 0; u8 c0 = 0, c1 = 0; u8 reg44 = 0, reg48 = 0, reg4a = 0, reg4b = 0, reg54 = 0, reg55 = 0; @@ -108,10 +108,14 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) c1 = inb_p((unsigned short)bibma + 0x0a); switch(bmide_dev->device) { + case PCI_DEVICE_ID_INTEL_82820FW_5: + p += sprintf(p, "\n Intel PIIX4 Ultra 100 Chipset.\n"); + break; case PCI_DEVICE_ID_INTEL_82372FB_1: case PCI_DEVICE_ID_INTEL_82801AA_1: p += sprintf(p, "\n Intel PIIX4 Ultra 66 Chipset.\n"); break; + case PCI_DEVICE_ID_INTEL_82451NX: case PCI_DEVICE_ID_INTEL_82801AB_1: case PCI_DEVICE_ID_INTEL_82443MX_1: case PCI_DEVICE_ID_INTEL_82371AB: @@ -142,21 +146,25 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) (reg48&0x04) ? "yes" : "no ", (reg48&0x08) ? "yes" : "no " ); p += sprintf(p, "UDMA enabled: %s %s %s %s\n", + ((reg54&0x11) && (reg55&0x10) && (reg4a&0x01)) ? "5" : ((reg54&0x11) && (reg4a&0x02)) ? "4" : ((reg54&0x11) && (reg4a&0x01)) ? "3" : (reg4a&0x02) ? "2" : (reg4a&0x01) ? "1" : (reg4a&0x00) ? "0" : "X", + ((reg54&0x22) && (reg55&0x20) && (reg4a&0x10)) ? "5" : ((reg54&0x22) && (reg4a&0x20)) ? "4" : ((reg54&0x22) && (reg4a&0x10)) ? "3" : (reg4a&0x20) ? "2" : (reg4a&0x10) ? "1" : (reg4a&0x00) ? "0" : "X", + ((reg54&0x44) && (reg55&0x40) && (reg4b&0x03)) ? "5" : ((reg54&0x44) && (reg4b&0x02)) ? "4" : ((reg54&0x44) && (reg4b&0x01)) ? "3" : (reg4b&0x02) ? "2" : (reg4b&0x01) ? "1" : (reg4b&0x00) ? "0" : "X", + ((reg54&0x88) && (reg55&0x80) && (reg4b&0x30)) ? "5" : ((reg54&0x88) && (reg4b&0x20)) ? "4" : ((reg54&0x88) && (reg4b&0x10)) ? "3" : (reg4b&0x20) ? "2" : @@ -188,6 +196,7 @@ extern char *ide_xfer_verbose (byte xfer_rate); */ static byte piix_dma_2_pio (byte xfer_rate) { switch(xfer_rate) { + case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: case XFER_UDMA_2: @@ -286,6 +295,7 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed) switch(speed) { case XFER_UDMA_4: case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; + case XFER_UDMA_5: case XFER_UDMA_3: case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; @@ -298,7 +308,11 @@ static int piix_tune_chipset (ide_drive_t *drive, byte speed) if (speed >= XFER_UDMA_0) { if (!(reg48 & u_flag)) pci_write_config_word(dev, 0x48, reg48|u_flag); - pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag); + if (speed == XFER_UDMA_5) { + pci_write_config_byte(dev, 0x55, (byte) reg55|w_flag); + } else { + pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag); + } if (!(reg4a & u_speed)) { pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); pci_write_config_word(dev, 0x4a, reg4a|u_speed); @@ -341,15 +355,20 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) struct pci_dev *dev = hwif->pci_dev; byte speed; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; - int ultra66 = ((dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || + byte udma_66 = eighty_ninty_three(drive); + int ultra100 = ((dev->device == PCI_DEVICE_ID_INTEL_82820FW_5)) ? 1 : 0; + int ultra66 = ((ultra100) || + (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0; int ultra = ((ultra66) || (dev->device == PCI_DEVICE_ID_INTEL_82371AB) || (dev->device == PCI_DEVICE_ID_INTEL_82443MX_1) || + (dev->device == PCI_DEVICE_ID_INTEL_82451NX) || (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0; - if ((id->dma_ultra & 0x0010) && (ultra)) { + if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra)) { speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; } else if ((id->dma_ultra & 0x0008) && (ultra)) { speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; @@ -371,7 +390,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive) (void) piix_tune_chipset(drive, speed); - return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on : + return ((int) ((id->dma_ultra >> 11) & 7) ? 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 : diff --git a/drivers/ide/qd6580.c b/drivers/ide/qd6580.c index 4c00de504..5787b73f2 100644 --- a/drivers/ide/qd6580.c +++ b/drivers/ide/qd6580.c @@ -1,16 +1,19 @@ /* - * linux/drivers/ide/qd6580.c Version 0.03 May 13, 2000 + * linux/drivers/ide/qd6580.c Version 0.04 June 4, 2000 * * Copyright (C) 1996-2000 Linus Torvalds & author (see below) */ /* * Version 0.03 Cleaned auto-tune, added probe - * + * Version 0.04 Added second channel tuning + * * QDI QD6580 EIDE controller fast support - * + * * To activate controller support use kernel parameter "ide0=qd6580" * To enable tuning use kernel parameter "ide0=autotune" + * To enable tuning second channel (not really tested), + * use parameter "ide1=autotune" */ /* @@ -36,146 +39,254 @@ #include "ide_modes.h" /* - * I/O ports are 0xb0 0xb1 0xb2 and 0xb3 - * or 0x30 0x31 0x32 and 0x33 + * I/O ports are 0xb0-0xb3 + * or 0x30-0x33 * -- this is a dual IDE interface with I/O chips * * More research on qd6580 being done by willmore@cig.mot.com (David) + * More Information given by Petr Sourcek (petr@ryston.cz) + * http://www.ryston.cz/petr/vlb */ -/* +/* * 0xb0: Timer1 * - * - * 0xb1: Status * - * && 0xf0 is either 0b1010000 or 0b01010000, or else it isn't a qd6580 - * bit 3 & 2: unknown (useless ?) I have 0 & 1, respectively - * bit 1: 1 if qd6580 baseport is 0xb0 - * 0 if qd6580 baseport is 0x30 - * bit 0: 1 if ide baseport is 0x1f0 - * 0 if ide baseport is 0x170 + * 0xb1: Config + * + * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 * (? Strange: the Dos driver uses it, and then forces baseport to 0x1f0 ?) - * - * + * bit 1: qd baseport: 1 = 0xb0 ; 0 = 0x30 + * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz + * bit 3: 1 for qd6580 + * upper nibble is either 1010 or 0101, or else it isn't a qd6580 + * + * * 0xb2: Timer2 * - * + * * 0xb3: Control * - * bits 0-3 are always set 1 - * bit 6 : if 1, must be set 1 - * bit 1 : if 1, bit 7 must be set 1 - * bit 0 : if 1, drives are independant, we can have two different timers for - * the two drives. - * if 0, we have to take the slowest drive into account, - * but we may tune the second hwif ? + * bits 0-3 must always be set 1 + * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock + * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb + * 0 = Primary and Secondary ports enabled : channel 0 for hda & hdb + * channel 1 for hdc & hdd + * bit 1 : 1 = only disks on primary port + * 0 = disks & ATAPI devices on primary port + * bit 2-4 : always 0 + * bit 5 : status, but of what ? + * bit 6 : always set 1 by dos driver + * bit 7 : set 1 for non-ATAPI devices (read-ahead and post-write buffer ?) */ +/* truncates a in [b,c] */ +#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) ) + typedef struct ide_hd_timings_s { int active_time; /* Active pulse (ns) minimum */ int recovery_time; /* Recovery pulse (ns) minimum */ } ide_hd_timings_t; static int basePort; /* base port address (0x30 or 0xb0) */ -static byte status; /* status register of qd6580 */ +static byte config; /* config register of qd6580 */ static byte control; /* control register of qd6580 */ -/* truncates a in [b,c] */ -#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) ) - static int bus_clock; /* Vesa local bus clock (ns) */ static int tuned=0; /* to remember whether we've already been tuned */ +static int snd_tuned=0; /* to remember whether we've already been tuned */ +static int nb_disks_prim=0; /* number of disk drives on primary port */ + +/* + * write_reg + * + * writes the specified byte on the specified register + */ + +static void write_reg ( byte content, byte reg ) +{ + unsigned long flags; + + save_flags(flags); /* all CPUs */ + cli(); /* all CPUs */ + outb_p(content,reg); + inb(0x3f6); + restore_flags(flags); /* all CPUs */ +} /* * tune_drive * - * Finds timings for the specified drive, returns it in struc t + * Finds timings for the specified drive, returns it in struct t */ -static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t) +static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t ) { ide_pio_data_t d; - t->active_time = 0xaf; - t->recovery_time = 0x19f; /* worst cases values from the dos driver */ + t->active_time = 175; + t->recovery_time = 415; /* worst cases values from the dos driver */ - if (drive->present == 0) { /* not present : free to give any timing */ - t->active_time = 0x0; - t->recovery_time = 0x0; + if (!drive->present) { /* not present : free to give any timing */ + t->active_time = 0; + t->recovery_time = 0; return; } - - pio = ide_get_best_pio_mode(drive, pio, 4, &d); - - if (pio) { - - switch (pio) { - case 0: break; - case 3: t->active_time = 0x56; - t->recovery_time = d.cycle_time-0x66; - break; - case 4: t->active_time = 0x46; - t->recovery_time = d.cycle_time-0x3d; - break; - default: if (d.cycle_time >= 0xb4) { - t->active_time = 0x6e; - t->recovery_time = d.cycle_time - 0x78; - } else { - t->active_time = ide_pio_timings[pio].active_time; - t->recovery_time = d.cycle_time - -t->active_time - -ide_pio_timings[pio].setup_time; - } - } - } + + pio = ide_get_best_pio_mode(drive, pio, 255, &d); + pio = IDE_MIN(pio,4); + + switch (pio) { + case 0: break; + case 3: + if (d.cycle_time >= 110) { + t->active_time = 86; + t->recovery_time = d.cycle_time-102; + } else { + printk("%s: Strange recovery time !\n",drive->name); + return; + } + break; + case 4: + if (d.cycle_time >= 69) { + t->active_time = 70; + t->recovery_time = d.cycle_time-61; + } else { + printk("%s: Strange recovery time !\n",drive->name); + return; + } + break; + default: + if (d.cycle_time >= 180) { + t->active_time = 110; + t->recovery_time = d.cycle_time - 120; + } else { + t->active_time = ide_pio_timings[pio].active_time; + t->recovery_time = d.cycle_time + -t->active_time; + } + } printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time); + + if (drive->media == ide_disk) + nb_disks_prim++; + else { +/* need to disable read-ahead FIFO and post-write buffer for ATAPI drives*/ + write_reg(0x5f,basePort+0x03); + printk("%s: Warning: please try to connect this drive to secondary IDE port\nto improve data transfer rate on primary IDE port.\n",drive->name); + } } -/* +/* + * tune_snd_drive + * + * Finds timings for the specified drive, using second channel rules + */ + +static void tune_snd_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t ) +{ + ide_pio_data_t d; + + t->active_time = 175; + t->recovery_time = 415; + + if (!drive->present) { /* not present : free to give any timing */ + t->active_time = 0; + t->recovery_time = 0; + return; + } + + pio = ide_get_best_pio_mode(drive, pio, 255, &d); + + if ((pio) && (d.cycle_time >= 180)) { + t->active_time = 115; + t->recovery_time = d.cycle_time - 115; + } + printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time); + + if ((drive->media == ide_disk) && (nb_disks_prim<2)) { +/* a disk drive on secondary port while there's room on primary, which is the + * only one that has read-ahead fifo and post-write buffer ? What a waste !*/ + printk("%s: Warning: please try to connect this drive to primary IDE port\nto improve data transfer rate.\n",drive->name); + } +} + +/* + * compute_timing + * + * computes the timing value where + * lower nibble is active time, in count of VLB clocks, 17-(from 2 to 17) + * upper nibble is recovery time, in count of VLB clocks, 15-(from 2 to 15) + */ + +static byte compute_timing ( char name[6], ide_hd_timings_t *t ) +{ + byte active_cycle; + byte recovery_cycle; + byte parameter; + + active_cycle = 17-IDE_IN(t->active_time / bus_clock + 1, 2, 17); + recovery_cycle = 15-IDE_IN(t->recovery_time / bus_clock + 1, 2, 15); + + parameter = active_cycle | (recovery_cycle<<4); + + printk("%s: tim1=%dns tim2=%dns => %#x\n", name, t[0].active_time, t[0].recovery_time, parameter); + return(parameter); +} + +/* * tune_ide * - * Tunes the whole ide, ie tunes each drives, and takes the worst timings - * to tune qd6580 + * Tunes the whole hwif, ie tunes each drives, and in case we have to share, + * takes the worse timings to tune qd6580 */ static void tune_ide ( ide_hwif_t *hwif, byte pio ) { unsigned long flags; ide_hd_timings_t t[2]={{0,0},{0,0}}; - - byte active_cycle; - byte recovery_cycle; - byte parameter; int bus_speed = ide_system_bus_speed (); - + bus_clock = 1000 / bus_speed; - + save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ outb( (bus_clock<30) ? 0x0 : 0x0a, basePort + 0x02); outb( 0x40 | ((control & 0x02) ? 0x9f:0x1f), basePort+0x03); - restore_flags(flags); + restore_flags(flags); tune_drive (&hwif->drives[0], pio, &t[0]); tune_drive (&hwif->drives[1], pio, &t[1]); + if (control & 0x01) { /* only primary port enabled, can tune separately */ + write_reg(compute_timing (hwif->drives[0].name, &t[0]),basePort); + write_reg(compute_timing (hwif->drives[1].name, &t[1]),basePort+0x02); + } else { /* both ports enabled, we have to share */ + + t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time); + t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time); + write_reg(compute_timing (hwif->name, &t[0]),basePort); + } +} + +/* + * tune_snd_ide + * + * Tunes the whole secondary hwif, ie tunes each drives, and takes the worse + * timings to tune qd6580 + */ + +static void tune_snd_ide ( ide_hwif_t *hwif, byte pio ) +{ + ide_hd_timings_t t[2]={{0,0},{0,0}}; + + tune_snd_drive (&hwif->drives[0], pio, &t[0]); + tune_snd_drive (&hwif->drives[1], pio, &t[1]); + t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time); t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time); - - active_cycle = 17-IDE_IN(t[0].active_time / bus_clock + 1, 2, 17); - recovery_cycle = 15-IDE_IN(t[0].recovery_time / bus_clock + 1, 2, 15); - - parameter=active_cycle | (recovery_cycle<<4); - - printk("%s: tim1=%dns tim2=%dns => %#x\n", hwif->name, t[0].active_time, t[0].recovery_time, parameter); - - save_flags(flags); /* all CPUs */ - cli(); /* all CPUs */ - outb_p(parameter,0xb0); - inb(0x3f6); - restore_flags(flags); /* all CPUs */ - + + write_reg(compute_timing (hwif->name, &t[0]),basePort+0x02); } /* @@ -193,6 +304,20 @@ static void tune_qd6580 (ide_drive_t *drive, byte pio) } /* + * tune_snd_qd6580 + * + * tunes the second hwif if not tuned + */ + +static void tune_snd_qd6580 (ide_drive_t *drive, byte pio) +{ + if (! snd_tuned) { + tune_snd_ide(HWIF(drive), pio); + snd_tuned = 1; + } +} + +/* * testreg * * tests if the given port is a register @@ -203,7 +328,7 @@ static int __init testreg(int port) byte savereg; byte readreg; unsigned long flags; - + save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ savereg = inb(port); @@ -214,14 +339,15 @@ static int __init testreg(int port) if (savereg == 0x15) { printk("Outch ! the probe for qd6580 isn't reliable !\n"); - printk("Please contact samuel.thibault@fnac.net to tell about your hardware\n"); - printk("Assuming qd6580 is present"); + printk("Please contact maintainers to tell about your hardware\n"); + printk("Assuming qd6580 is not present.\n"); + return 0; } return (readreg == 0x15); } -/* +/* * trybase: * * tries to find a qd6580 at the given base and save it if found @@ -233,20 +359,20 @@ static int __init trybase (int base) save_flags(flags); /* all CPUs */ cli(); /* all CPUs */ - status = inb(base+0x01); + config = inb(base+0x01); control = inb(base+0x03); restore_flags(flags); /* all CPUs */ - if (((status & 0xf0) != 0x50) && ((status & 0xf0) != 0xa0)) return(0); - if (! ( ((status & 0x02) == 0x0) == (base == 0x30) ) ) return (0); + if (((config & 0xf0) != 0x50) && ((config & 0xf0) != 0xa0)) return(0); + if (! ( ((config & 0x02) == 0x0) == (base == 0x30) ) ) return (0); /* Seems to be OK, let's use it */ - + basePort = base; return(testreg(base)); } -/* +/* * probe: * * probes qd6580 at 0xb0 (the default) or 0x30 @@ -257,6 +383,11 @@ static int __init probe (void) return (trybase(0xb0) ? 1 : trybase(0x30)); } +/* + * init_qd6580: + * + * called at the very beginning of initialization ; should just probe and link + */ void __init init_qd6580 (void) { @@ -264,13 +395,16 @@ void __init init_qd6580 (void) printk("qd6580: not found\n"); return; } - - printk("qd6580: base=%#x, status=%#x, control=%#x\n", basePort, status, control); - + + printk("qd6580: base=%#x, config=%#x, control=%#x\n", basePort, config, control); + ide_hwifs[0].chipset = ide_qd6580; - ide_hwifs[1].chipset = ide_qd6580; ide_hwifs[0].tuneproc = &tune_qd6580; - ide_hwifs[0].mate = &ide_hwifs[1]; - ide_hwifs[1].mate = &ide_hwifs[0]; - ide_hwifs[1].channel = 1; + if (!(control & 0x01)) { + ide_hwifs[1].chipset = ide_qd6580; + ide_hwifs[1].tuneproc = &tune_snd_qd6580; + ide_hwifs[0].mate = &ide_hwifs[1]; + ide_hwifs[1].mate = &ide_hwifs[0]; + ide_hwifs[1].channel = 1; + } } diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c index be56a7f24..4f0a33086 100644 --- a/drivers/ide/sis5513.c +++ b/drivers/ide/sis5513.c @@ -1,7 +1,7 @@ /* - * linux/drivers/ide/sis5513.c Version 0.10 Mar. 18, 2000 + * linux/drivers/ide/sis5513.c Version 0.11 June 9, 2000 * - * Copyright (C) 1999-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * Thanks to SIS Taiwan for direct support and hardware. @@ -111,12 +111,12 @@ static int sis_get_info(char *, char **, off_t, int); extern int (*sis_display_info)(char *, char **, off_t, int); /* ide-proc.c */ static struct pci_dev *bmide_dev; -static char *cable_type[] __initdata = { +static char *cable_type[] = { "80 pins", "40 pins" }; -static char *recovery_time [] __initdata ={ +static char *recovery_time [] ={ "12 PCICLK", "1 PCICLK", "2 PCICLK", "3 PCICLK", "4 PCICLK", "5 PCICLCK", @@ -127,14 +127,14 @@ static char *recovery_time [] __initdata ={ "15 PCICLK", "15 PCICLK" }; -static char * cycle_time [] __initdata = { +static char * cycle_time [] = { "Undefined", "2 CLCK", "3 CLK", "4 CLK", "5 CLK", "6 CLK", "7 CLK", "8 CLK" }; -static char * active_time [] __initdata = { +static char * active_time [] = { "8 PCICLK", "1 PCICLCK", "2 PCICLK", "2 PCICLK", "4 PCICLK", "5 PCICLK", @@ -185,7 +185,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", - active_time[(reg & 0x07)], active_time[(reg &0x07)] ); + active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); rc = pci_read_config_byte(bmide_dev, 0x40, ®); rc = pci_read_config_byte(bmide_dev, 0x44, ®1); @@ -209,7 +209,7 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, " UDMA Cycle Time %s \t UDMA Cycle Time %s\n", cycle_time[(reg & 0x70) >> 4], cycle_time[(reg1 & 0x70) >> 4]); p += sprintf(p, " Data Active Time %s \t Data Active Time %s\n", - active_time[(reg & 0x07)], active_time[(reg &0x07)] ); + active_time[(reg & 0x07)], active_time[(reg1 &0x07)] ); rc = pci_read_config_byte(bmide_dev, 0x42, ®); rc = pci_read_config_byte(bmide_dev, 0x46, ®1); @@ -335,7 +335,7 @@ static void sis5513_tune_drive (ide_drive_t *drive, byte pio) #ifdef CONFIG_BLK_DEV_IDEDMA /* - * ((id->hw_config & 0x2000) && (HWIF(drive)->udma_four)) + * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) */ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) { @@ -349,7 +349,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) unsigned long dma_base = hwif->dma_base; byte unit = (drive->select.b.unit & 0x01); byte speed = 0x00, unmask = 0xE0, four_two = 0x00; - byte udma_66 = ((id->hw_config & 0x2000) && (hwif->udma_four)) ? 1 : 0; + byte udma_66 = eighty_ninty_three(drive); if (host_dev) { switch(host_dev->device) { @@ -536,7 +536,7 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name) pci_read_config_byte(dev, 0x52, ®52h); if (!(reg52h & 0x04)) { - /* set IDE controller to operate in Compabitility mode obly */ + /* set IDE controller to operate in Compabitility mode only */ pci_write_config_byte(dev, 0x52, reg52h|0x04); } #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c index e7ee2e977..c1aa3fb4e 100644 --- a/drivers/ide/trm290.c +++ b/drivers/ide/trm290.c @@ -224,10 +224,10 @@ void __init ide_init_trm290 (ide_hwif_t *hwif) struct pci_dev *dev = hwif->pci_dev; hwif->chipset = ide_trm290; - cfgbase = dev->resource[4].start; + cfgbase = pci_resource_start(dev, 4); if ((dev->class & 5) && cfgbase) { - hwif->config_data = cfgbase & PCI_BASE_ADDRESS_IO_MASK; + hwif->config_data = cfgbase; printk("TRM290: chip config base at 0x%04lx\n", hwif->config_data); } else { hwif->config_data = 0x3df0; diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c index 6c201599f..3ab298596 100644 --- a/drivers/ide/via82cxxx.c +++ b/drivers/ide/via82cxxx.c @@ -1,10 +1,10 @@ /* - * linux/drivers/ide/via82cxxx.c Version 0.09 Apr. 02, 2000 + * linux/drivers/ide/via82cxxx.c Version 0.10 June 9, 2000 * * Copyright (C) 1998-99 Michel Aubry, Maintainer * Copyright (C) 1999 Jeff Garzik, MVP4 Support * (jgarzik@mandrakesoft.com) - * Copyright (C) 1998-2000 Andre Hedrick (andre@suse.com) + * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org> * May be copied or modified under the terms of the GNU General Public License * * The VIA MVP-4 is reported OK with UDMA. @@ -101,19 +101,19 @@ 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 chipset_settings_25; byte ultra_settings_33; - byte chipset_settings_37; + byte chipset_settings_33; byte ultra_settings_37; - byte chipset_settings_41; + byte chipset_settings_37; byte ultra_settings_41; + byte chipset_settings_41; }; static struct chipset_bus_clock_list_entry * via82cxxx_table = NULL; -struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -134,7 +134,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_one [] = { { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xA9, 0x00, 0x00 } }; -struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -155,7 +155,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_two [] = { { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE } }; -struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, @@ -176,7 +176,7 @@ struct chipset_bus_clock_list_entry via82cxxx_type_three [] = { { 0, 0x03, 0xA8, 0x03, 0xA8, 0x03, 0xDB, 0x03, 0xFE } }; -struct chipset_bus_clock_list_entry via82cxxx_type_four [] = { +static struct chipset_bus_clock_list_entry via82cxxx_type_four [] = { /* speed */ /* 25 */ /* 33 */ /* 37.5 */ /* 41.5 */ #ifdef CONFIG_BLK_DEV_IDEDMA { XFER_UDMA_4, 0x00, 0x00, 0xE0, 0x20, 0xE1, 0x31, 0x00, 0x00 }, @@ -243,20 +243,20 @@ static const struct { #define arraysize(x) (sizeof(x)/sizeof(*(x))) -#undef DISPLAY_VIA_TIMINGS +#define DISPLAY_VIA_TIMINGS #if defined(DISPLAY_VIA_TIMINGS) && defined(CONFIG_PROC_FS) #include <linux/stat.h> #include <linux/proc_fs.h> -static char *FIFO_str[] __initdata = { +static char *FIFO_str[] = { " 1 ", "3/4", "1/2", "1/4" }; -static char *control3_str[] __initdata = { +static char *control3_str[] = { "No limitation", "64", "128", @@ -760,11 +760,15 @@ static int config_chipset_for_dma (ide_drive_t *drive) { struct hd_driveid *id = drive->id; byte speed = 0x00; + byte ultra66 = eighty_ninty_three(drive); + byte ultra100 = 0; int rval; - if ((id->dma_ultra & 0x0010) && (HWIF(drive)->udma_four)) { + if ((id->dma_ultra & 0x0020) && (ultra66) && (ultra100)) { + speed = XFER_UDMA_5; + } else if ((id->dma_ultra & 0x0010) && (ultra66)) { speed = XFER_UDMA_4; - } else if ((id->dma_ultra & 0x0008) && (HWIF(drive)->udma_four)) { + } else if ((id->dma_ultra & 0x0008) && (ultra66)) { speed = XFER_UDMA_3; } else if (id->dma_ultra & 0x0004) { speed = XFER_UDMA_2; @@ -778,12 +782,6 @@ static int config_chipset_for_dma (ide_drive_t *drive) 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); } @@ -793,7 +791,6 @@ static int config_chipset_for_dma (ide_drive_t *drive) rval = (int)( ((id->dma_ultra >> 11) & 3) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : - ((id->dma_1word >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly); return rval; } @@ -811,7 +808,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { - if (id->dma_ultra & 0x001F) { + if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && @@ -820,8 +817,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive) } } else if (id->field_valid & 2) { try_dma_modes: - if ((id->dma_mword & 0x0007) || - (id->dma_1word & 0x0007)) { + if (id->dma_mword & 0x0007) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) @@ -870,7 +866,7 @@ unsigned int __init pci_init_via82cxxx (struct pci_dev *dev, const char *name) byte revision = 0; for (i = 0; i < arraysize (ApolloHostChipInfo) && !host_dev; i++) { - host = pci_find_device (PCI_VENDOR_ID_VIA, + host = pci_find_device (ApolloHostChipInfo[i].vendor_id, ApolloHostChipInfo[i].host_id, NULL); if (!host) |