Commit 198231a8 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.7-pre2 IDE 22a

- Apply more patches from Vojtech Pavlik for the handling of host chip setup.
   Hopefully they are settled now.

- Kill unused CONFIG_BLK_DEV_MODES

- Push register addressing down in to task_vlb_sync.

- Make the taskfile parsing stuff actually readable. This is compressing the
   code by an incredible amount. We use just one function doing the whole
   scanning right now. This should make sure that the IRQ handler used by a
   particular command is always right.  I didn't introduce typos hopefully
   here.

- Don't call ide_handler_parser as argument for do_taskfile() any longer. We
   have killed this function by coalescing it's functionality with
   ide_cmd_type_parser() anyway.

- Kill unused SLC90E66 code, which Vojtech apparently missed in his patch.

- sync up with 2.5.7-pre2

Once again the actual patch is rather big mostly due to the removal of
some default configuration variables which are not used anylonger. So time for
the next patch stage.
parent ed0e83f5
......@@ -290,7 +290,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -274,7 +274,6 @@ CONFIG_BLK_DEV_CY82C693=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -564,7 +564,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -429,7 +429,6 @@ CONFIG_BLK_DEV_PDC202XX=y
# CONFIG_PDC202XX_BURST is not set
# CONFIG_BLK_DEV_OSB4 is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_SL82C105=y
......
......@@ -478,7 +478,6 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_SL82C105 is not set
......
......@@ -149,7 +149,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -305,7 +305,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -285,7 +285,6 @@ CONFIG_PIIX_TUNING=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -131,7 +131,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -248,7 +248,6 @@ CONFIG_BLK_DEV_PIIX=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -235,7 +235,6 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -235,7 +235,6 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -161,7 +161,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -350,7 +350,6 @@ if [ "$CONFIG_SGI_IP22" != "y" -a \
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -248,7 +248,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -317,7 +317,6 @@ CONFIG_IT8172_TUNING=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_IDE_CHIPSETS=y
......
......@@ -147,7 +147,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -425,7 +425,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -276,7 +276,6 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_SL82C105=y
......
......@@ -259,7 +259,6 @@ CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_SL82C105 is not set
......
......@@ -263,7 +263,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_SL82C105 is not set
......
......@@ -256,7 +256,6 @@ CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_PDC202XX_BURST is not set
# CONFIG_BLK_DEV_OSB4 is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_BLK_DEV_SL82C105 is not set
......
......@@ -266,7 +266,6 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_SL82C105=y
......
......@@ -270,7 +270,6 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
CONFIG_BLK_DEV_VIA82CXXX=y
CONFIG_BLK_DEV_SL82C105=y
......
......@@ -233,7 +233,6 @@ CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_SL82C105=y
......
......@@ -276,7 +276,6 @@ CONFIG_BLK_DEV_CMD64X=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_SL82C105=y
......
......@@ -92,7 +92,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -218,7 +218,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -110,14 +110,11 @@ if [ "$CONFIG_PCI" = "y" ]; then
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
else
define_bool CONFIG_IDE n
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
......
......@@ -112,7 +112,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -311,7 +311,6 @@ CONFIG_BLK_DEV_NS87415=y
# CONFIG_PDC202XX_FORCE is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_IDE_CHIPSETS is not set
......
......@@ -122,7 +122,6 @@ tristate 'ATA/IDE/MFM/RLL support' CONFIG_IDE
if [ "$CONFIG_IDE" != "n" ]; then
source drivers/ide/Config.in
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
define_bool CONFIG_BLK_DEV_HD n
fi
endmenu
......
......@@ -352,19 +352,10 @@ CONFIG_WDC_ALI15X3
SAY N!
CONFIG_BLK_DEV_AMD74XX
This driver ensures (U)DMA support for the AMD756/760 Viper
chipsets.
If you say Y here, you also need to say Y to "Use DMA by default
when available", above.
Please read the comments at the top of <file:drivers/ide/amd74xx.c>.
If unsure, say N.
CONFIG_AMD74XX_OVERRIDE
This option auto-forces the ata66 flag.
This effect can be also invoked by calling "idex=ata66"
If unsure, say N.
This driver adds explicit support for AMD-7xx and AMD-8111 chips
and also for the nVidia nForce chip. This allows the kernel to
change PIO, DMA and UDMA speeds and to configure the chip to
optimum performance.
CONFIG_BLK_DEV_CMD64X
Say Y here if you have an IDE controller which uses any of these
......@@ -435,28 +426,10 @@ CONFIG_BLK_DEV_SVWKS
chipsets.
CONFIG_BLK_DEV_PIIX
This driver adds PIO mode setting and tuning for all PIIX IDE
controllers by Intel. Since the BIOS can sometimes improperly tune
PIO 0-4 mode settings, this allows dynamic tuning of the chipset
via the standard end-user tool 'hdparm'.
Please read the comments at the top of <file:drivers/ide/piix.c>.
If you say Y here, you should also say Y to "PIIXn Tuning support",
below.
If unsure, say N.
CONFIG_PIIX_TUNING
This driver extension adds DMA mode setting and tuning for all PIIX
IDE controllers by Intel. Since the BIOS can sometimes improperly
set up the device/adapter combination and speed limits, it has
become a necessity to back/forward speed devices as needed.
Case 430HX/440FX PIIX3 need speed limits to reduce UDMA to DMA mode
2 if the BIOS can not perform this task at initialization.
If unsure, say N.
This driver adds explicit support for Intel PIIX and ICH chips
and also for the Efar Victory66 (slc90e66) chip. This allows
the kernel to change PIO, DMA and UDMA speeds and to configure
the chip to optimum performance.
CONFIG_BLK_DEV_PDC202XX
Promise Ultra33 or PDC20246
......@@ -513,19 +486,6 @@ CONFIG_BLK_DEV_SIS5513
Please read the comments at the top of <file:drivers/ide/sis5513.c>.
CONFIG_BLK_DEV_SLC90E66
This driver ensures (U)DMA support for Victroy66 SouthBridges for
SMsC with Intel NorthBridges. This is an Ultra66 based chipset.
The nice thing about it is that you can mix Ultra/DMA/PIO devices
and it will handle timing cycles. Since this is an improved
look-a-like to the PIIX4 it should be a nice addition.
If you say Y here, you need to say Y to "Use DMA by default when
available" as well.
Please read the comments at the top of
<file:drivers/ide/slc90e66.c>.
CONFIG_BLK_DEV_SL82C105
If you have a Winbond SL82c105 IDE controller, say Y here to enable
special configuration for this chip. This is common on various CHRP
......@@ -538,20 +498,9 @@ CONFIG_BLK_DEV_TRM290
Please read the comments at the top of <file:drivers/ide/trm290.c>.
CONFIG_BLK_DEV_VIA82CXXX
This allows you to configure your chipset for a better use while
running PIO/(U)DMA, it will allow you to enable efficiently the
second channel dma usage, as it may not be set by BIOS. It will try
to set fifo configuration at its best. It will allow you to get
information from /proc/ide/via provided you enabled "/proc file
system" support.
Please read the comments at the top of
<file:drivers/ide/via82cxxx.c>.
If you say Y here, then say Y to "Use DMA by default when available"
as well.
If unsure, say N.
This driver adds explicit support for VIA BusMastering IDE chips.
This allows the kernel to change PIO, DMA and UDMA speeds and to
configure the chip to optimum performance.
CONFIG_BLK_DEV_IDE_RAPIDE
Say Y here if you want to support the Yellowstone RapIDE controller
......
......@@ -53,18 +53,14 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
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_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' AMD Viper ATA-66 Override (WIP)' CONFIG_AMD74XX_OVERRIDE $CONFIG_BLK_DEV_AMD74XX $CONFIG_IDEDMA_PCI_WIP
dep_bool ' AMD and nVidia chipset support' CONFIG_BLK_DEV_AMD74XX $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' CMD64X chipset support' CONFIG_BLK_DEV_CMD64X $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
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 ' Intel and Efar (SMsC) chipset support' CONFIG_BLK_DEV_PIIX $CONFIG_BLK_DEV_IDEDMA_PCI
if [ "$CONFIG_MIPS_ITE8172" = "y" -o "$CONFIG_MIPS_IVR" = "y" ]; then
dep_mbool ' IT8172 IDE support' CONFIG_BLK_DEV_IT8172 $CONFIG_BLK_DEV_IDEDMA_PCI
dep_mbool ' IT8172 IDE Tuning support' CONFIG_IT8172_TUNING $CONFIG_BLK_DEV_IT8172 $CONFIG_IDEDMA_PCI_AUTO
......@@ -77,9 +73,8 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_bool ' Special FastTrak Feature' CONFIG_PDC202XX_FORCE $CONFIG_BLK_DEV_PDC202XX
dep_bool ' ServerWorks OSB4/CSB5 chipsets support' CONFIG_BLK_DEV_SVWKS $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
dep_bool ' SiS5513 chipset support' CONFIG_BLK_DEV_SIS5513 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
dep_bool ' SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $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' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' VIA chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
fi
if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
......@@ -167,32 +162,6 @@ 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 \
"$CONFIG_BLK_DEV_AMD74XX" = "y" -o \
"$CONFIG_BLK_DEV_CMD640" = "y" -o \
"$CONFIG_BLK_DEV_CMD64X" = "y" -o \
"$CONFIG_BLK_DEV_CS5530" = "y" -o \
"$CONFIG_BLK_DEV_CY82C693" = "y" -o \
"$CONFIG_BLK_DEV_HPT34X" = "y" -o \
"$CONFIG_BLK_DEV_HPT366" = "y" -o \
"$CONFIG_BLK_DEV_IDE_PMAC" = "y" -o \
"$CONFIG_BLK_DEV_OPTI621" = "y" -o \
"$CONFIG_BLK_DEV_SVWKS" = "y" -o \
"$CONFIG_BLK_DEV_PDC202XX" = "y" -o \
"$CONFIG_BLK_DEV_PIIX" = "y" -o \
"$CONFIG_BLK_DEV_IT8172" = "y" -o \
"$CONFIG_BLK_DEV_SIS5513" = "y" -o \
"$CONFIG_BLK_DEV_SLC90E66" = "y" -o \
"$CONFIG_BLK_DEV_SL82C105" = "y" -o \
"$CONFIG_BLK_DEV_VIA82CXXX" = "y" -o \
"$CONFIG_BLK_DEV_MPC8xx_IDE" = "y" ]; then
define_bool CONFIG_BLK_DEV_IDE_MODES y
else
define_bool CONFIG_BLK_DEV_IDE_MODES n
fi
dep_tristate 'Support for IDE Raid controllers' CONFIG_BLK_DEV_ATARAID $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL
dep_tristate ' Support Promise software RAID (Fasttrak(tm))' CONFIG_BLK_DEV_ATARAID_PDC $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
dep_tristate ' Highpoint 370 software RAID' CONFIG_BLK_DEV_ATARAID_HPT $CONFIG_BLK_DEV_IDE $CONFIG_EXPERIMENTAL $CONFIG_BLK_DEV_ATARAID
......
......@@ -60,7 +60,6 @@ ide-obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o
ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o
ide-obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o
ide-obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
ide-obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
ide-obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
......
/*
* $Id: amd74xx.c,v 2.7 2002/09/01 17:37:00 vojtech Exp $
* $Id: amd74xx.c,v 2.8 2002/03/14 11:52:20 vojtech Exp $
*
* Copyright (c) 2000-2002 Vojtech Pavlik
*
......@@ -46,13 +46,13 @@
#include "ata-timing.h"
#define AMD_IDE_ENABLE 0x40
#define AMD_IDE_CONFIG 0x41
#define AMD_CABLE_DETECT 0x42
#define AMD_DRIVE_TIMING 0x48
#define AMD_8BIT_TIMING 0x4e
#define AMD_ADDRESS_SETUP 0x4c
#define AMD_UDMA_TIMING 0x50
#define AMD_IDE_ENABLE (0x00 + amd_config->base)
#define AMD_IDE_CONFIG (0x01 + amd_config->base)
#define AMD_CABLE_DETECT (0x02 + amd_config->base)
#define AMD_DRIVE_TIMING (0x08 + amd_config->base)
#define AMD_8BIT_TIMING (0x0e + amd_config->base)
#define AMD_ADDRESS_SETUP (0x0c + amd_config->base)
#define AMD_UDMA_TIMING (0x10 + amd_config->base)
#define AMD_UDMA 0x07
#define AMD_UDMA_33 0x01
......@@ -66,18 +66,19 @@
*/
static struct amd_ide_chip {
char *name;
unsigned short id;
unsigned char rev;
unsigned int base;
unsigned char flags;
} amd_ide_chips[] = {
{ "8111", PCI_DEVICE_ID_AMD_8111_IDE, 0x00, AMD_UDMA_100 },
{ "768 Opus", PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, AMD_UDMA_100 },
{ "766 Viper", PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, AMD_UDMA_100 | AMD_BAD_FIFO },
{ "756/c4+ Viper", PCI_DEVICE_ID_AMD_VIPER_7409, 0x07, AMD_UDMA_66 },
{ "756 Viper", PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, AMD_UDMA_66 | AMD_BAD_SWDMA },
{ "755 Cobra", PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, AMD_UDMA_33 | AMD_BAD_SWDMA },
{ NULL }
{ PCI_DEVICE_ID_AMD_8111_IDE, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-8111 */
{ PCI_DEVICE_ID_AMD_OPUS_7441, 0x00, 0x40, AMD_UDMA_100 }, /* AMD-768 Opus */
{ PCI_DEVICE_ID_AMD_VIPER_7411, 0x00, 0x40, AMD_UDMA_100 | AMD_BAD_FIFO }, /* AMD-766 Viper */
{ PCI_DEVICE_ID_AMD_VIPER_7409, 0x07, 0x40, AMD_UDMA_66 }, /* AMD-756/c4+ Viper */
{ PCI_DEVICE_ID_AMD_VIPER_7409, 0x00, 0x40, AMD_UDMA_66 | AMD_BAD_SWDMA }, /* AMD-756 Viper */
{ PCI_DEVICE_ID_AMD_COBRA_7401, 0x00, 0x40, AMD_UDMA_33 | AMD_BAD_SWDMA }, /* AMD-755 Cobra */
{ PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, 0x00, 0x50, AMD_UDMA_100 }, /* nVidia nForce */
{ 0 }
};
static struct amd_ide_chip *amd_config;
......@@ -119,8 +120,8 @@ static int amd_get_info(char *buffer, char **addr, off_t offset, int count)
amd_print("----------AMD BusMastering IDE Configuration----------------");
amd_print("Driver Version: 2.7");
amd_print("South Bridge: AMD-%s", amd_config->name);
amd_print("Driver Version: 2.8");
amd_print("South Bridge: %s", bmide_dev->name);
pci_read_config_byte(dev, PCI_REVISION_ID, &t);
amd_print("Revision: IDE %#x", t);
......@@ -389,8 +390,8 @@ unsigned int __init pci_init_amd74xx(struct pci_dev *dev, const char *name)
*/
pci_read_config_byte(dev, PCI_REVISION_ID, &t);
printk(KERN_INFO "AMD_IDE: AMD-%s (rev %02x) IDE %s controller on pci%s\n",
amd_config->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name);
printk(KERN_INFO "AMD_IDE: %s (rev %02x) %s controller on pci%s\n",
dev->name, t, amd_dma[amd_config->flags & AMD_UDMA], dev->slot_name);
/*
* Register /proc/ide/amd74xx entry
......
......@@ -106,40 +106,51 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
return 0; /* lba_capacity value may be bad */
}
static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block);
static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block);
static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block);
/*
* do_rw_disk() issues READ and WRITE commands to a disk,
* using LBA if supported, or CHS otherwise, to address sectors.
* It also takes care of issuing special DRIVE_CMDs.
* Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
* otherwise, to address sectors. It also takes care of issuing special
* DRIVE_CMDs.
*/
static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
{
if (drive->blocked)
panic("ide: Request while drive blocked? You don't like your data intact?");
/*
* Wait until all request have bin finished.
*/
while (drive->blocked) {
yield();
// panic("ide: Request while drive blocked?");
}
if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "do_rw_disk, bad command");
blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
ide_end_request(drive, 0);
return ide_stopped;
}
if (IS_PDC4030_DRIVE) {
extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
return promise_rw_disk(drive, rq, block);
}
if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) /* 48-bit LBA */
return lba_48_rw_disk(drive, rq, block);
if (drive->select.b.lba) /* 28-bit LBA */
return lba_28_rw_disk(drive, rq, block);
/* 48-bit LBA */
if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
return lba48_do_request(drive, rq, block);
/* 28-bit LBA */
if (drive->select.b.lba)
return lba28_do_request(drive, rq, block);
/* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */
return chs_rw_disk(drive, rq, block);
/* 28-bit CHS */
return chs_do_request(drive, rq, block);
}
static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
{
int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
......@@ -147,23 +158,25 @@ static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
lba48bit = drive->addressing;
#endif
if ((cmd == READ) && (drive->using_dma))
return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
else if ((cmd == READ) && (drive->mult_count))
return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
else if (cmd == READ)
return (lba48bit) ? WIN_READ_EXT : WIN_READ;
else if ((cmd == WRITE) && (drive->using_dma))
return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
else if ((cmd == WRITE) && (drive->mult_count))
return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
else if (cmd == WRITE)
return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
else
return WIN_NOP;
if (cmd == READ) {
if (drive->using_dma)
return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
else if (drive->mult_count)
return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
else
return (lba48bit) ? WIN_READ_EXT : WIN_READ;
} else if (cmd == WRITE) {
if (drive->using_dma)
return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
else if (drive->mult_count)
return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
else
return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
}
return WIN_NOP;
}
static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
......@@ -203,19 +216,15 @@ static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsi
memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
args.command_type = ide_cmd_type_parser(&args);
args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
args.handler = ide_handler_parser(&taskfile, &hobfile);
args.posthandler = NULL;
args.rq = (struct request *) rq;
args.block = block;
rq->special = NULL;
rq->special = (ide_task_t *)&args;
ide_cmd_type_parser(&args);
args.rq = rq;
args.block = block;
rq->special = &args;
return do_rw_taskfile(drive, &args);
}
static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
......@@ -250,14 +259,10 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u
memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
args.command_type = ide_cmd_type_parser(&args);
args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
args.handler = ide_handler_parser(&taskfile, &hobfile);
args.posthandler = NULL;
args.rq = (struct request *) rq;
args.block = block;
rq->special = NULL;
rq->special = (ide_task_t *)&args;
ide_cmd_type_parser(&args);
args.rq = rq;
args.block = block;
rq->special = &args;
return do_rw_taskfile(drive, &args);
}
......@@ -268,7 +273,7 @@ static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, u
* 1073741822 == 549756 MB or 48bit addressing fake drive
*/
static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block)
static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
......@@ -314,13 +319,10 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u
memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
args.command_type = ide_cmd_type_parser(&args);
args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
args.handler = ide_handler_parser(&taskfile, &hobfile);
args.posthandler = NULL;
args.rq = (struct request *) rq;
args.block = block;
rq->special = (ide_task_t *)&args;
ide_cmd_type_parser(&args);
args.rq = rq;
args.block = block;
rq->special = &args;
return do_rw_taskfile(drive, &args);
}
......@@ -637,9 +639,9 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
taskfile.high_cylinder = drive->cyl>>8;
taskfile.device_head = ((drive->head-1)|drive->select.all)&0xBF;
if (!IS_PDC4030_DRIVE) {
taskfile.sector_count = drive->sect;
taskfile.command = WIN_SPECIFY;
handler = ide_handler_parser(&taskfile, &hobfile);
taskfile.sector_count = drive->sect;
taskfile.command = WIN_SPECIFY;
handler = set_geometry_intr;;
}
do_taskfile(drive, &taskfile, &hobfile, handler);
} else if (s->b.recalibrate) {
......@@ -651,7 +653,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = drive->sect;
taskfile.command = WIN_RESTORE;
do_taskfile(drive, &taskfile, &hobfile, ide_handler_parser(&taskfile, &hobfile));
do_taskfile(drive, &taskfile, &hobfile, recal_intr);
}
} else if (s->b.set_multmode) {
s->b.set_multmode = 0;
......@@ -1089,7 +1091,7 @@ static struct ata_operations idedisk_driver = {
owner: THIS_MODULE,
cleanup: idedisk_cleanup,
standby: idedisk_standby,
do_request: do_rw_disk,
do_request: idedisk_do_request,
end_request: NULL,
ioctl: NULL,
open: idedisk_open,
......@@ -1127,7 +1129,7 @@ int idedisk_init (void)
{
ide_drive_t *drive;
int failed = 0;
MOD_INC_USE_COUNT;
while ((drive = ide_scan_devices(ATA_DISK, "ide-disk", NULL, failed++)) != NULL) {
if (ide_register_subdriver (drive, &idedisk_driver)) {
......
......@@ -119,6 +119,7 @@ extern void ide_init_pdc202xx(ide_hwif_t *);
extern unsigned int pci_init_piix(struct pci_dev *);
extern unsigned int ata66_piix(ide_hwif_t *);
extern void ide_init_piix(ide_hwif_t *);
extern void ide_dmacapable_piix(ide_hwif_t *, unsigned long);
#endif
#ifdef CONFIG_BLK_DEV_IT8172
......@@ -142,12 +143,6 @@ extern unsigned int ata66_sis5513(ide_hwif_t *);
extern void ide_init_sis5513(ide_hwif_t *);
#endif
#ifdef CONFIG_BLK_DEV_SLC90E66
extern unsigned int pci_init_slc90e66(struct pci_dev *);
extern unsigned int ata66_slc90e66(ide_hwif_t *);
extern void ide_init_slc90e66(ide_hwif_t *);
#endif
#ifdef CONFIG_BLK_DEV_SL82C105
extern unsigned int pci_init_sl82c105(struct pci_dev *);
extern void dma_init_sl82c105(ide_hwif_t *, unsigned long);
......@@ -197,19 +192,18 @@ typedef struct ide_pci_device_s {
static ide_pci_device_t pci_chipsets[] __initdata = {
#ifdef CONFIG_BLK_DEV_PIIX
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_0, NULL, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, NULL, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, NULL, NULL, ide_init_piix, NULL, {{0x6D,0x80,0x80}, {0x6F,0x80,0x80}}, ON_BOARD, 0, ATA_F_NODMA },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_init_piix, NULL, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, ATA_F_NOADMA },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_init_piix, ata66_piix, ide_init_piix, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371FB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82372FB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_9, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_8, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, pci_init_piix, ata66_piix, ide_init_piix, ide_dmacapable_piix, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
#endif
#ifdef CONFIG_BLK_DEV_VIA82CXXX
{PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576_1, pci_init_via82cxxx, ata66_via82cxxx, ide_init_via82cxxx, ide_dmacapable_via82cxxx, {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, ON_BOARD, 0, ATA_F_NOADMA },
......@@ -289,13 +283,11 @@ static ide_pci_device_t pci_chipsets[] __initdata = {
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7411, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7441, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_IDE, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_IDE, pci_init_amd74xx, ata66_amd74xx, ide_init_amd74xx, ide_dmacapable_amd74xx, {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, ON_BOARD, 0, 0 },
#endif
#ifdef CONFIG_BLK_DEV_PDC_ADMA
{PCI_VENDOR_ID_PDC, PCI_DEVICE_ID_PDC_1841, pci_init_pdcadma, ata66_pdcadma, ide_init_pdcadma, ide_dmacapable_pdcadma, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_NODMA },
#endif
#ifdef CONFIG_BLK_DEV_SLC90E66
{PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, pci_init_slc90e66, ata66_slc90e66, ide_init_slc90e66, NULL, {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, ON_BOARD, 0, 0 },
#endif
#ifdef CONFIG_BLK_DEV_SVWKS
{PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, pci_init_svwks, ata66_svwks, ide_init_svwks, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_DMA },
{PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, pci_init_svwks, ata66_svwks, ide_init_svwks, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
......@@ -311,6 +303,7 @@ static ide_pci_device_t pci_chipsets[] __initdata = {
{PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, NULL, NULL, NULL, NULL, {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_HINT, PCI_DEVICE_ID_HINT, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_HOLTEK, PCI_DEVICE_ID_HOLTEK_6565, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX, NULL, NULL, NULL, NULL, {{0x6D,0x80,0x80}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_NODMA },
{PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_FIXIRQ },
{PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_FIXIRQ },
{PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, ATA_F_FIXIRQ },
......
......@@ -118,10 +118,6 @@ int (*svwks_display_info)(char *, char **, off_t, int) = NULL;
extern byte sis_proc;
int (*sis_display_info)(char *, char **, off_t, int) = NULL;
#endif /* CONFIG_BLK_DEV_SIS5513 */
#ifdef CONFIG_BLK_DEV_SLC90E66
extern byte slc90e66_proc;
int (*slc90e66_display_info)(char *, char **, off_t, int) = NULL;
#endif /* CONFIG_BLK_DEV_SLC90E66 */
#ifdef CONFIG_BLK_DEV_VIA82CXXX
extern byte via_proc;
int (*via_display_info)(char *, char **, off_t, int) = NULL;
......@@ -593,10 +589,6 @@ void proc_ide_create(void)
if ((sis_display_info) && (sis_proc))
create_proc_info_entry("sis", 0, proc_ide_root, sis_display_info);
#endif /* CONFIG_BLK_DEV_SIS5513 */
#ifdef CONFIG_BLK_DEV_SLC90E66
if ((slc90e66_display_info) && (slc90e66_proc))
create_proc_info_entry("slc90e66", 0, proc_ide_root, slc90e66_display_info);
#endif /* CONFIG_BLK_DEV_SLC90E66 */
#ifdef CONFIG_BLK_DEV_VIA82CXXX
if ((via_display_info) && (via_proc))
create_proc_info_entry("via", 0, proc_ide_root, via_display_info);
......@@ -653,10 +645,6 @@ void proc_ide_destroy(void)
if ((sis_display_info) && (sis_proc))
remove_proc_entry("ide/sis", 0);
#endif /* CONFIG_BLK_DEV_SIS5513 */
#ifdef CONFIG_BLK_DEV_SLC90E66
if ((slc90e66_display_info) && (slc90e66_proc))
remove_proc_entry("ide/slc90e66",0);
#endif /* CONFIG_BLK_DEV_SLC90E66 */
#ifdef CONFIG_BLK_DEV_VIA82CXXX
if ((via_display_info) && (via_proc))
remove_proc_entry("ide/via",0);
......
......@@ -38,6 +38,8 @@
#define DTF(x...)
#endif
#define SUPPORT_VLB_SYNC 1
/*
* for now, taskfile requests are special :/
*/
......@@ -56,7 +58,7 @@ static inline void ide_unmap_rq(struct request *rq, char *to,
bio_kunmap_irq(to, flags);
}
static void ata_bswap_data (void *buffer, int wcount)
static void bswap_data (void *buffer, int wcount)
{
u16 *p = buffer;
......@@ -74,18 +76,20 @@ static void ata_bswap_data (void *buffer, int wcount)
* of the sector count register location, with interrupts disabled
* to ensure that the reads all happen together.
*/
static inline void task_vlb_sync(ide_ioreg_t port)
static inline void task_vlb_sync(ide_drive_t *drive)
{
IN_BYTE (port);
IN_BYTE (port);
IN_BYTE (port);
ide_ioreg_t port = IDE_NSECTOR_REG;
IN_BYTE(port);
IN_BYTE(port);
IN_BYTE(port);
}
#endif
/*
* This is used for most PIO data transfers *from* the IDE interface
*/
void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
void ata_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount)
{
byte io_32bit;
......@@ -107,7 +111,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
unsigned long flags;
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
task_vlb_sync(IDE_NSECTOR_REG);
task_vlb_sync(drive);
insl(IDE_DATA_REG, buffer, wcount);
__restore_flags(flags); /* local CPU only */
} else
......@@ -130,7 +134,7 @@ void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
/*
* This is used for most PIO data transfers *to* the IDE interface
*/
void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
void ata_output_data(ide_drive_t *drive, void *buffer, unsigned int wcount)
{
byte io_32bit;
......@@ -147,7 +151,7 @@ void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
unsigned long flags;
__save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */
task_vlb_sync(IDE_NSECTOR_REG);
task_vlb_sync(drive);
outsl(IDE_DATA_REG, buffer, wcount);
__restore_flags(flags); /* local CPU only */
} else
......@@ -188,7 +192,7 @@ void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount
insw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
return;
}
#endif /* CONFIG_ATARI */
#endif
ata_input_data (drive, buffer, bytecount / 4);
if ((bytecount & 0x03) >= 2)
insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
......@@ -208,25 +212,25 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun
outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
return;
}
#endif /* CONFIG_ATARI */
#endif
ata_output_data (drive, buffer, bytecount / 4);
if ((bytecount & 0x03) >= 2)
outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
outsw(IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
}
void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
void taskfile_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount)
{
ata_input_data(drive, buffer, wcount);
if (drive->bswap)
ata_bswap_data(buffer, wcount);
bswap_data(buffer, wcount);
}
void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
void taskfile_output_data(ide_drive_t *drive, void *buffer, unsigned int wcount)
{
if (drive->bswap) {
ata_bswap_data(buffer, wcount);
bswap_data(buffer, wcount);
ata_output_data(drive, buffer, wcount);
ata_bswap_data(buffer, wcount);
bswap_data(buffer, wcount);
} else {
ata_output_data(drive, buffer, wcount);
}
......@@ -235,7 +239,7 @@ void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount
/*
* Needed for PCI irq sharing
*/
int drive_is_ready (ide_drive_t *drive)
int drive_is_ready(ide_drive_t *drive)
{
byte stat = 0;
if (drive->waiting_for_dma)
......@@ -255,7 +259,7 @@ int drive_is_ready (ide_drive_t *drive)
if (IDE_CONTROL_REG)
stat = GET_ALTSTAT();
else
#endif /* CONFIG_IDEPCI_SHARE_IRQ */
#endif
stat = GET_STAT(); /* Note: this may clear a pending IRQ!! */
if (stat & BUSY_STAT)
......@@ -291,7 +295,7 @@ static ide_startstop_t bio_mulout_intr(ide_drive_t *drive);
* Called directly from execute_drive_cmd for the first bunch of sectors,
* afterwards only by the ISR
*/
static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
static ide_startstop_t task_mulout_intr(ide_drive_t *drive)
{
unsigned int msect, nsect;
byte stat = GET_STAT();
......@@ -314,6 +318,7 @@ static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
* necessary
*/
ide_end_request(drive, 1);
return ide_stopped;
}
......@@ -341,13 +346,14 @@ static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
/* Are we sure that this as all been already transfered? */
rq->current_nr_sectors -= nsect;
if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
{
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
......@@ -399,7 +405,9 @@ ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
return ide_started;
}
void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler)
void do_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile,
struct hd_drive_hob_hdr *hobfile,
ide_handler_t *handler)
{
struct hd_driveid *id = drive->id;
byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
......@@ -439,10 +447,6 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct
}
}
/*
* Handler for special commands without a data phase from ide-disk
*/
/*
* This is invoked on completion of a WIN_SETMULT cmd.
*/
......@@ -463,7 +467,7 @@ ide_startstop_t set_multmode_intr (ide_drive_t *drive)
/*
* This is invoked on completion of a WIN_SPECIFY cmd.
*/
static ide_startstop_t set_geometry_intr (ide_drive_t *drive)
ide_startstop_t set_geometry_intr (ide_drive_t *drive)
{
byte stat;
......@@ -480,7 +484,7 @@ static ide_startstop_t set_geometry_intr (ide_drive_t *drive)
/*
* This is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
*/
static ide_startstop_t recal_intr (ide_drive_t *drive)
ide_startstop_t recal_intr(ide_drive_t *drive)
{
byte stat = GET_STAT();
......@@ -713,37 +717,6 @@ static ide_startstop_t bio_mulout_intr (ide_drive_t *drive)
return ide_started;
}
/* Called by internal to feature out type of command being called */
ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile)
{
switch(taskfile->command) {
/* IDE_DRIVE_TASK_RAW_WRITE */
/* IDE_DRIVE_TASK_OUT */
case WIN_WRITE:
case WIN_WRITE_EXT:
case WIN_WRITE_VERIFY:
case WIN_WRITE_BUFFER:
case CFA_WRITE_SECT_WO_ERASE:
case WIN_DOWNLOAD_MICROCODE:
return &pre_task_out_intr;
case CFA_WRITE_MULTI_WO_ERASE:
case WIN_MULTWRITE:
case WIN_MULTWRITE_EXT:
return &pre_bio_out_intr;
case WIN_SMART:
if (taskfile->feature == SMART_WRITE_LOG_SECTOR)
return &pre_task_out_intr;
case WIN_WRITEDMA:
case WIN_WRITEDMA_QUEUED:
case WIN_WRITEDMA_EXT:
case WIN_WRITEDMA_QUEUED_EXT:
/* IDE_DRIVE_TASK_OUT */
default:
break;
}
return(NULL);
}
/*
* Handler for command with Read Multiple
*/
......@@ -798,154 +771,85 @@ static ide_startstop_t task_mulin_intr(ide_drive_t *drive)
return ide_started;
}
/* Called by internal to feature out type of command being called */
ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile)
{
switch(taskfile->command) {
case WIN_IDENTIFY:
case WIN_PIDENTIFY:
case CFA_TRANSLATE_SECTOR:
case WIN_READ_BUFFER:
case WIN_READ:
case WIN_READ_EXT:
return &task_in_intr;
case WIN_SECURITY_DISABLE:
case WIN_SECURITY_ERASE_UNIT:
case WIN_SECURITY_SET_PASS:
case WIN_SECURITY_UNLOCK:
case WIN_DOWNLOAD_MICROCODE:
case CFA_WRITE_SECT_WO_ERASE:
case WIN_WRITE_BUFFER:
case WIN_WRITE_VERIFY:
case WIN_WRITE:
case WIN_WRITE_EXT:
return &task_out_intr;
case WIN_MULTREAD:
case WIN_MULTREAD_EXT:
return &task_mulin_intr;
case CFA_WRITE_MULTI_WO_ERASE:
case WIN_MULTWRITE:
case WIN_MULTWRITE_EXT:
return &bio_mulout_intr;
case WIN_SMART:
switch(taskfile->feature) {
case SMART_READ_VALUES:
case SMART_READ_THRESHOLDS:
case SMART_READ_LOG_SECTOR:
return &task_in_intr;
case SMART_WRITE_LOG_SECTOR:
return &task_out_intr;
default:
return &task_no_data_intr;
}
case CFA_REQ_EXT_ERROR_CODE:
case CFA_ERASE_SECTORS:
case WIN_VERIFY:
case WIN_VERIFY_EXT:
case WIN_SEEK:
return &task_no_data_intr;
case WIN_SPECIFY:
return &set_geometry_intr;
case WIN_RESTORE:
return &recal_intr;
case WIN_DIAGNOSE:
case WIN_FLUSH_CACHE:
case WIN_FLUSH_CACHE_EXT:
case WIN_STANDBYNOW1:
case WIN_STANDBYNOW2:
case WIN_SLEEPNOW1:
case WIN_SLEEPNOW2:
case WIN_SETIDLE1:
case WIN_CHECKPOWERMODE1:
case WIN_CHECKPOWERMODE2:
case WIN_GETMEDIASTATUS:
case WIN_MEDIAEJECT:
return &task_no_data_intr;
case WIN_SETMULT:
return &set_multmode_intr;
case WIN_READ_NATIVE_MAX:
case WIN_SET_MAX:
case WIN_READ_NATIVE_MAX_EXT:
case WIN_SET_MAX_EXT:
case WIN_SECURITY_ERASE_PREPARE:
case WIN_SECURITY_FREEZE_LOCK:
case WIN_DOORLOCK:
case WIN_DOORUNLOCK:
case WIN_SETFEATURES:
return &task_no_data_intr;
case DISABLE_SEAGATE:
case EXABYTE_ENABLE_NEST:
return &task_no_data_intr;
#ifdef CONFIG_BLK_DEV_IDEDMA
case WIN_READDMA:
case WIN_IDENTIFY_DMA:
case WIN_READDMA_QUEUED:
case WIN_READDMA_EXT:
case WIN_READDMA_QUEUED_EXT:
case WIN_WRITEDMA:
case WIN_WRITEDMA_QUEUED:
case WIN_WRITEDMA_EXT:
case WIN_WRITEDMA_QUEUED_EXT:
#endif
case WIN_FORMAT:
case WIN_INIT:
case WIN_DEVICE_RESET:
case WIN_QUEUED_SERVICE:
case WIN_PACKETCMD:
default:
return NULL;
}
}
/* Called by ioctl to feature out type of command being called */
int ide_cmd_type_parser (ide_task_t *args)
void ide_cmd_type_parser(ide_task_t *args)
{
struct hd_drive_task_hdr *taskfile = (struct hd_drive_task_hdr *) args->tfRegister;
struct hd_drive_hob_hdr *hobfile = (struct hd_drive_hob_hdr *) args->hobRegister;
args->prehandler = ide_pre_handler_parser(taskfile, hobfile);
args->handler = ide_handler_parser(taskfile, hobfile);
args->prehandler = NULL;
args->handler = NULL;
switch(args->tfRegister[IDE_COMMAND_OFFSET]) {
case WIN_IDENTIFY:
case WIN_PIDENTIFY:
return IDE_DRIVE_TASK_IN;
args->handler = task_in_intr;
args->command_type = IDE_DRIVE_TASK_IN;
return;
case CFA_TRANSLATE_SECTOR:
case WIN_READ:
case WIN_READ_EXT:
case WIN_READ_BUFFER:
return IDE_DRIVE_TASK_IN;
args->handler = task_in_intr;
args->command_type = IDE_DRIVE_TASK_IN;
return;
case WIN_WRITE:
case WIN_WRITE_EXT:
case WIN_WRITE_VERIFY:
case WIN_WRITE_BUFFER:
case CFA_WRITE_SECT_WO_ERASE:
case WIN_DOWNLOAD_MICROCODE:
return IDE_DRIVE_TASK_RAW_WRITE;
args->prehandler = pre_task_out_intr;
args->handler = task_out_intr;
args->command_type = IDE_DRIVE_TASK_RAW_WRITE;
return;
case WIN_MULTREAD:
case WIN_MULTREAD_EXT:
return IDE_DRIVE_TASK_IN;
args->handler = task_mulin_intr;
args->command_type = IDE_DRIVE_TASK_IN;
return;
case CFA_WRITE_MULTI_WO_ERASE:
case WIN_MULTWRITE:
case WIN_MULTWRITE_EXT:
return IDE_DRIVE_TASK_RAW_WRITE;
args->prehandler = pre_bio_out_intr;
args->handler = bio_mulout_intr;
args->command_type = IDE_DRIVE_TASK_RAW_WRITE;
return;
case WIN_SECURITY_DISABLE:
case WIN_SECURITY_ERASE_UNIT:
case WIN_SECURITY_SET_PASS:
case WIN_SECURITY_UNLOCK:
return IDE_DRIVE_TASK_OUT;
args->handler = task_out_intr;
args->command_type = IDE_DRIVE_TASK_OUT;
return;
case WIN_SMART:
if (taskfile->feature == SMART_WRITE_LOG_SECTOR)
args->prehandler = pre_task_out_intr;
args->tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS;
args->tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS;
switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
case SMART_READ_VALUES:
case SMART_READ_THRESHOLDS:
case SMART_READ_LOG_SECTOR:
return IDE_DRIVE_TASK_IN;
args->handler = task_in_intr;
args->command_type = IDE_DRIVE_TASK_IN;
return;
case SMART_WRITE_LOG_SECTOR:
return IDE_DRIVE_TASK_OUT;
args->handler = task_out_intr;
args->command_type = IDE_DRIVE_TASK_OUT;
return;
default:
return IDE_DRIVE_TASK_NO_DATA;
args->handler = task_no_data_intr;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
}
#ifdef CONFIG_BLK_DEV_IDEDMA
case WIN_READDMA:
......@@ -953,17 +857,23 @@ int ide_cmd_type_parser (ide_task_t *args)
case WIN_READDMA_QUEUED:
case WIN_READDMA_EXT:
case WIN_READDMA_QUEUED_EXT:
return IDE_DRIVE_TASK_IN;
args->command_type = IDE_DRIVE_TASK_IN;
return;
case WIN_WRITEDMA:
case WIN_WRITEDMA_QUEUED:
case WIN_WRITEDMA_EXT:
case WIN_WRITEDMA_QUEUED_EXT:
return IDE_DRIVE_TASK_RAW_WRITE;
args->command_type = IDE_DRIVE_TASK_RAW_WRITE;
return;
#endif
case WIN_SETFEATURES:
args->handler = task_no_data_intr;
switch(args->tfRegister[IDE_FEATURE_OFFSET]) {
case SETFEATURES_XFER:
return IDE_DRIVE_TASK_SET_XFER;
args->command_type = IDE_DRIVE_TASK_SET_XFER;
return;
case SETFEATURES_DIS_DEFECT:
case SETFEATURES_EN_APM:
case SETFEATURES_DIS_MSN:
......@@ -980,16 +890,20 @@ int ide_cmd_type_parser (ide_task_t *args)
case SETFEATURES_DIS_RI:
case SETFEATURES_DIS_SI:
default:
return IDE_DRIVE_TASK_NO_DATA;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
}
case WIN_NOP:
case CFA_REQ_EXT_ERROR_CODE:
case CFA_ERASE_SECTORS:
case WIN_VERIFY:
case WIN_VERIFY_EXT:
case WIN_SEEK:
case WIN_SPECIFY:
args->handler = set_geometry_intr;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
case WIN_RESTORE:
args->handler = recal_intr;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
case WIN_DIAGNOSE:
case WIN_FLUSH_CACHE:
case WIN_FLUSH_CACHE_EXT:
......@@ -998,29 +912,48 @@ int ide_cmd_type_parser (ide_task_t *args)
case WIN_SLEEPNOW1:
case WIN_SLEEPNOW2:
case WIN_SETIDLE1:
case DISABLE_SEAGATE:
case WIN_CHECKPOWERMODE1:
case WIN_CHECKPOWERMODE2:
case WIN_GETMEDIASTATUS:
case WIN_MEDIAEJECT:
case WIN_SETMULT:
case CFA_REQ_EXT_ERROR_CODE:
case CFA_ERASE_SECTORS:
case WIN_VERIFY:
case WIN_VERIFY_EXT:
case WIN_SEEK:
case WIN_READ_NATIVE_MAX:
case WIN_SET_MAX:
case WIN_READ_NATIVE_MAX_EXT:
case WIN_SET_MAX_EXT:
case WIN_SECURITY_ERASE_PREPARE:
case WIN_SECURITY_FREEZE_LOCK:
case EXABYTE_ENABLE_NEST:
case WIN_DOORLOCK:
case WIN_DOORUNLOCK:
return IDE_DRIVE_TASK_NO_DATA;
case DISABLE_SEAGATE:
case EXABYTE_ENABLE_NEST:
args->handler = task_no_data_intr;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
case WIN_SETMULT:
args->handler = set_multmode_intr;
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
case WIN_NOP:
args->command_type = IDE_DRIVE_TASK_NO_DATA;
return;
case WIN_FORMAT:
case WIN_INIT:
case WIN_DEVICE_RESET:
case WIN_QUEUED_SERVICE:
case WIN_PACKETCMD:
default:
return IDE_DRIVE_TASK_INVALID;
args->command_type = IDE_DRIVE_TASK_INVALID;
return;
}
}
......@@ -1067,7 +1000,7 @@ int ide_wait_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, st
ide_init_drive_taskfile(&rq);
/* This is kept for internal use only !!! */
args.command_type = ide_cmd_type_parser (&args);
ide_cmd_type_parser(&args);
if (args.command_type != IDE_DRIVE_TASK_NO_DATA)
rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count;
......@@ -1232,14 +1165,13 @@ EXPORT_SYMBOL(taskfile_output_data);
EXPORT_SYMBOL(do_rw_taskfile);
EXPORT_SYMBOL(do_taskfile);
EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(set_geometry_intr);
EXPORT_SYMBOL(set_multmode_intr);
EXPORT_SYMBOL(task_no_data_intr);
EXPORT_SYMBOL(ide_wait_taskfile);
EXPORT_SYMBOL(ide_raw_taskfile);
EXPORT_SYMBOL(ide_pre_handler_parser);
EXPORT_SYMBOL(ide_handler_parser);
EXPORT_SYMBOL(ide_cmd_type_parser);
EXPORT_SYMBOL(ide_cmd_ioctl);
EXPORT_SYMBOL(ide_task_ioctl);
......@@ -654,14 +654,14 @@ ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigne
memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
memcpy(args.hobRegister, NULL, sizeof(struct hd_drive_hob_hdr));
args.command_type = ide_cmd_type_parser(&args);
ide_cmd_type_parser(&args);
/* We don't use the generic inerrupt handlers here? */
args.prehandler = NULL;
args.handler = NULL;
args.posthandler = NULL;
args.rq = (struct request *) rq;
args.rq = rq;
args.block = block;
rq->special = NULL;
rq->special = (ide_task_t *)&args;
rq->special = &args;
return do_pdc4030_io(drive, &args);
}
......
/*
* linux/drivers/ide/piix.c Version 0.32 June 9, 2000
* $Id: piix.c,v 1.2 2002/03/13 22:50:43 vojtech Exp $
*
* Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
* Copyright (c) 2000-2002 Vojtech Pavlik
*
* PIO mode setting function for Intel chipsets.
* For use instead of BIOS settings.
* Based on the work of:
* Andrzej Krzysztofowicz
* Andre Hedrick
*
* 40-41
* 42-43
*
* 41
* 43
*
* | PIO 0 | c0 | 80 | 0 | piix_tune_drive(drive, 0);
* | PIO 2 | SW2 | d0 | 90 | 4 | piix_tune_drive(drive, 2);
* | PIO 3 | MW1 | e1 | a1 | 9 | piix_tune_drive(drive, 3);
* | PIO 4 | MW2 | e3 | a3 | b | piix_tune_drive(drive, 4);
*
* sitre = word40 & 0x4000; primary
* sitre = word42 & 0x4000; secondary
*
* 44 8421|8421 hdd|hdb
*
* 48 8421 hdd|hdc|hdb|hda udma enabled
*
* 0001 hda
* 0010 hdb
* 0100 hdc
* 1000 hdd
*
* 4a 84|21 hdb|hda
* 4b 84|21 hdd|hdc
* Thanks to Daniela Egbert for advice on PIIX bugs.
*/
/*
* Intel PIIX/ICH and Efar Victory66 IDE driver for Linux.
*
* ata-33/82371AB
* ata-33/82371EB
* ata-33/82801AB ata-66/82801AA
* 00|00 udma 0 00|00 reserved
* 01|01 udma 1 01|01 udma 3
* 10|10 udma 2 10|10 udma 4
* 11|11 reserved 11|11 reserved
* UDMA66 and higher modes are autoenabled only in case the BIOS has detected a
* 80 wire cable. To ignore the BIOS data and assume the cable is present, use
* 'ide0=ata66' or 'ide1=ata66' on the kernel command line.
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 54 8421|8421 ata66 drive|ata66 enable
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* pci_read_config_word(HWIF(drive)->pci_dev, 0x40, &reg40);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x42, &reg42);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x44, &reg44);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x48, &reg48);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x4a, &reg4a);
* pci_read_config_word(HWIF(drive)->pci_dev, 0x54, &reg54);
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/pci.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ide.h>
#include <asm/io.h>
#include "ata-timing.h"
#define PIIX_DEBUG_DRIVE_INFO 0
#define PIIX_IDETIM0 0x40
#define PIIX_IDETIM1 0x42
#define PIIX_SIDETIM 0x44
#define PIIX_IDESTAT 0x47
#define PIIX_UDMACTL 0x48
#define PIIX_UDMATIM 0x4a
#define PIIX_IDECFG 0x54
#define PIIX_UDMA 0x07
#define PIIX_UDMA_NONE 0x00
#define PIIX_UDMA_33 0x01
#define PIIX_UDMA_66 0x02
#define PIIX_UDMA_V66 0x03
#define PIIX_UDMA_100 0x04
#define PIIX_NO_SITRE 0x08 /* Chip doesn't have separate slave timing */
#define PIIX_PINGPONG 0x10 /* Enable ping-pong buffers */
#define PIIX_VICTORY 0x20 /* Efar Victory66 has a different UDMA setup */
#define PIIX_CHECK_REV 0x40 /* May be a buggy revision of PIIX */
#define PIIX_NODMA 0x80 /* Don't do DMA with this chip */
/*
* Intel IDE chips
*/
static struct piix_ide_chip {
unsigned short id;
unsigned char flags;
} piix_ide_chips[] = {
{ PCI_DEVICE_ID_INTEL_82801CA_11, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801CA ICH3 */
{ PCI_DEVICE_ID_INTEL_82801CA_10, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801CAM ICH3-M */
{ PCI_DEVICE_ID_INTEL_82801BA_9, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801BA ICH2 */
{ PCI_DEVICE_ID_INTEL_82801BA_8, PIIX_UDMA_100 | PIIX_PINGPONG }, /* Intel 82801BAM ICH2-M */
{ PCI_DEVICE_ID_INTEL_82801AB_1, PIIX_UDMA_33 | PIIX_PINGPONG }, /* Intel 82801AB ICH0 */
{ PCI_DEVICE_ID_INTEL_82801AA_1, PIIX_UDMA_66 | PIIX_PINGPONG }, /* Intel 82801AA ICH */
{ PCI_DEVICE_ID_INTEL_82372FB_1, PIIX_UDMA_66 }, /* Intel 82372FB PIIX5 */
{ PCI_DEVICE_ID_INTEL_82443MX_1, PIIX_UDMA_33 }, /* Intel 82443MX MPIIX4 */
{ PCI_DEVICE_ID_INTEL_82371AB, PIIX_UDMA_33 }, /* Intel 82371AB/EB PIIX4/4E */
{ PCI_DEVICE_ID_INTEL_82371SB_1, PIIX_UDMA_NONE }, /* Intel 82371SB PIIX3 */
{ PCI_DEVICE_ID_INTEL_82371FB_1, PIIX_UDMA_NONE | PIIX_NO_SITRE | PIIX_CHECK_REV }, /* Intel 82371FB PIIX */
{ PCI_DEVICE_ID_EFAR_SLC90E66_1, PIIX_UDMA_V66 | PIIX_VICTORY }, /* Efar Victory66 */
{ 0 }
};
static struct piix_ide_chip *piix_config;
static unsigned char piix_enabled;
static unsigned int piix_80w;
static unsigned int piix_clock;
static char *piix_dma[] = { "MWDMA16", "UDMA33", "UDMA66", "UDMA66", "UDMA100" };
/*
* PIIX/ICH /proc entry.
*/
#define DISPLAY_PIIX_TIMINGS
#ifdef CONFIG_PROC_FS
#if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static int piix_get_info(char *, char **, off_t, int);
extern int (*piix_display_info)(char *, char **, off_t, int); /* ide-proc.c */
byte piix_proc;
int piix_base;
static struct pci_dev *bmide_dev;
extern int (*piix_display_info)(char *, char **, off_t, int); /* ide-proc.c */
#define piix_print(format, arg...) p += sprintf(p, format "\n" , ## arg)
#define piix_print_drive(name, format, arg...)\
p += sprintf(p, name); for (i = 0; i < 4; i++) p += sprintf(p, format, ## arg); p += sprintf(p, "\n");
static int piix_get_info (char *buffer, char **addr, off_t offset, int count)
static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
{
int speed[4], cycle[4], active[4], recover[4], dmaen[4], uen[4], udma[4], umul;
struct pci_dev *dev = bmide_dev;
unsigned int i, u;
unsigned short c, d, e;
unsigned char t;
char *p = buffer;
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;
if (bmide_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
p += sprintf(p, "\n Intel MPIIX Chipset.\n");
return p-buffer; /* => must be less than 4k! */
}
pci_read_config_word(bmide_dev, 0x40, &reg40);
pci_read_config_word(bmide_dev, 0x42, &reg42);
pci_read_config_byte(bmide_dev, 0x44, &reg44);
pci_read_config_byte(bmide_dev, 0x48, &reg48);
pci_read_config_byte(bmide_dev, 0x4a, &reg4a);
pci_read_config_byte(bmide_dev, 0x4b, &reg4b);
pci_read_config_byte(bmide_dev, 0x54, &reg54);
pci_read_config_byte(bmide_dev, 0x55, &reg55);
psitre = (reg40 & 0x4000) ? 1 : 0;
ssitre = (reg42 & 0x4000) ? 1 : 0;
/*
* at that point bibma+0x2 et bibma+0xa are byte registers
* to investigate:
*/
c0 = inb_p((unsigned short)bibma + 0x02);
c1 = inb_p((unsigned short)bibma + 0x0a);
p += sprintf(p, "\n %s Chipset.\n", bmide_dev->name);
p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
p += sprintf(p, " %sabled %sabled\n",
(c0&0x80) ? "dis" : " en",
(c1&0x80) ? "dis" : " en");
p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
p += sprintf(p, "DMA enabled: %s %s %s %s\n",
(c0&0x20) ? "yes" : "no ",
(c0&0x40) ? "yes" : "no ",
(c1&0x20) ? "yes" : "no ",
(c1&0x40) ? "yes" : "no " );
p += sprintf(p, "UDMA enabled: %s %s %s %s\n",
(reg48&0x01) ? "yes" : "no ",
(reg48&0x02) ? "yes" : "no ",
(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" :
(reg4b&0x10) ? "1" :
(reg4b&0x00) ? "0" : "X");
p += sprintf(p, "UDMA\n");
p += sprintf(p, "DMA\n");
p += sprintf(p, "PIO\n");
piix_print("----------PIIX BusMastering IDE Configuration---------------");
/*
* FIXME.... Add configuration junk data....blah blah......
*/
piix_print("Driver Version: 1.2");
piix_print("South Bridge: %s", bmide_dev->name);
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS) */
pci_read_config_byte(dev, PCI_REVISION_ID, &t);
piix_print("Revision: IDE %#x", t);
piix_print("Highest DMA rate: %s", piix_config->flags & PIIX_NODMA ? "No DMA"
: piix_dma[piix_config->flags & PIIX_UDMA]);
/*
* Used to set Fifo configuration via kernel command line:
*/
piix_print("BM-DMA base: %#x", piix_base);
piix_print("PCI clock: %d.%dMHz", piix_clock / 1000, piix_clock / 100 % 10);
byte piix_proc = 0;
piix_print("-----------------------Primary IDE-------Secondary IDE------");
extern char *ide_xfer_verbose (byte xfer_rate);
pci_read_config_word(dev, PIIX_IDETIM0, &d);
pci_read_config_word(dev, PIIX_IDETIM1, &e);
piix_print("Enabled: %10s%20s", (d & 0x8000) ? "yes" : "no", (e & 0x8000) ? "yes" : "no");
#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING)
/*
*
*/
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:
case XFER_UDMA_1:
case XFER_UDMA_0:
case XFER_MW_DMA_2:
case XFER_PIO_4:
return 4;
case XFER_MW_DMA_1:
case XFER_PIO_3:
return 3;
case XFER_SW_DMA_2:
case XFER_PIO_2:
return 2;
case XFER_MW_DMA_0:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
case XFER_PIO_1:
case XFER_PIO_0:
case XFER_PIO_SLOW:
default:
return 0;
c = inb(piix_base + 0x02) | (inb(piix_base + 0x0a) << 8);
piix_print("Simplex only: %10s%20s", (c & 0x80) ? "yes" : "no", (c & 0x8000) ? "yes" : "no");
piix_print("Cable Type: %10s%20s", (piix_80w & 1) ? "80w" : "40w", (piix_80w & 2) ? "80w" : "40w");
if (!piix_clock)
return p - buffer;
piix_print("-------------------drive0----drive1----drive2----drive3-----");
piix_print_drive("Prefetch+Post: ", "%10s", (((i & 2) ? d : e) & (1 << (2 + ((i & 1) << 2)))) ? "yes" : "no");
for (i = 0; i < 4; i++) {
pci_read_config_word(dev, PIIX_IDETIM0 + (i & 2), &d);
if (~piix_config->flags & PIIX_NO_SITRE)
pci_read_config_byte(dev, PIIX_SIDETIM, &t);
umul = 4;
udma[i] = uen[i] = 0;
active[i] = 12;
recover[i] = 18;
switch (i & 1) {
case 1: if (~d & 0x10) break;
if ((~piix_config->flags & PIIX_NO_SITRE) && (d & 0x4000)) {
active[i] = 5 - ((t >> (((i & 2) << 1) + 2)) & 3);
recover[i] = 4 - ((t >> (((i & 2) << 1) + 0)) & 3);
break;
}
case 0: if (~d & 0x01) break;
active[i] = 5 - ((d >> 12) & 3);
recover[i] = 4 - ((d >> 8) & 3);
}
dmaen[i] = (c & ((i & 1) ? 0x40 : 0x20) << ((i & 2) << 2));
cycle[i] = 1000000 / piix_clock * (active[i] + recover[i]);
speed[i] = 2 * piix_clock / (active[i] + recover[i]);
if (!(piix_config->flags & PIIX_UDMA))
continue;
pci_read_config_byte(dev, PIIX_UDMACTL, &t);
uen[i] = (t & (1 << i)) ? dmaen[i] : 0;
if (!uen[i])
continue;
pci_read_config_word(dev, PIIX_UDMATIM, &e);
pci_read_config_dword(dev, PIIX_IDECFG, &u);
if (~piix_config->flags & PIIX_VICTORY) {
if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 && (u & (1 << i))) umul = 2;
if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 && (u & ((1 << i) + 12))) umul = 1;
udma[i] = (4 - ((e >> (i << 2)) & 3)) * umul;
} else udma[i] = (8 - ((e >> (i << 2)) & 7)) * 2;
speed[i] = 8 * piix_clock / udma[i];
cycle[i] = 250000 * udma[i] / piix_clock;
}
piix_print_drive("Transfer Mode: ", "%10s", dmaen[i] ? (uen[i] ? "UDMA" : "DMA") : "PIO");
piix_print_drive("Address Setup: ", "%8dns", (1000000 / piix_clock) * 3);
piix_print_drive("Cmd Active: ", "%8dns", (1000000 / piix_clock) * 12);
piix_print_drive("Cmd Recovery: ", "%8dns", (1000000 / piix_clock) * 18);
piix_print_drive("Data Active: ", "%8dns", (1000000 / piix_clock) * active[i]);
piix_print_drive("Data Recovery: ", "%8dns", (1000000 / piix_clock) * recover[i]);
piix_print_drive("Cycle Time: ", "%8dns", cycle[i]);
piix_print_drive("Transfer Rate: ", "%4d.%dMB/s", speed[i] / 1000, speed[i] / 100 % 10);
return p - buffer; /* hoping it is less than 4K... */
}
#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */
#endif
/*
* Based on settings done by AMI BIOS
* (might be useful if drive is not registered in CMOS for any reason).
* piix_set_speed() writes timing values to the chipset registers
*/
static void piix_tune_drive (ide_drive_t *drive, byte pio)
{
unsigned long flags;
u16 master_data;
u8 slave_data;
int is_slave = (&HWIF(drive)->drives[1] == drive);
int master_port = HWIF(drive)->index ? 0x42 : 0x40;
int slave_port = 0x44;
/* ISP RTC */
byte timings[][2] = { { 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
if (pio == 255)
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
else
pio = min_t(byte, pio, 4);
pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
if (is_slave) {
master_data = master_data | 0x4000;
if (pio > 1)
/* enable PPE, IE and TIME */
master_data = master_data | 0x0070;
pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
slave_data = slave_data | (((timings[pio][0] << 2) | timings[pio][1])
<< (HWIF(drive)->index ? 4 : 0));
} else {
master_data = master_data & 0xccf8;
if (pio > 1)
/* enable PPE, IE and TIME */
master_data = master_data | 0x0007;
master_data = master_data | (timings[pio][0] << 12) |
(timings[pio][1] << 8);
}
save_flags(flags);
cli();
pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
if (is_slave)
pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
restore_flags(flags);
}
#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING)
static int piix_tune_chipset (ide_drive_t *drive, byte speed)
static void piix_set_speed(struct pci_dev *dev, unsigned char dn, struct ata_timing *timing, int umul)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
byte maslave = hwif->channel ? 0x42 : 0x40;
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int v_flag = 0x01 << drive->dn;
int w_flag = 0x10 << drive->dn;
int u_speed = 0;
int err = 0;
int sitre;
short reg4042, reg44, reg48, reg4a, reg54;
byte reg55;
pci_read_config_word(dev, maslave, &reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
pci_read_config_word(dev, 0x44, &reg44);
pci_read_config_word(dev, 0x48, &reg48);
pci_read_config_word(dev, 0x4a, &reg4a);
pci_read_config_word(dev, 0x54, &reg54);
pci_read_config_byte(dev, 0x55, &reg55);
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;
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
default: return -1;
unsigned short t;
unsigned char u;
unsigned int c;
pci_read_config_word(dev, PIIX_IDETIM0 + (dn & 2), &t);
switch (dn & 1) {
case 1:
if (timing->cycle > 9) {
t &= ~0x30;
break;
}
if (~piix_config->flags & PIIX_NO_SITRE) {
pci_read_config_byte(dev, PIIX_SIDETIM, &u);
u &= ~(0xf << ((dn & 2) << 1));
t |= 0x30;
u |= (4 - FIT(timing->recover, 1, 4)) << ((dn & 2) << 1);
u |= (5 - FIT(timing->active, 2, 5)) << (((dn & 2) << 1) + 2);
pci_write_config_byte(dev, PIIX_SIDETIM, u);
break;
}
case 0:
if ((~dn & 1) && timing->cycle > 9) {
t &= ~0x03;
break;
}
t &= 0xccff;
t |= 0x03 << ((dn & 1) << 2);
t |= (4 - FIT(timing->recover, 1, 4)) << 8;
t |= (5 - FIT(timing->active, 2, 5)) << 12;
}
if (speed >= XFER_UDMA_0) {
if (!(reg48 & u_flag))
pci_write_config_word(dev, 0x48, reg48|u_flag);
if (speed == XFER_UDMA_5) {
pci_write_config_byte(dev, 0x55, (byte) reg55|w_flag);
pci_write_config_word(dev, PIIX_IDETIM0 + (dn & 2), t);
if (!(piix_config->flags & PIIX_UDMA)) return;
pci_read_config_byte(dev, PIIX_UDMACTL, &u);
u &= ~(1 << dn);
if (timing->udma) {
u |= 1 << dn;
pci_read_config_word(dev, PIIX_UDMATIM, &t);
if (piix_config->flags & PIIX_VICTORY) {
t &= ~(0x07 << (dn << 2));
t |= (8 - FIT(timing->udma, 2, 8)) << (dn << 2);
} 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);
t &= ~(0x03 << (dn << 2));
t |= (4 - FIT(timing->udma, 2, 4)) << (dn << 2);
}
if (speed > XFER_UDMA_2) {
if (!(reg54 & v_flag)) {
pci_write_config_word(dev, 0x54, reg54|v_flag);
pci_write_config_word(dev, PIIX_UDMATIM, t);
if ((piix_config->flags & PIIX_UDMA) > PIIX_UDMA_33
&& ~piix_config->flags & PIIX_VICTORY) {
pci_read_config_dword(dev, PIIX_IDECFG, &c);
if ((piix_config->flags & PIIX_UDMA) > PIIX_UDMA_66)
c &= ~(1 << (dn + 12));
c &= ~(1 << dn);
switch (umul) {
case 2: c |= 1 << dn; break;
case 4: c |= 1 << (dn + 12); break;
}
} else {
pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
pci_write_config_dword(dev, PIIX_IDECFG, c);
}
}
if (speed < XFER_UDMA_0) {
if (reg48 & u_flag)
pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
if (reg54 & v_flag)
pci_write_config_word(dev, 0x54, reg54 & ~v_flag);
if (reg55 & w_flag)
pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag);
pci_write_config_byte(dev, PIIX_UDMACTL, u);
}
/*
* piix_set_drive() computes timing values configures the drive and
* the chipset to a desired transfer mode. It also can be called
* by upper layers.
*/
static int piix_set_drive(ide_drive_t *drive, unsigned char speed)
{
ide_drive_t *peer = HWIF(drive)->drives + (~drive->dn & 1);
struct ata_timing t, p;
int err, T, UT, umul;
if (speed != XFER_PIO_SLOW && speed != drive->current_speed)
if ((err = ide_config_drive_speed(drive, speed)))
return err;
umul = min((speed > XFER_UDMA_4) ? 4 : ((speed > XFER_UDMA_2) ? 2 : 1),
piix_config->flags & PIIX_UDMA);
if (piix_config->flags & PIIX_VICTORY)
umul = 2;
T = 1000000000 / piix_clock;
UT = T / umul;
ata_timing_compute(drive, speed, &t, T, UT);
if ((piix_config->flags & PIIX_NO_SITRE) && peer->present) {
ata_timing_compute(peer, peer->current_speed, &p, T, UT);
if (t.cycle <= 9 && p.cycle <= 9)
ata_timing_merge(&p, &t, &t, IDE_TIMING_ALL);
}
piix_tune_drive(drive, piix_dma_2_pio(speed));
piix_set_speed(HWIF(drive)->pci_dev, drive->dn, &t, umul);
#if PIIX_DEBUG_DRIVE_INFO
printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
#endif /* PIIX_DEBUG_DRIVE_INFO */
if (!drive->init_speed)
if (!drive->init_speed)
drive->init_speed = speed;
err = ide_config_drive_speed(drive, speed);
drive->current_speed = speed;
return err;
return 0;
}
static int piix_config_drive_for_dma (ide_drive_t *drive)
/*
* piix_tune_drive() is a callback from upper layers for
* PIO-only tuning.
*/
static void piix_tune_drive(ide_drive_t *drive, unsigned char pio)
{
struct hd_driveid *id = drive->id;
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
byte speed;
byte udma_66 = eighty_ninty_three(drive);
int ultra100 = ((dev->device == PCI_DEVICE_ID_INTEL_82801BA_8) ||
(dev->device == PCI_DEVICE_ID_INTEL_82801BA_9) ||
(dev->device == PCI_DEVICE_ID_INTEL_82801CA_10)) ? 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;
speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA
| (ultra ? XFER_UDMA : 0) | ((udma_66 & ultra66) ? XFER_UDMA_66 : 0)
| ((udma_66 & ultra100) ? XFER_UDMA_100 : 0));
(void) piix_tune_chipset(drive, speed);
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 :
ide_dma_off_quietly);
if (!((piix_enabled >> HWIF(drive)->channel) & 1))
return;
if (pio == 255) {
piix_set_drive(drive, ata_timing_mode(drive, XFER_PIO | XFER_EPIO));
return;
}
piix_set_drive(drive, XFER_PIO_0 + min_t(byte, pio, 5));
}
static void config_chipset_for_pio (ide_drive_t *drive)
#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* piix_dmaproc() is a callback from upper layers that can do
* a lot, but we use it for DMA/PIO tuning only, delegating everything
* else to the default ide_dmaproc().
*/
int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
piix_tune_drive(drive, ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0);
if (func == ide_dma_check) {
short w80 = HWIF(drive)->udma_four;
short speed = ata_timing_mode(drive,
XFER_PIO | XFER_EPIO |
(piix_config->flags & PIIX_NODMA ? 0 : (XFER_SWDMA | XFER_MWDMA |
(piix_config->flags & PIIX_UDMA ? XFER_UDMA : 0) |
(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 ? XFER_UDMA_66 : 0) |
(w80 && (piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 ? XFER_UDMA_100 : 0))));
piix_set_drive(drive, speed);
func = (HWIF(drive)->autodma && (speed & XFER_MODE) != XFER_PIO)
? ide_dma_on : ide_dma_off_quietly;
}
return ide_dmaproc(func, drive);
}
static int config_drive_xfer_rate (ide_drive_t *drive)
#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* The initialization callback. Here we determine the IDE chip type
* and initialize its drive independent registers.
*/
unsigned int __init pci_init_piix(struct pci_dev *dev, const char *name)
{
struct hd_driveid *id = drive->id;
ide_dma_action_t dma_func = ide_dma_on;
if (id && (id->capability & 1) && HWIF(drive)->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
if (id->dma_ultra & 0x003F) {
/* Force if Capable UltraDMA */
dma_func = piix_config_drive_for_dma(drive);
if ((id->field_valid & 2) &&
(dma_func != ide_dma_on))
goto try_dma_modes;
}
} else if (id->field_valid & 2) {
try_dma_modes:
if ((id->dma_mword & 0x0007) ||
(id->dma_1word & 0x007)) {
/* Force if Capable regular DMA modes */
dma_func = piix_config_drive_for_dma(drive);
if (dma_func != ide_dma_on)
goto no_dma_set;
unsigned int u;
unsigned short w;
unsigned char t;
int i;
/*
* Find out which Intel IDE this is.
*/
for (piix_config = piix_ide_chips; piix_config->id != 0; ++piix_config)
if (dev->device == piix_config->id)
break;
if (!piix_config->id) {
printk(KERN_WARNING "PIIX: Unknown PIIX/ICH chip %#x, contact Vojtech Pavlik <vojtech@ucw.cz>\n", dev->device);
return -ENODEV;
}
/*
* Check for possibly broken DMA configs.
*/
{
struct pci_dev *orion = NULL;
if (piix_config->flags & PIIX_CHECK_REV) {
pci_read_config_byte(dev, PCI_REVISION_ID, &t);
if (t < 2) {
printk(KERN_INFO "PIIX: Found buggy old PIIX rev %#x, disabling DMA\n", t);
piix_config->flags |= PIIX_NODMA;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
if (id->eide_dma_time > 150) {
goto no_dma_set;
}
if ((orion = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454GX, NULL))) {
pci_read_config_byte(orion, PCI_REVISION_ID, &t);
if (t < 4) {
printk(KERN_INFO "PIIX: Found buggy 82454GX Orion bridge rev %#x, disabling DMA\n", t);
piix_config->flags |= PIIX_NODMA;
}
/* Consult the list of known "good" drives */
dma_func = piix_config_drive_for_dma(drive);
if (dma_func != ide_dma_on)
goto no_dma_set;
} else {
goto fast_ata_pio;
}
} else if ((id->capability & 8) || (id->field_valid & 2)) {
fast_ata_pio:
dma_func = ide_dma_off_quietly;
no_dma_set:
config_chipset_for_pio(drive);
}
return HWIF(drive)->dmaproc(dma_func, drive);
}
static int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
switch (func) {
case ide_dma_check:
return config_drive_xfer_rate(drive);
default :
/*
* Check 80-wire cable presence.
*/
switch (piix_config->flags & PIIX_UDMA) {
case PIIX_UDMA_66:
case PIIX_UDMA_100:
pci_read_config_dword(dev, PIIX_IDECFG, &u);
piix_80w = ((u & 0x30) ? 1 : 0) | ((u & 0xc0) ? 2 : 0);
break;
case PIIX_UDMA_V66:
pci_read_config_byte(dev, PIIX_IDESTAT, &t);
piix_80w = ((t & 2) ? 1 : 0) | ((t & 1) ? 2 : 0);
break;
}
/* Other cases are done by generic IDE-DMA code. */
return ide_dmaproc(func, drive);
}
#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */
unsigned int __init pci_init_piix(struct pci_dev *dev)
{
#if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS)
/*
* Enable ping-pong buffers where applicable.
*/
if (piix_config->flags & PIIX_PINGPONG) {
pci_read_config_dword(dev, PIIX_IDECFG, &u);
u |= 0x400;
pci_write_config_dword(dev, PIIX_IDECFG, u);
}
/*
* Detect enabled interfaces, enable slave separate timing if possible.
*/
for (i = 0; i < 2; i++) {
pci_read_config_word(dev, PIIX_IDETIM0 + (i << 1), &w);
piix_enabled |= (w & 0x8000) ? (1 << i) : 0;
w &= 0x8c00;
if (~piix_config->flags & PIIX_NO_SITRE) w |= 0x4000;
w |= 0x44;
pci_write_config_word(dev, PIIX_IDETIM0 + (i << 1), w);
}
/*
* Determine the system bus clock.
*/
piix_clock = system_bus_speed * 1000;
switch (piix_clock) {
case 33000: piix_clock = 33333; break;
case 37000: piix_clock = 37500; break;
case 41000: piix_clock = 41666; break;
}
if (piix_clock < 20000 || piix_clock > 50000) {
printk(KERN_WARNING "PIIX: User given PCI clock speed impossible (%d), using 33 MHz instead.\n", piix_clock);
printk(KERN_WARNING "PIIX: Use ide0=ata66 if you want to assume 80-wire cable\n");
piix_clock = 33333;
}
/*
* Print the boot message.
*/
printk(KERN_INFO "PIIX: %s %s controller on pci%s\n",
dev->name, piix_dma[piix_config->flags & PIIX_UDMA], dev->slot_name);
/*
* Register /proc/ide/piix entry
*/
#ifdef CONFIG_PROC_FS
if (!piix_proc) {
piix_proc = 1;
piix_base = pci_resource_start(dev, 4);
bmide_dev = dev;
piix_display_info = &piix_get_info;
piix_proc = 1;
}
#endif /* DISPLAY_PIIX_TIMINGS && CONFIG_PROC_FS */
#endif
return 0;
}
/*
* Sheesh, someone at Intel needs to go read the ATA-4/5 T13 standards.
* It does not specify device detection, but channel!!!
* You determine later if bit 13 of word93 is set...
*/
unsigned int __init ata66_piix (ide_hwif_t *hwif)
unsigned int __init ata66_piix(ide_hwif_t *hwif)
{
byte reg54h = 0, reg55h = 0, ata66 = 0;
byte mask = hwif->channel ? 0xc0 : 0x30;
pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h);
pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h);
ata66 = (reg54h & mask) ? 1 : 0;
return ata66;
return ((piix_enabled & piix_80w) >> hwif->channel) & 1;
}
void __init ide_init_piix (ide_hwif_t *hwif)
void __init ide_init_piix(ide_hwif_t *hwif)
{
#ifndef CONFIG_IA64
if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14;
#endif /* CONFIG_IA64 */
int i;
if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) {
/* This is a painful system best to let it self tune for now */
return;
hwif->tuneproc = &piix_tune_drive;
hwif->speedproc = &piix_set_drive;
hwif->autodma = 0;
for (i = 0; i < 2; i++) {
hwif->drives[i].io_32bit = 1;
hwif->drives[i].unmask = 1;
hwif->drives[i].autotune = 1;
hwif->drives[i].dn = hwif->channel * 2 + i;
}
hwif->tuneproc = &piix_tune_drive;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_base) {
hwif->highmem = 1;
hwif->dmaproc = &piix_dmaproc;
#ifdef CONFIG_IDEDMA_AUTO
if (!noautodma)
hwif->autodma = 1;
#endif
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
}
if (!hwif->dma_base)
return;
/*
* We allow the BM-DMA driver only work on enabled interfaces,
* and only if DMA is safe with the chip and bridge.
*/
hwif->highmem = 1;
#ifndef CONFIG_BLK_DEV_IDEDMA
hwif->autodma = 0;
#else /* CONFIG_BLK_DEV_IDEDMA */
#ifdef CONFIG_PIIX_TUNING
if (!noautodma)
hwif->autodma = 1;
hwif->dmaproc = &piix_dmaproc;
hwif->speedproc = &piix_tune_chipset;
#endif /* CONFIG_PIIX_TUNING */
#endif /* !CONFIG_BLK_DEV_IDEDMA */
void __init ide_dmacapable_piix(ide_hwif_t *hwif, unsigned long dmabase)
{
if (((piix_enabled >> hwif->channel) & 1)
&& !(piix_config->flags & PIIX_NODMA))
ide_setup_dma(hwif, dmabase, 8);
}
/*
* linux/drivers/ide/slc90e66.c Version 0.10 October 4, 2000
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* 00:07.1 IDE interface: EFAR Microsystems:
* Unknown device 9130 (prog-if 8a [Master SecP PriP])
* Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV-
* VGASnoop- ParErr- Stepping- SERR- FastB2B-
* Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium
* >TAbort- <TAbort- <MAbort- >SERR- <PERR-
* Latency: 64
* Interrupt: pin A routed to IRQ 255
* Region 4: I/O ports at 1050
*
* 00: 55 10 30 91 05 00 00 02 00 8a 01 01 00 40 00 00
* 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 20: 51 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 30: 00 00 00 00 00 00 00 00 00 00 00 00 ff 01 00 00
* 40: 37 e3 33 e3 b9 55 01 00 0d 00 04 22 00 00 00 00
* 50: 00 00 ff a0 00 00 00 08 40 00 00 00 00 00 00 00
* 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
* This a look-a-like variation of the ICH0 PIIX4 Ultra-66,
* but this keeps the ISA-Bridge and slots alive.
*
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <asm/io.h>
#include "ata-timing.h"
#define SLC90E66_DEBUG_DRIVE_INFO 0
#define DISPLAY_SLC90E66_TIMINGS
#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static int slc90e66_get_info(char *, char **, off_t, int);
extern int (*slc90e66_display_info)(char *, char **, off_t, int); /* ide-proc.c */
static struct pci_dev *bmide_dev;
static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
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, reg47 = 0, reg48 = 0, reg4a = 0, reg4b = 0;
pci_read_config_word(bmide_dev, 0x40, &reg40);
pci_read_config_word(bmide_dev, 0x42, &reg42);
pci_read_config_byte(bmide_dev, 0x44, &reg44);
pci_read_config_byte(bmide_dev, 0x47, &reg47);
pci_read_config_byte(bmide_dev, 0x48, &reg48);
pci_read_config_byte(bmide_dev, 0x4a, &reg4a);
pci_read_config_byte(bmide_dev, 0x4b, &reg4b);
psitre = (reg40 & 0x4000) ? 1 : 0;
ssitre = (reg42 & 0x4000) ? 1 : 0;
/*
* at that point bibma+0x2 et bibma+0xa are byte registers
* to investigate:
*/
#ifdef __mips__ /* only for mips? */
c0 = inb_p(bibma + 0x02);
c1 = inb_p(bibma + 0x0a);
#else
c0 = inb_p((unsigned short)bibma + 0x02);
c1 = inb_p((unsigned short)bibma + 0x0a);
#endif
p += sprintf(p, " SLC90E66 Chipset.\n");
p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
p += sprintf(p, " %sabled %sabled\n",
(c0&0x80) ? "dis" : " en",
(c1&0x80) ? "dis" : " en");
p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
p += sprintf(p, "DMA enabled: %s %s %s %s\n",
(c0&0x20) ? "yes" : "no ",
(c0&0x40) ? "yes" : "no ",
(c1&0x20) ? "yes" : "no ",
(c1&0x40) ? "yes" : "no " );
p += sprintf(p, "UDMA enabled: %s %s %s %s\n",
(reg48&0x01) ? "yes" : "no ",
(reg48&0x02) ? "yes" : "no ",
(reg48&0x04) ? "yes" : "no ",
(reg48&0x08) ? "yes" : "no " );
p += sprintf(p, "UDMA enabled: %s %s %s %s\n",
((reg4a&0x04)==0x04) ? "4" :
((reg4a&0x03)==0x03) ? "3" :
(reg4a&0x02) ? "2" :
(reg4a&0x01) ? "1" :
(reg4a&0x00) ? "0" : "X",
((reg4a&0x40)==0x40) ? "4" :
((reg4a&0x30)==0x30) ? "3" :
(reg4a&0x20) ? "2" :
(reg4a&0x10) ? "1" :
(reg4a&0x00) ? "0" : "X",
((reg4b&0x04)==0x04) ? "4" :
((reg4b&0x03)==0x03) ? "3" :
(reg4b&0x02) ? "2" :
(reg4b&0x01) ? "1" :
(reg4b&0x00) ? "0" : "X",
((reg4b&0x40)==0x40) ? "4" :
((reg4b&0x30)==0x30) ? "3" :
(reg4b&0x20) ? "2" :
(reg4b&0x10) ? "1" :
(reg4b&0x00) ? "0" : "X");
p += sprintf(p, "UDMA\n");
p += sprintf(p, "DMA\n");
p += sprintf(p, "PIO\n");
/*
* FIXME.... Add configuration junk data....blah blah......
*/
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */
/*
* Used to set Fifo configuration via kernel command line:
*/
byte slc90e66_proc = 0;
extern char *ide_xfer_verbose (byte xfer_rate);
#ifdef CONFIG_BLK_DEV_IDEDMA
/*
*
*/
static byte slc90e66_dma_2_pio (byte xfer_rate) {
switch(xfer_rate) {
case XFER_UDMA_4:
case XFER_UDMA_3:
case XFER_UDMA_2:
case XFER_UDMA_1:
case XFER_UDMA_0:
case XFER_MW_DMA_2:
case XFER_PIO_4:
return 4;
case XFER_MW_DMA_1:
case XFER_PIO_3:
return 3;
case XFER_SW_DMA_2:
case XFER_PIO_2:
return 2;
case XFER_MW_DMA_0:
case XFER_SW_DMA_1:
case XFER_SW_DMA_0:
case XFER_PIO_1:
case XFER_PIO_0:
case XFER_PIO_SLOW:
default:
return 0;
}
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
/*
* Based on settings done by AMI BIOS
* (might be useful if drive is not registered in CMOS for any reason).
*/
static void slc90e66_tune_drive (ide_drive_t *drive, byte pio)
{
unsigned long flags;
u16 master_data;
byte slave_data;
int is_slave = (&HWIF(drive)->drives[1] == drive);
int master_port = HWIF(drive)->index ? 0x42 : 0x40;
int slave_port = 0x44;
/* ISP RTC */
byte timings[][2] = { { 0, 0 },
{ 0, 0 },
{ 1, 0 },
{ 2, 1 },
{ 2, 3 }, };
if (pio == 255)
pio = ata_timing_mode(drive, XFER_PIO | XFER_EPIO) - XFER_PIO_0;
else
pio = min_t(byte, pio, 4);
pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
if (is_slave) {
master_data = master_data | 0x4000;
if (pio > 1)
/* enable PPE, IE and TIME */
master_data = master_data | 0x0070;
pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
slave_data = slave_data | ((timings[pio][0] << 2) | (timings[pio][1]
<< (HWIF(drive)->index ? 4 : 0)));
} else {
master_data = master_data & 0xccf8;
if (pio > 1)
/* enable PPE, IE and TIME */
master_data = master_data | 0x0007;
master_data = master_data | (timings[pio][0] << 12) |
(timings[pio][1] << 8);
}
save_flags(flags);
cli();
pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
if (is_slave)
pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
restore_flags(flags);
}
#ifdef CONFIG_BLK_DEV_IDEDMA
static int slc90e66_tune_chipset (ide_drive_t *drive, byte speed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
byte maslave = hwif->channel ? 0x42 : 0x40;
int a_speed = 7 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int u_speed = 0;
int err = 0;
int sitre;
short reg4042, reg44, reg48, reg4a;
pci_read_config_word(dev, maslave, &reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
pci_read_config_word(dev, 0x44, &reg44);
pci_read_config_word(dev, 0x48, &reg48);
pci_read_config_word(dev, 0x4a, &reg4a);
switch(speed) {
case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break;
case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break;
case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_SW_DMA_2: break;
#if 0 /* allow PIO modes */
default: return -1;
#endif
}
if (speed >= XFER_UDMA_0) {
if (!(reg48 & u_flag))
pci_write_config_word(dev, 0x48, reg48|u_flag);
if ((reg4a & u_speed) != u_speed) {
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
pci_read_config_word(dev, 0x4a, &reg4a);
pci_write_config_word(dev, 0x4a, reg4a|u_speed);
}
}
if (speed < XFER_UDMA_0) {
if (reg48 & u_flag)
pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
if (reg4a & a_speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
}
slc90e66_tune_drive(drive, slc90e66_dma_2_pio(speed));
#if SLC90E66_DEBUG_DRIVE_INFO
printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
#endif /* SLC90E66_DEBUG_DRIVE_INFO */
if (!drive->init_speed)
drive->init_speed = speed;
err = ide_config_drive_speed(drive, speed);
drive->current_speed = speed;
return err;
}
static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
int ultra = 1;
byte speed = 0;
byte udma_66 = eighty_ninty_three(drive);
#if 1 /* allow PIO modes */
if (!HWIF(drive)->autodma) {
speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO);
(void) slc90e66_tune_chipset(drive, speed);
return ((int) ide_dma_off_quietly);
}
#endif
speed = ata_timing_mode(drive, XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA
| (ultra ? XFER_UDMA : 0) | ((ultra && udma_66) ? XFER_UDMA_66 : 0));
(void) slc90e66_tune_chipset(drive, speed);
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 :
ide_dma_off_quietly);
}
static int slc90e66_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
switch (func) {
case ide_dma_check:
return ide_dmaproc((ide_dma_action_t) slc90e66_config_drive_for_dma(drive), drive);
default :
break;
}
/* Other cases are done by generic IDE-DMA code. */
return ide_dmaproc(func, drive);
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
unsigned int __init pci_init_slc90e66(struct pci_dev *dev)
{
#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
if (!slc90e66_proc) {
slc90e66_proc = 1;
bmide_dev = dev;
slc90e66_display_info = &slc90e66_get_info;
}
#endif /* DISPLAY_SLC90E66_TIMINGS && CONFIG_PROC_FS */
return 0;
}
unsigned int __init ata66_slc90e66 (ide_hwif_t *hwif)
{
#if 1
byte reg47 = 0, ata66 = 0;
byte mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */
pci_read_config_byte(hwif->pci_dev, 0x47, &reg47);
ata66 = (reg47 & mask) ? 0 : 1; /* bit[0(1)]: 0:80, 1:40 */
#else
byte ata66 = 0;
#endif
return ata66;
}
void __init ide_init_slc90e66 (ide_hwif_t *hwif)
{
if (!hwif->irq)
hwif->irq = hwif->channel ? 15 : 14;
hwif->tuneproc = &slc90e66_tune_drive;
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
if (!hwif->dma_base)
return;
hwif->autodma = 0;
hwif->highmem = 1;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (!noautodma)
hwif->autodma = 1;
hwif->dmaproc = &slc90e66_dmaproc;
hwif->speedproc = &slc90e66_tune_chipset;
#endif /* !CONFIG_BLK_DEV_IDEDMA */
}
......@@ -526,8 +526,10 @@
2040 79c974
7006 AMD-751 [Irongate] System Controller
7007 AMD-751 [Irongate] AGP Bridge
700e AMD-760 [Irongate] System Controller
700f AMD-760 [Irongate] AGP Bridge
700c AMD-760 MP [IGD4-2P] System Controller
700d AMD-760 MP [IGD4-2P] AGP Bridge
700e AMD-760 [IGD4-1P] System Controller
700f AMD-760 [IGD4-1P] AGP Bridge
7400 AMD-755 [Cobra] ISA
7401 AMD-755 [Cobra] IDE
7403 AMD-755 [Cobra] ACPI
......@@ -540,11 +542,21 @@
7411 AMD-765 [Viper] IDE
7413 AMD-765 [Viper] ACPI
7414 AMD-765 [Viper] USB
7440 AMD-768 [??] ISA
7441 AMD-768 [??] IDE
7443 AMD-768 [??] ACPI
7448 AMD-768 [??] PCI
7449 AMD-768 [??] USB
7440 AMD-768 [Opus] ISA
7441 AMD-768 [Opus] IDE
7443 AMD-768 [Opus] ACPI
7448 AMD-768 [Opus] PCI
7449 AMD-768 [Opus] USB
7454 AMD-8151 System Controller
7455 AMD-8151 AGP Bridge
7460 AMD-8111 PCI
7461 AMD-8111 USB
7462 AMD-8111 Ethernet
7468 AMD-8111 LPC
7469 AMD-8111 IDE
746a AMD-8111 SMBus 2.0
746b AMD-8111 ACPI
746d AMD-8111 AC97 Audio
1023 Trident Microsystems
0194 82C194
2000 4DWave DX
......@@ -1055,11 +1067,11 @@
1052 ?Young Micro Systems
1053 Young Micro Systems
1054 Hitachi, Ltd
1055 EFAR Microsystems
9130 EIDE Controller
9460 PCI to ISA Bridge
9462 USB Universal Host Controller [OHCI]
9463 Power Management Controller [Bridge]
1055 Efar Microsystems
9130 slc90e66 [Victory66] IDE
9460 slc90e66 [Victory66] ISA
9462 slc90e66 [Victory66] USB
9463 slc90e66 [Victory66] ACPI
1056 ICL
# Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this.
1057 Motorola
......@@ -1925,6 +1937,7 @@
0151 NV15 DDR (GeForce2 GTS)
0152 NV15 Bladerunner (GeForce2 Ultra)
0153 NV15 GL (Quadro2 Pro)
01bc nForce IDE
0200 NV20 (GeForce3)
0203 Quadro DCC
10df Emulex Corporation
......@@ -5066,6 +5079,8 @@
244c 82820 820 (Camino 2) Chipset ISA Bridge (ICH2-M)
244e 82820 820 (Camino 2) Chipset PCI
2485 AC'97 Audio Controller
248a 82801CAM ICH3-M IDE
248b 82801CA ICH3 IDE
2500 82820 820 (Camino) Chipset Host Bridge (MCH)
1043 801c P3C-2000 system chipset
2501 82820 820 (Camino) Chipset Host Bridge (MCH)
......@@ -5118,10 +5133,10 @@
71a0 440GX - 82443GX Host bridge
71a1 440GX - 82443GX AGP bridge
71a2 440GX - 82443GX Host bridge (AGP disabled)
7600 82372FB PCI to ISA Bridge
7601 82372FB PIIX4 IDE
7602 82372FB [PCI-to-USB UHCI]
7603 82372FB System Management Bus Controller
7600 82372FB PIIX5 ISA
7601 82372FB PIIX5 IDE
7602 82372FB PIIX5 USB
7603 82372FB PIIX5 SMBus
7800 i740
1092 0100 Stealth II G460
8086 0100 Intel740 Graphics Accelerator
......
......@@ -815,7 +815,6 @@ typedef struct ide_task_s {
int command_type;
ide_pre_handler_t *prehandler;
ide_handler_t *handler;
ide_post_handler_t *posthandler;
void *special; /* valid_t generally */
struct request *rq; /* copy of request */
unsigned long block; /* copy of block */
......@@ -842,17 +841,17 @@ void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct
* Special Flagged Register Validation Caller
*/
ide_startstop_t set_multmode_intr (ide_drive_t *drive);
ide_startstop_t task_no_data_intr (ide_drive_t *drive);
extern ide_startstop_t recal_intr(ide_drive_t *drive);
extern ide_startstop_t set_geometry_intr(ide_drive_t *drive);
extern ide_startstop_t set_multmode_intr(ide_drive_t *drive);
extern ide_startstop_t task_no_data_intr(ide_drive_t *drive);
int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf);
int ide_raw_taskfile (ide_drive_t *drive, ide_task_t *cmd, byte *buf);
ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
/* Expects args is a full set of TF registers and parses the command type */
int ide_cmd_type_parser (ide_task_t *args);
extern void ide_cmd_type_parser(ide_task_t *args);
int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
......
......@@ -865,6 +865,7 @@
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151
#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152
#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153
#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc
#define PCI_VENDOR_ID_IMS 0x10e0
#define PCI_DEVICE_ID_IMS_8849 0x8849
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment