aboutsummaryrefslogtreecommitdiff
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/Kconfig110
-rw-r--r--drivers/ide/Makefile5
-rw-r--r--drivers/ide/aec62xx.c21
-rw-r--r--drivers/ide/ali14xx.c9
-rw-r--r--drivers/ide/alim15x3.c203
-rw-r--r--drivers/ide/amd74xx.c22
-rw-r--r--drivers/ide/at91_ide.c369
-rw-r--r--drivers/ide/atiixp.c19
-rw-r--r--drivers/ide/au1xxx-ide.c95
-rw-r--r--drivers/ide/buddha.c50
-rw-r--r--drivers/ide/cmd640.c28
-rw-r--r--drivers/ide/cmd64x.c235
-rw-r--r--drivers/ide/cs5520.c18
-rw-r--r--drivers/ide/cs5530.c19
-rw-r--r--drivers/ide/cs5535.c20
-rw-r--r--drivers/ide/cs5536.c52
-rw-r--r--drivers/ide/cy82c693.c190
-rw-r--r--drivers/ide/delkin_cb.c24
-rw-r--r--drivers/ide/dtc2278.c8
-rw-r--r--drivers/ide/falconide.c10
-rw-r--r--drivers/ide/gayle.c166
-rw-r--r--drivers/ide/hpt366.c158
-rw-r--r--drivers/ide/ht6560b.c41
-rw-r--r--drivers/ide/icside.c52
-rw-r--r--drivers/ide/ide-4drives.c8
-rw-r--r--drivers/ide/ide-acpi.c84
-rw-r--r--drivers/ide/ide-atapi.c325
-rw-r--r--drivers/ide/ide-cd.c429
-rw-r--r--drivers/ide/ide-cd.h7
-rw-r--r--drivers/ide/ide-cd_ioctl.c17
-rw-r--r--drivers/ide/ide-cd_verbose.c2
-rw-r--r--drivers/ide/ide-cs.c242
-rw-r--r--drivers/ide/ide-devsets.c9
-rw-r--r--drivers/ide/ide-disk.c140
-rw-r--r--drivers/ide/ide-disk_ioctl.c10
-rw-r--r--drivers/ide/ide-disk_proc.c131
-rw-r--r--drivers/ide/ide-dma-sff.c1
-rw-r--r--drivers/ide/ide-dma.c48
-rw-r--r--drivers/ide/ide-eh.c22
-rw-r--r--drivers/ide/ide-floppy.c111
-rw-r--r--drivers/ide/ide-floppy_ioctl.c59
-rw-r--r--drivers/ide/ide-floppy_proc.c31
-rw-r--r--drivers/ide/ide-gd.c60
-rw-r--r--drivers/ide/ide-generic.c7
-rw-r--r--drivers/ide/ide-h8300.c109
-rw-r--r--drivers/ide/ide-io-std.c1
-rw-r--r--drivers/ide/ide-io.c208
-rw-r--r--drivers/ide/ide-ioctls.c31
-rw-r--r--drivers/ide/ide-iops.c70
-rw-r--r--drivers/ide/ide-legacy.c8
-rw-r--r--drivers/ide/ide-lib.c30
-rw-r--r--drivers/ide/ide-park.c16
-rw-r--r--drivers/ide/ide-pci-generic.c20
-rw-r--r--drivers/ide/ide-pio-blacklist.c1
-rw-r--r--drivers/ide/ide-pm.c83
-rw-r--r--drivers/ide/ide-pnp.c7
-rw-r--r--drivers/ide/ide-probe.c189
-rw-r--r--drivers/ide/ide-proc.c349
-rw-r--r--drivers/ide/ide-scan-pci.c2
-rw-r--r--drivers/ide/ide-sysfs.c35
-rw-r--r--drivers/ide/ide-tape.c1201
-rw-r--r--drivers/ide/ide-taskfile.c167
-rw-r--r--drivers/ide/ide-timings.c18
-rw-r--r--drivers/ide/ide-xfer-mode.c31
-rw-r--r--drivers/ide/ide.c31
-rw-r--r--drivers/ide/ide_platform.c38
-rw-r--r--drivers/ide/it8172.c21
-rw-r--r--drivers/ide/it8213.c26
-rw-r--r--drivers/ide/it821x.c25
-rw-r--r--drivers/ide/jmicron.c10
-rw-r--r--drivers/ide/macide.c38
-rw-r--r--drivers/ide/ns87415.c8
-rw-r--r--drivers/ide/opti621.c87
-rw-r--r--drivers/ide/palm_bk3710.c29
-rw-r--r--drivers/ide/pdc202xx_new.c44
-rw-r--r--drivers/ide/pdc202xx_old.c173
-rw-r--r--drivers/ide/piix.c53
-rw-r--r--drivers/ide/pmac.c199
-rw-r--r--drivers/ide/q40ide.c17
-rw-r--r--drivers/ide/qd65xx.c26
-rw-r--r--drivers/ide/qd65xx.h11
-rw-r--r--drivers/ide/rapide.c16
-rw-r--r--drivers/ide/rz1000.c6
-rw-r--r--drivers/ide/sc1200.c13
-rw-r--r--drivers/ide/scc_pata.c50
-rw-r--r--drivers/ide/serverworks.c54
-rw-r--r--drivers/ide/setup-pci.c86
-rw-r--r--drivers/ide/sgiioc4.c129
-rw-r--r--drivers/ide/siimage.c73
-rw-r--r--drivers/ide/sis5513.c41
-rw-r--r--drivers/ide/sl82c105.c77
-rw-r--r--drivers/ide/slc90e66.c27
-rw-r--r--drivers/ide/tc86c001.c24
-rw-r--r--drivers/ide/triflex.c33
-rw-r--r--drivers/ide/trm290.c6
-rw-r--r--drivers/ide/tx4938ide.c33
-rw-r--r--drivers/ide/tx4939ide.c36
-rw-r--r--drivers/ide/umc8672.c13
-rw-r--r--drivers/ide/via82cxxx.c84
99 files changed, 3344 insertions, 4536 deletions
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index cf06494bb74..a04c49f2a01 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -7,50 +7,25 @@ config HAVE_IDE
bool
menuconfig IDE
- tristate "ATA/ATAPI/MFM/RLL support"
+ tristate "ATA/ATAPI/MFM/RLL support (DEPRECATED)"
depends on HAVE_IDE
depends on BLOCK
---help---
- If you say Y here, your kernel will be able to manage low cost mass
- storage units such as ATA/(E)IDE and ATAPI units. The most common
- cases are IDE hard drives and ATAPI CD-ROM drives.
-
- If your system is pure SCSI and doesn't use these interfaces, you
- can say N here.
-
- Integrated Disk Electronics (IDE aka ATA-1) is a connecting standard
- for mass storage units such as hard disks. It was designed by
- Western Digital and Compaq Computer in 1984. It was then named
- ST506. Quite a number of disks use the IDE interface.
-
- AT Attachment (ATA) is the superset of the IDE specifications.
- ST506 was also called ATA-1.
-
- Fast-IDE is ATA-2 (also named Fast ATA), Enhanced IDE (EIDE) is
- ATA-3. It provides support for larger disks (up to 8.4GB by means of
- the LBA standard), more disks (4 instead of 2) and for other mass
- storage units such as tapes and cdrom. UDMA/33 (aka UltraDMA/33) is
- ATA-4 and provides faster (and more CPU friendly) transfer modes
- than previous PIO (Programmed processor Input/Output) from previous
- ATA/IDE standards by means of fast DMA controllers.
-
- ATA Packet Interface (ATAPI) is a protocol used by EIDE tape and
- CD-ROM drives, similar in many respects to the SCSI protocol.
-
- SMART IDE (Self Monitoring, Analysis and Reporting Technology) was
- designed in order to prevent data corruption and disk crash by
- detecting pre hardware failure conditions (heat, access time, and
- the like...). Disks built since June 1995 may follow this standard.
- The kernel itself doesn't manage this; however there are quite a
- number of user programs such as smart that can query the status of
- SMART parameters from disk drives.
+ If you say Y here, your kernel will be able to manage ATA/(E)IDE and
+ ATAPI units. The most common cases are IDE hard drives and ATAPI
+ CD-ROM drives.
+
+ This subsystem is currently in maintenance mode with only bug fix
+ changes applied. Users of ATA hardware are encouraged to migrate to
+ the newer ATA subsystem ("Serial ATA (prod) and Parallel ATA
+ (experimental) drivers") which is more actively maintained.
To compile this driver as a module, choose M here: the
- module will be called ide-core.ko.
+ module will be called ide-core.
For further information, please read <file:Documentation/ide/ide.txt>.
- If unsure, say Y.
+ If unsure, say N.
if IDE
@@ -159,7 +134,7 @@ config BLK_DEV_IDECD
module will be called ide-cd.
config BLK_DEV_IDECD_VERBOSE_ERRORS
- bool "Verbose error logging for IDE/ATAPI CDROM driver" if EMBEDDED
+ bool "Verbose error logging for IDE/ATAPI CDROM driver" if EXPERT
depends on BLK_DEV_IDECD
default y
help
@@ -222,8 +197,8 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
- depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
- default ARM && (ARCH_RPC || ARCH_SHARK)
+ depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC
+ default ARM && ARCH_RPC
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
@@ -347,12 +322,11 @@ config BLK_DEV_GENERIC
which otherwise might not be supported.
config BLK_DEV_OPTI621
- tristate "OPTi 82C621 chipset enhanced support (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ tristate "OPTi 82C621 chipset enhanced support"
select BLK_DEV_IDEPCI
help
This is a driver for the OPTi 82C621 EIDE controller.
- Please read the comments at the top of <file:drivers/ide/pci/opti621.c>.
+ Please read the comments at the top of <file:drivers/ide/opti621.c>.
config BLK_DEV_RZ1000
tristate "RZ1000 chipset bugfix/support"
@@ -390,7 +364,7 @@ config BLK_DEV_ALI15X3
normal dual channel support.
Please read the comments at the top of
- <file:drivers/ide/pci/alim15x3.c>.
+ <file:drivers/ide/alim15x3.c>.
If unsure, say N.
@@ -442,7 +416,7 @@ config BLK_DEV_CY82C693
config BLK_DEV_CS5520
tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on X86_32 || COMPILE_TEST
select BLK_DEV_IDEDMA_PCI
help
Include support for PIO tuning and virtual DMA on the Cyrix MediaGX
@@ -453,6 +427,7 @@ config BLK_DEV_CS5520
config BLK_DEV_CS5530
tristate "Cyrix/National Semiconductor CS5530 MediaGX chipset support"
+ depends on X86_32 || COMPILE_TEST
select BLK_DEV_IDEDMA_PCI
help
Include support for UDMA on the Cyrix MediaGX 5530 chipset. This
@@ -462,7 +437,7 @@ config BLK_DEV_CS5530
config BLK_DEV_CS5535
tristate "AMD CS5535 chipset support"
- depends on X86 && !X86_64
+ depends on X86_32
select BLK_DEV_IDEDMA_PCI
help
Include support for UDMA on the NSC/AMD CS5535 companion chipset.
@@ -513,6 +488,7 @@ config BLK_DEV_JMICRON
config BLK_DEV_SC1200
tristate "National SCx200 chipset support"
+ depends on X86_32 || COMPILE_TEST
select BLK_DEV_IDEDMA_PCI
help
This driver adds support for the on-board IDE controller on the
@@ -553,7 +529,7 @@ config BLK_DEV_NS87415
This driver adds detection and support for the NS87415 chip
(used mainly on SPARC64 and PA-RISC machines).
- Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
+ Please read the comments at the top of <file:drivers/ide/ns87415.c>.
config BLK_DEV_PDC202XX_OLD
tristate "PROMISE PDC202{46|62|65|67} support"
@@ -572,7 +548,7 @@ config BLK_DEV_PDC202XX_OLD
for more than one card.
Please read the comments at the top of
- <file:drivers/ide/pci/pdc202xx_old.c>.
+ <file:drivers/ide/pdc202xx_old.c>.
If unsure, say N.
@@ -618,7 +594,7 @@ config BLK_DEV_SIS5513
ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740,
SiS745, SiS750
- Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>.
+ Please read the comments at the top of <file:drivers/ide/sis5513.c>.
config BLK_DEV_SL82C105
tristate "Winbond SL82c105 support"
@@ -641,7 +617,7 @@ config BLK_DEV_SLC90E66
look-a-like to the PIIX4 it should be a nice addition.
Please read the comments at the top of
- <file:drivers/ide/pci/slc90e66.c>.
+ <file:drivers/ide/slc90e66.c>.
config BLK_DEV_TRM290
tristate "Tekram TRM290 chipset support"
@@ -650,7 +626,7 @@ config BLK_DEV_TRM290
This driver adds support for bus master DMA transfers
using the Tekram TRM290 PCI IDE chip. Volunteers are
needed for further tweaking and development.
- Please read the comments at the top of <file:drivers/ide/pci/trm290.c>.
+ Please read the comments at the top of <file:drivers/ide/trm290.c>.
config BLK_DEV_VIA82CXXX
tristate "VIA82CXXX chipset support"
@@ -702,19 +678,19 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200"
- depends on SOC_AU1200
+ depends on MIPS_ALCHEMY
select IDE_XFER_MODE
choice
prompt "IDE Mode for AMD Alchemy Au1200"
- default CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA
- depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+ default BLK_DEV_IDE_AU1XXX_PIO_DBDMA
+ depends on BLK_DEV_IDE_AU1XXX
config BLK_DEV_IDE_AU1XXX_PIO_DBDMA
bool "PIO+DbDMA IDE for AMD Alchemy Au1200"
config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200"
- depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX
+ depends on BLK_DEV_IDE_AU1XXX
endchoice
config BLK_DEV_IDE_TX4938
@@ -727,11 +703,6 @@ config BLK_DEV_IDE_TX4939
depends on SOC_TX4939
select BLK_DEV_IDEDMA_SFF
-config BLK_DEV_IDE_AT91
- tristate "Atmel AT91 (SAM9, CAP9, AT572D940HF) IDE support"
- depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
- select IDE_TIMINGS
-
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
@@ -754,13 +725,6 @@ config BLK_DEV_IDE_RAPIDE
Say Y here if you want to support the Yellowstone RapIDE controller
manufactured for use with Acorn computers.
-config IDE_H8300
- tristate "H8300 IDE support"
- depends on H8300
- default y
- help
- Enables the H8300 IDE driver.
-
config BLK_DEV_GAYLE
tristate "Amiga Gayle IDE interface support"
depends on AMIGA
@@ -786,8 +750,8 @@ config BLK_DEV_GAYLE
use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_BUDDHA
- tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
- depends on ZORRO && EXPERIMENTAL
+ tristate "Buddha/Catweasel/X-Surf IDE interface support"
+ depends on ZORRO
help
This is the IDE driver for the IDE interfaces on the Buddha, Catweasel
and X-Surf expansion boards. It supports up to two interfaces on the
@@ -861,7 +825,7 @@ config BLK_DEV_ALI14XX
of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster
I/O speeds to be set as well.
See the files <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/ali14xx.c> for more info.
+ <file:drivers/ide/ali14xx.c> for more info.
config BLK_DEV_DTC2278
tristate "DTC-2278 support"
@@ -872,7 +836,7 @@ config BLK_DEV_DTC2278
boot parameter. It enables support for the secondary IDE interface
of the DTC-2278 card, and permits faster I/O speeds to be set as
well. See the <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/dtc2278.c> files for more info.
+ <file:drivers/ide/dtc2278.c> files for more info.
config BLK_DEV_HT6560B
tristate "Holtek HT6560B support"
@@ -883,7 +847,7 @@ config BLK_DEV_HT6560B
boot parameter. It enables support for the secondary IDE interface
of the Holtek card, and permits faster I/O speeds to be set as well.
See the <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/ht6560b.c> files for more info.
+ <file:drivers/ide/ht6560b.c> files for more info.
config BLK_DEV_QD65XX
tristate "QDI QD65xx support"
@@ -892,7 +856,7 @@ config BLK_DEV_QD65XX
help
This driver is enabled at runtime using the "qd65xx.probe" kernel
boot parameter. It permits faster I/O speeds to be set. See the
- <file:Documentation/ide/ide.txt> and <file:drivers/ide/legacy/qd65xx.c>
+ <file:Documentation/ide/ide.txt> and <file:drivers/ide/qd65xx.c>
for more info.
config BLK_DEV_UMC8672
@@ -904,7 +868,7 @@ config BLK_DEV_UMC8672
boot parameter. It enables support for the secondary IDE interface
of the UMC-8672, and permits faster I/O speeds to be set as well.
See the files <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/umc8672.c> for more info.
+ <file:drivers/ide/umc8672.c> for more info.
endif
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 81df925f0e8..a04ee82f1c8 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -2,7 +2,7 @@
# link order is important here
#
-EXTRA_CFLAGS += -Idrivers/ide
+ccflags-y := -Idrivers/ide
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
@@ -78,8 +78,6 @@ obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o
obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o
-obj-$(CONFIG_IDE_H8300) += ide-h8300.o
-
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
@@ -116,4 +114,3 @@ obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o
obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o
obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o
-obj-$(CONFIG_BLK_DEV_IDE_AT91) += at91_ide.o
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 878f8ec6dbe..c7eaf20af92 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -81,15 +81,15 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
return chipset_table->ultra_settings;
}
-static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
+static void aec6210_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
u16 d_conf = 0;
u8 ultra = 0, ultra_conf = 0;
u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
+ const u8 speed = drive->dma_mode;
unsigned long flags;
local_irq_save(flags);
@@ -109,15 +109,15 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
local_irq_restore(flags);
}
-static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
+static void aec6260_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
u8 unit = drive->dn & 1;
u8 tmp1 = 0, tmp2 = 0;
u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
+ const u8 speed = drive->dma_mode;
unsigned long flags;
local_irq_save(flags);
@@ -134,9 +134,10 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
local_irq_restore(flags);
}
-static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void aec_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0);
+ drive->dma_mode = drive->pio_mode;
+ hwif->port_ops->set_dma_mode(hwif, drive);
}
static int init_chipset_aec62xx(struct pci_dev *dev)
@@ -180,7 +181,7 @@ static const struct ide_port_ops atp86x_port_ops = {
.cable_detect = atp86x_cable_detect,
};
-static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
+static const struct ide_port_info aec62xx_chipsets[] = {
{ /* 0: AEC6210 */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
@@ -250,7 +251,7 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
* chips, pass a local copy of 'struct ide_port_info' down the call chain.
*/
-static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct chipset_bus_clock_list_entry *bus_clock;
struct ide_port_info d;
@@ -286,7 +287,7 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi
return err;
}
-static void __devexit aec62xx_remove(struct pci_dev *dev)
+static void aec62xx_remove(struct pci_dev *dev)
{
ide_pci_remove(dev);
pci_disable_device(dev);
@@ -306,7 +307,7 @@ static struct pci_driver aec62xx_pci_driver = {
.name = "AEC62xx_IDE",
.id_table = aec62xx_pci_tbl,
.probe = aec62xx_init_one,
- .remove = __devexit_p(aec62xx_remove),
+ .remove = aec62xx_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c
index 90da1f953ed..8f3570ee64c 100644
--- a/drivers/ide/ali14xx.c
+++ b/drivers/ide/ali14xx.c
@@ -52,13 +52,13 @@
/* port addresses for auto-detection */
#define ALI_NUM_PORTS 4
-static const int ports[ALI_NUM_PORTS] __initdata =
+static const int ports[ALI_NUM_PORTS] __initconst =
{ 0x074, 0x0f4, 0x034, 0x0e4 };
/* register initialization data */
typedef struct { u8 reg, data; } RegInitializer;
-static const RegInitializer initData[] __initdata = {
+static const RegInitializer initData[] __initconst = {
{0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
{0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
@@ -109,13 +109,14 @@ static DEFINE_SPINLOCK(ali14xx_lock);
* This function computes timing parameters
* and sets controller registers accordingly.
*/
-static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int driveNum;
int time1, time2;
u8 param1, param2, param3, param4;
unsigned long flags;
int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
/* calculate timing, according to PIO mode */
@@ -220,7 +221,7 @@ static int __init ali14xx_probe(void)
return ide_legacy_device_add(&ali14xx_port_info, 0);
}
-static int probe_ali14xx;
+static bool probe_ali14xx;
module_param_named(probe, probe_ali14xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 537da1cde16..36f76e28a0b 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -8,7 +8,7 @@
* Copyright (C) 2002 Alan Cox
* ALi (now ULi M5228) support by Clear Zhang <Clear.Zhang@ali.com.tw>
* Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* (U)DMA capable version of ali 1533/1543(C), 1535(D)
*
@@ -40,16 +40,6 @@
#define DRV_NAME "alim15x3"
/*
- * Allow UDMA on M1543C-E chipset for WDC disks that ignore CRC checking
- * (this is DANGEROUS and could result in data corruption).
- */
-static int wdc_udma;
-
-module_param(wdc_udma, bool, 0);
-MODULE_PARM_DESC(wdc_udma,
- "allow UDMA on M1543C-E chipset for WDC disks (DANGEROUS)");
-
-/*
* ALi devices are not plug in. Otherwise these static values would
* need to go. They ought to go away anyway
*/
@@ -58,61 +48,84 @@ static u8 m5229_revision;
static u8 chip_is_1543c_e;
static struct pci_dev *isa_dev;
+static void ali_fifo_control(ide_hwif_t *hwif, ide_drive_t *drive, int on)
+{
+ struct pci_dev *pdev = to_pci_dev(hwif->dev);
+ int pio_fifo = 0x54 + hwif->channel;
+ u8 fifo;
+ int shift = 4 * (drive->dn & 1);
+
+ pci_read_config_byte(pdev, pio_fifo, &fifo);
+ fifo &= ~(0x0F << shift);
+ fifo |= (on << shift);
+ pci_write_config_byte(pdev, pio_fifo, fifo);
+}
+
+static void ali_program_timings(ide_hwif_t *hwif, ide_drive_t *drive,
+ struct ide_timing *t, u8 ultra)
+{
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ int port = hwif->channel ? 0x5c : 0x58;
+ int udmat = 0x56 + hwif->channel;
+ u8 unit = drive->dn & 1, udma;
+ int shift = 4 * unit;
+
+ /* Set up the UDMA */
+ pci_read_config_byte(dev, udmat, &udma);
+ udma &= ~(0x0F << shift);
+ udma |= ultra << shift;
+ pci_write_config_byte(dev, udmat, udma);
+
+ if (t == NULL)
+ return;
+
+ t->setup = clamp_val(t->setup, 1, 8) & 7;
+ t->act8b = clamp_val(t->act8b, 1, 8) & 7;
+ t->rec8b = clamp_val(t->rec8b, 1, 16) & 15;
+ t->active = clamp_val(t->active, 1, 8) & 7;
+ t->recover = clamp_val(t->recover, 1, 16) & 15;
+
+ pci_write_config_byte(dev, port, t->setup);
+ pci_write_config_byte(dev, port + 1, (t->act8b << 4) | t->rec8b);
+ pci_write_config_byte(dev, port + unit + 2,
+ (t->active << 4) | t->recover);
+}
+
/**
* ali_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Program the controller for the given PIO mode.
*/
-static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void ali_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
- int s_time = t->setup, a_time = t->active, c_time = t->cycle;
- u8 s_clc, a_clc, r_clc;
- unsigned long flags;
+ ide_drive_t *pair = ide_get_pair_dev(drive);
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
- int port = hwif->channel ? 0x5c : 0x58;
- int portFIFO = hwif->channel ? 0x55 : 0x54;
- u8 cd_dma_fifo = 0, unit = drive->dn & 1;
-
- if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8)
- s_clc = 0;
- if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8)
- a_clc = 0;
-
- if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) {
- r_clc = 1;
- } else {
- if (r_clc >= 16)
- r_clc = 0;
+ unsigned long T = 1000000 / bus_speed; /* PCI clock based */
+ struct ide_timing t;
+
+ ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
+ if (pair) {
+ struct ide_timing p;
+
+ ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
+ ide_timing_merge(&p, &t, &t,
+ IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+ if (pair->dma_mode) {
+ ide_timing_compute(pair, pair->dma_mode, &p, T, 1);
+ ide_timing_merge(&p, &t, &t,
+ IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+ }
}
- local_irq_save(flags);
-
+
/*
* PIO mode => ATA FIFO on, ATAPI FIFO off
*/
- pci_read_config_byte(dev, portFIFO, &cd_dma_fifo);
- if (drive->media==ide_disk) {
- if (unit) {
- pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50);
- } else {
- pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05);
- }
- } else {
- if (unit) {
- pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F);
- } else {
- pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0);
- }
- }
-
- pci_write_config_byte(dev, port, s_clc);
- pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc);
- local_irq_restore(flags);
+ ali_fifo_control(hwif, drive, (drive->media == ide_disk) ? 0x05 : 0x00);
+
+ ali_program_timings(hwif, drive, &t, 0);
}
/**
@@ -132,7 +145,7 @@ static u8 ali_udma_filter(ide_drive_t *drive)
if (m5229_revision > 0x20 && m5229_revision < 0xC2) {
if (drive->media != ide_disk)
return 0;
- if (wdc_udma == 0 && chip_is_1543c_e &&
+ if (chip_is_1543c_e &&
strstr((char *)&drive->id[ATA_ID_PROD], "WDC "))
return 0;
}
@@ -142,44 +155,42 @@ static u8 ali_udma_filter(ide_drive_t *drive)
/**
* ali_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Configure the hardware for the desired IDE transfer mode.
*/
-static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void ali_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
+ static u8 udma_timing[7] = { 0xC, 0xB, 0xA, 0x9, 0x8, 0xF, 0xD };
struct pci_dev *dev = to_pci_dev(hwif->dev);
- u8 speed1 = speed;
- u8 unit = drive->dn & 1;
+ ide_drive_t *pair = ide_get_pair_dev(drive);
+ int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
+ unsigned long T = 1000000 / bus_speed; /* PCI clock based */
+ const u8 speed = drive->dma_mode;
u8 tmpbyte = 0x00;
- int m5229_udma = (hwif->channel) ? 0x57 : 0x56;
-
- if (speed == XFER_UDMA_6)
- speed1 = 0x47;
+ struct ide_timing t;
if (speed < XFER_UDMA_0) {
- u8 ultra_enable = (unit) ? 0x7f : 0xf7;
- /*
- * clear "ultra enable" bit
- */
- pci_read_config_byte(dev, m5229_udma, &tmpbyte);
- tmpbyte &= ultra_enable;
- pci_write_config_byte(dev, m5229_udma, tmpbyte);
-
- /*
- * FIXME: Oh, my... DMA timings are never set.
- */
+ ide_timing_compute(drive, drive->dma_mode, &t, T, 1);
+ if (pair) {
+ struct ide_timing p;
+
+ ide_timing_compute(pair, pair->pio_mode, &p, T, 1);
+ ide_timing_merge(&p, &t, &t,
+ IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+ if (pair->dma_mode) {
+ ide_timing_compute(pair, pair->dma_mode,
+ &p, T, 1);
+ ide_timing_merge(&p, &t, &t,
+ IDE_TIMING_SETUP | IDE_TIMING_8BIT);
+ }
+ }
+ ali_program_timings(hwif, drive, &t, 0);
} else {
- pci_read_config_byte(dev, m5229_udma, &tmpbyte);
- tmpbyte &= (0x0f << ((1-unit) << 2));
- /*
- * enable ultra dma and set timing
- */
- tmpbyte |= ((0x08 | ((4-speed1)&0x07)) << (unit << 2));
- pci_write_config_byte(dev, m5229_udma, tmpbyte);
+ ali_program_timings(hwif, drive, NULL,
+ udma_timing[speed - XFER_UDMA_0]);
if (speed >= XFER_UDMA_3) {
pci_read_config_byte(dev, 0x4b, &tmpbyte);
tmpbyte |= 1;
@@ -365,19 +376,13 @@ static int ali_cable_override(struct pci_dev *pdev)
*
* This checks if the controller and the cable are capable
* of UDMA66 transfers. It doesn't check the drives.
- * But see note 2 below!
- *
- * FIXME: frobs bits that are not defined on newer ALi devicea
*/
static u8 ali_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
- unsigned long flags;
u8 cbl = ATA_CBL_PATA40, tmpbyte;
- local_irq_save(flags);
-
if (m5229_revision >= 0xC2) {
/*
* m5229 80-pin cable detection (from Host View)
@@ -397,32 +402,26 @@ static u8 ali_cable_detect(ide_hwif_t *hwif)
}
}
- local_irq_restore(flags);
-
return cbl;
}
-#if !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC)
+#ifndef CONFIG_SPARC64
/**
* init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
* @hwif: interface to configure
*
* Obtain the IRQ tables for an ALi based IDE solution on the PC
* class platforms. This part of the code isn't applicable to the
- * Sparc and PowerPC systems.
+ * Sparc systems.
*/
-static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
+static void init_hwif_ali15x3(ide_hwif_t *hwif)
{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 ideic, inmir;
s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6,
1, 11, 0, 12, 0, 14, 0, 15 };
int irq = -1;
- if (dev->device == PCI_DEVICE_ID_AL_M5229)
- hwif->irq = hwif->channel ? 15 : 14;
-
if (isa_dev) {
/*
* read IDE interface control
@@ -455,7 +454,7 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
}
#else
#define init_hwif_ali15x3 NULL
-#endif /* !defined(CONFIG_SPARC64) && !defined(CONFIG_PPC) */
+#endif /* CONFIG_SPARC64 */
/**
* init_dma_ali15x3 - set up DMA on ALi15x3
@@ -465,8 +464,7 @@ static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif)
* Set up the DMA functionality on the ALi 15x3.
*/
-static int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
- const struct ide_port_info *d)
+static int init_dma_ali15x3(ide_hwif_t *hwif, const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long base = ide_pci_dma_base(hwif, d);
@@ -513,7 +511,7 @@ static const struct ide_dma_ops ali_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info ali15x3_chipset __devinitdata = {
+static const struct ide_port_info ali15x3_chipset = {
.name = DRV_NAME,
.init_chipset = init_chipset_ali15x3,
.init_hwif = init_hwif_ali15x3,
@@ -533,7 +531,8 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = {
* hot plug layer.
*/
-static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int alim15x3_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct ide_port_info d = ali15x3_chipset;
u8 rev = dev->revision, idx = id->driver_data;
@@ -598,6 +597,6 @@ static void __exit ali15x3_ide_exit(void)
module_init(ali15x3_ide_init);
module_exit(ali15x3_ide_exit);
-MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox");
+MODULE_AUTHOR("Michael Aubry, Andrzej Krzysztofowicz, CJ, Andre Hedrick, Alan Cox, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for ALi 15x3 IDE");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index 628cd2e5fed..cbfe846911d 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -3,7 +3,7 @@
* IDE driver for Linux.
*
* Copyright (c) 2000-2002 Vojtech Pavlik
- * Copyright (c) 2007-2008 Bartlomiej Zolnierkiewicz
+ * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
*
* Based on the work of:
* Andre Hedrick
@@ -70,7 +70,8 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask,
default: return;
}
- pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + (3 - dn), t);
+ if (timing->udma)
+ pci_write_config_byte(dev, AMD_UDMA_TIMING + offset + 3 - dn, t);
}
/*
@@ -78,14 +79,14 @@ static void amd_set_speed(struct pci_dev *dev, u8 dn, u8 udma_mask,
* to a desired transfer mode. It also can be called by upper layers.
*/
-static void amd_set_drive(ide_drive_t *drive, const u8 speed)
+static void amd_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
ide_drive_t *peer = ide_get_pair_dev(drive);
struct ide_timing t, p;
int T, UT;
u8 udma_mask = hwif->ultra_mask;
+ const u8 speed = drive->dma_mode;
T = 1000000000 / amd_clock;
UT = (udma_mask == ATA_UDMA2) ? T : (T / 2);
@@ -93,7 +94,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_compute(drive, speed, &t, T, UT);
if (peer) {
- ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+ ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
@@ -107,9 +108,10 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
* amd_set_pio_mode() is a callback from upper layers for PIO-only tuning.
*/
-static void amd_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void amd_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- amd_set_drive(drive, XFER_PIO_0 + pio);
+ drive->dma_mode = drive->pio_mode;
+ amd_set_drive(hwif, drive);
}
static void amd7409_cable_detect(struct pci_dev *dev)
@@ -221,7 +223,7 @@ static const struct ide_port_ops amd_port_ops = {
.udma_mask = udma, \
}
-static const struct ide_port_info amd74xx_chipsets[] __devinitdata = {
+static const struct ide_port_info amd74xx_chipsets[] = {
/* 0: AMD7401 */ DECLARE_AMD_DEV(0x00, ATA_UDMA2),
/* 1: AMD7409 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA4),
/* 2: AMD7411/7441 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA5),
@@ -233,7 +235,7 @@ static const struct ide_port_info amd74xx_chipsets[] __devinitdata = {
/* 6: AMD5536 */ DECLARE_AMD_DEV(ATA_SWDMA2, ATA_UDMA5),
};
-static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d;
u8 idx = id->driver_data;
@@ -340,6 +342,6 @@ static void __exit amd74xx_ide_exit(void)
module_init(amd74xx_ide_init);
module_exit(amd74xx_ide_exit);
-MODULE_AUTHOR("Vojtech Pavlik");
+MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("AMD PCI IDE driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
deleted file mode 100644
index 403d0e4265d..00000000000
--- a/drivers/ide/at91_ide.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * IDE host driver for AT91 (SAM9, CAP9, AT572D940HF) Static Memory Controller
- * with Compact Flash True IDE logic
- *
- * Copyright (c) 2008, 2009 Kelvatek Ltd.
- *
- * 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.
- *
- * 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.
- *
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/ide.h>
-#include <linux/platform_device.h>
-
-#include <mach/board.h>
-#include <mach/gpio.h>
-#include <mach/at91sam9263.h>
-#include <mach/at91sam9_smc.h>
-#include <mach/at91sam9263_matrix.h>
-
-#define DRV_NAME "at91_ide"
-
-#define perr(fmt, args...) pr_err(DRV_NAME ": " fmt, ##args)
-#define pdbg(fmt, args...) pr_debug("%s " fmt, __func__, ##args)
-
-/*
- * Access to IDE device is possible through EBI Static Memory Controller
- * with Compact Flash logic. For details see EBI and SMC datasheet sections
- * of any microcontroller from AT91SAM9 family.
- *
- * Within SMC chip select address space, lines A[23:21] distinguish Compact
- * Flash modes (I/O, common memory, attribute memory, True IDE). IDE modes are:
- * 0x00c0000 - True IDE
- * 0x00e0000 - Alternate True IDE (Alt Status Register)
- *
- * On True IDE mode Task File and Data Register are mapped at the same address.
- * To distinguish access between these two different bus data width is used:
- * 8Bit for Task File, 16Bit for Data I/O.
- *
- * After initialization we do 8/16 bit flipping (changes in SMC MODE register)
- * only inside IDE callback routines which are serialized by IDE layer,
- * so no additional locking needed.
- */
-
-#define TASK_FILE 0x00c00000
-#define ALT_MODE 0x00e00000
-#define REGS_SIZE 8
-
-#define enter_16bit(cs, mode) do { \
- mode = at91_sys_read(AT91_SMC_MODE(cs)); \
- at91_sys_write(AT91_SMC_MODE(cs), mode | AT91_SMC_DBW_16); \
-} while (0)
-
-#define leave_16bit(cs, mode) at91_sys_write(AT91_SMC_MODE(cs), mode);
-
-static void set_smc_timings(const u8 chipselect, const u16 cycle,
- const u16 setup, const u16 pulse,
- const u16 data_float, int use_iordy)
-{
- unsigned long mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
- AT91_SMC_BAT_SELECT;
-
- /* disable or enable waiting for IORDY signal */
- if (use_iordy)
- mode |= AT91_SMC_EXNWMODE_READY;
-
- /* add data float cycles if needed */
- if (data_float)
- mode |= AT91_SMC_TDF_(data_float);
-
- at91_sys_write(AT91_SMC_MODE(chipselect), mode);
-
- /* setup timings in SMC */
- at91_sys_write(AT91_SMC_SETUP(chipselect), AT91_SMC_NWESETUP_(setup) |
- AT91_SMC_NCS_WRSETUP_(0) |
- AT91_SMC_NRDSETUP_(setup) |
- AT91_SMC_NCS_RDSETUP_(0));
- at91_sys_write(AT91_SMC_PULSE(chipselect), AT91_SMC_NWEPULSE_(pulse) |
- AT91_SMC_NCS_WRPULSE_(cycle) |
- AT91_SMC_NRDPULSE_(pulse) |
- AT91_SMC_NCS_RDPULSE_(cycle));
- at91_sys_write(AT91_SMC_CYCLE(chipselect), AT91_SMC_NWECYCLE_(cycle) |
- AT91_SMC_NRDCYCLE_(cycle));
-}
-
-static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz)
-{
- u64 tmp = ns;
-
- tmp *= mck_hz;
- tmp += 1000*1000*1000 - 1; /* round up */
- do_div(tmp, 1000*1000*1000);
- return (unsigned int) tmp;
-}
-
-static void apply_timings(const u8 chipselect, const u8 pio,
- const struct ide_timing *timing, int use_iordy)
-{
- unsigned int t0, t1, t2, t6z;
- unsigned int cycle, setup, pulse, data_float;
- unsigned int mck_hz;
- struct clk *mck;
-
- /* see table 22 of Compact Flash standard 4.1 for the meaning,
- * we do not stretch active (t2) time, so setup (t1) + hold time (th)
- * assure at least minimal recovery (t2i) time */
- t0 = timing->cyc8b;
- t1 = timing->setup;
- t2 = timing->act8b;
- t6z = (pio < 5) ? 30 : 20;
-
- pdbg("t0=%u t1=%u t2=%u t6z=%u\n", t0, t1, t2, t6z);
-
- mck = clk_get(NULL, "mck");
- BUG_ON(IS_ERR(mck));
- mck_hz = clk_get_rate(mck);
- pdbg("mck_hz=%u\n", mck_hz);
-
- cycle = calc_mck_cycles(t0, mck_hz);
- setup = calc_mck_cycles(t1, mck_hz);
- pulse = calc_mck_cycles(t2, mck_hz);
- data_float = calc_mck_cycles(t6z, mck_hz);
-
- pdbg("cycle=%u setup=%u pulse=%u data_float=%u\n",
- cycle, setup, pulse, data_float);
-
- set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy);
-}
-
-static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
- void *buf, unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- u8 chipselect = hwif->select_data;
- unsigned long mode;
-
- pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
-
- len++;
-
- enter_16bit(chipselect, mode);
- readsw((void __iomem *)io_ports->data_addr, buf, len / 2);
- leave_16bit(chipselect, mode);
-}
-
-static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
- void *buf, unsigned int len)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct ide_io_ports *io_ports = &hwif->io_ports;
- u8 chipselect = hwif->select_data;
- unsigned long mode;
-
- pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
-
- enter_16bit(chipselect, mode);
- writesw((void __iomem *)io_ports->data_addr, buf, len / 2);
- leave_16bit(chipselect, mode);
-}
-
-static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- struct ide_timing *timing;
- u8 chipselect = drive->hwif->select_data;
- int use_iordy = 0;
-
- pdbg("chipselect %u pio %u\n", chipselect, pio);
-
- timing = ide_timing_find_mode(XFER_PIO_0 + pio);
- BUG_ON(!timing);
-
- if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
- !(ata_id_is_cfa(drive->id) && pio > 4))
- use_iordy = 1;
-
- apply_timings(chipselect, pio, timing, use_iordy);
-}
-
-static const struct ide_tp_ops at91_ide_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
- .write_devctl = ide_write_devctl,
-
- .dev_select = ide_dev_select,
- .tf_load = ide_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = at91_ide_input_data,
- .output_data = at91_ide_output_data,
-};
-
-static const struct ide_port_ops at91_ide_port_ops = {
- .set_pio_mode = at91_ide_set_pio_mode,
-};
-
-static const struct ide_port_info at91_ide_port_info __initdata = {
- .port_ops = &at91_ide_port_ops,
- .tp_ops = &at91_ide_tp_ops,
- .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE |
- IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS,
- .pio_mask = ATA_PIO6,
-};
-
-/*
- * If interrupt is delivered through GPIO, IRQ are triggered on falling
- * and rising edge of signal. Whereas IDE device request interrupt on high
- * level (rising edge in our case). This mean we have fake interrupts, so
- * we need to check interrupt pin and exit instantly from ISR when line
- * is on low level.
- */
-
-irqreturn_t at91_irq_handler(int irq, void *dev_id)
-{
- int ntries = 8;
- int pin_val1, pin_val2;
-
- /* additional deglitch, line can be noisy in badly designed PCB */
- do {
- pin_val1 = at91_get_gpio_value(irq);
- pin_val2 = at91_get_gpio_value(irq);
- } while (pin_val1 != pin_val2 && --ntries > 0);
-
- if (pin_val1 == 0 || ntries <= 0)
- return IRQ_HANDLED;
-
- return ide_intr(irq, dev_id);
-}
-
-static int __init at91_ide_probe(struct platform_device *pdev)
-{
- int ret;
- hw_regs_t hw;
- hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
- struct ide_host *host;
- struct resource *res;
- unsigned long tf_base = 0, ctl_base = 0;
- struct at91_cf_data *board = pdev->dev.platform_data;
-
- if (!board)
- return -ENODEV;
-
- if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) {
- perr("no device detected\n");
- return -ENODEV;
- }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- perr("can't get memory resource\n");
- return -ENODEV;
- }
-
- if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE,
- REGS_SIZE, "ide") ||
- !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE,
- REGS_SIZE, "alt")) {
- perr("memory resources in use\n");
- return -EBUSY;
- }
-
- pdbg("chipselect %u irq %u res %08lx\n", board->chipselect,
- board->irq_pin, (unsigned long) res->start);
-
- tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE,
- REGS_SIZE);
- ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE,
- REGS_SIZE);
- if (!tf_base || !ctl_base) {
- perr("can't map memory regions\n");
- return -EBUSY;
- }
-
- memset(&hw, 0, sizeof(hw));
-
- if (board->flags & AT91_IDE_SWAP_A0_A2) {
- /* workaround for stupid hardware bug */
- hw.io_ports.data_addr = tf_base + 0;
- hw.io_ports.error_addr = tf_base + 4;
- hw.io_ports.nsect_addr = tf_base + 2;
- hw.io_ports.lbal_addr = tf_base + 6;
- hw.io_ports.lbam_addr = tf_base + 1;
- hw.io_ports.lbah_addr = tf_base + 5;
- hw.io_ports.device_addr = tf_base + 3;
- hw.io_ports.command_addr = tf_base + 7;
- hw.io_ports.ctl_addr = ctl_base + 3;
- } else
- ide_std_init_ports(&hw, tf_base, ctl_base + 6);
-
- hw.irq = board->irq_pin;
- hw.chipset = ide_generic;
- hw.dev = &pdev->dev;
-
- host = ide_host_alloc(&at91_ide_port_info, hws);
- if (!host) {
- perr("failed to allocate ide host\n");
- return -ENOMEM;
- }
-
- /* setup Static Memory Controller - PIO 0 as default */
- apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0);
-
- /* with GPIO interrupt we have to do quirks in handler */
- if (board->irq_pin >= PIN_BASE)
- host->irq_handler = at91_irq_handler;
-
- host->ports[0]->select_data = board->chipselect;
-
- ret = ide_host_register(host, &at91_ide_port_info, hws);
- if (ret) {
- perr("failed to register ide host\n");
- goto err_free_host;
- }
- platform_set_drvdata(pdev, host);
- return 0;
-
-err_free_host:
- ide_host_free(host);
- return ret;
-}
-
-static int __exit at91_ide_remove(struct platform_device *pdev)
-{
- struct ide_host *host = platform_get_drvdata(pdev);
-
- ide_host_remove(host);
- return 0;
-}
-
-static struct platform_driver at91_ide_driver = {
- .driver = {
- .name = DRV_NAME,
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(at91_ide_remove),
-};
-
-static int __init at91_ide_init(void)
-{
- return platform_driver_probe(&at91_ide_driver, at91_ide_probe);
-}
-
-static void __exit at91_ide_exit(void)
-{
- platform_driver_unregister(&at91_ide_driver);
-}
-
-module_init(at91_ide_init);
-module_exit(at91_ide_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Stanislaw Gruszka <stf_xl@wp.pl>");
-
diff --git a/drivers/ide/atiixp.c b/drivers/ide/atiixp.c
index 923cbfe259d..dbd0f242ec1 100644
--- a/drivers/ide/atiixp.c
+++ b/drivers/ide/atiixp.c
@@ -42,19 +42,20 @@ static DEFINE_SPINLOCK(atiixp_lock);
/**
* atiixp_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Set the interface PIO mode.
*/
-static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void atiixp_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn ^ 1) * 8;
u32 pio_timing_data;
u16 pio_mode_data;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
spin_lock_irqsave(&atiixp_lock, flags);
@@ -74,21 +75,22 @@ static void atiixp_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* atiixp_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Set a ATIIXP host controller to the desired DMA mode. This involves
* programming the right timing data into the PCI configuration space.
*/
-static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void atiixp_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn ^ 1) * 8;
u32 tmp32;
u16 tmp16;
u16 udma_ctl = 0;
+ const u8 speed = drive->dma_mode;
spin_lock_irqsave(&atiixp_lock, flags);
@@ -137,7 +139,7 @@ static const struct ide_port_ops atiixp_port_ops = {
.cable_detect = atiixp_cable_detect,
};
-static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
+static const struct ide_port_info atiixp_pci_info[] = {
{ /* 0: IXP200/300/400/700 */
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
@@ -166,7 +168,7 @@ static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
* finds a device matching our IDE device tables.
*/
-static int __devinit atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &atiixp_pci_info[id->driver_data], NULL);
}
@@ -177,6 +179,7 @@ static const struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), 0 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), 1 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), 0 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 46013644c96..259786ca8b7 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -36,13 +36,17 @@
#include <linux/ide.h>
#include <linux/scatterlist.h>
-#include <asm/mach-au1x00/au1xxx.h>
+#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide"
#define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
+#ifndef IDE_REG_SHIFT
+#define IDE_REG_SHIFT 5
+#endif
+
/* enable the burstmode in the dbdma */
#define IDE_AU1XXX_BURSTMODE 1
@@ -56,8 +60,8 @@ static inline void auide_insw(unsigned long port, void *addr, u32 count)
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
- if(!put_dest_flags(ahwif->rx_chan, (void*)addr, count << 1,
- DDMA_FLAGS_NOIE)) {
+ if (!au1xxx_dbdma_put_dest(ahwif->rx_chan, virt_to_phys(addr),
+ count << 1, DDMA_FLAGS_NOIE)) {
printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
return;
}
@@ -74,8 +78,8 @@ static inline void auide_outsw(unsigned long port, void *addr, u32 count)
chan_tab_t *ctp;
au1x_ddma_desc_t *dp;
- if(!put_source_flags(ahwif->tx_chan, (void*)addr,
- count << 1, DDMA_FLAGS_NOIE)) {
+ if (!au1xxx_dbdma_put_source(ahwif->tx_chan, virt_to_phys(addr),
+ count << 1, DDMA_FLAGS_NOIE)) {
printk(KERN_ERR "%s failed %d\n", __func__, __LINE__);
return;
}
@@ -99,12 +103,11 @@ static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
}
#endif
-static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void au1xxx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
- /* set pio mode! */
- switch(pio) {
+ switch (drive->pio_mode - XFER_PIO_0) {
case 0:
mem_sttime = SBC_IDE_TIMING(PIO0);
@@ -161,11 +164,11 @@ static void au1xxx_set_pio_mode(ide_drive_t *drive, const u8 pio)
au_writel(mem_stcfg,MEM_STCFG2);
}
-static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void auide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int mem_sttime = 0, mem_stcfg = au_readl(MEM_STCFG2);
- switch(speed) {
+ switch (drive->dma_mode) {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
case XFER_MW_DMA_2:
mem_sttime = SBC_IDE_TIMING(MDMA2);
@@ -246,17 +249,14 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
flags = DDMA_FLAGS_NOIE;
if (iswrite) {
- if(!put_source_flags(ahwif->tx_chan,
- (void*) sg_virt(sg),
- tc, flags)) {
+ if (!au1xxx_dbdma_put_source(ahwif->tx_chan,
+ sg_phys(sg), tc, flags)) {
printk(KERN_ERR "%s failed %d\n",
__func__, __LINE__);
}
- } else
- {
- if(!put_dest_flags(ahwif->rx_chan,
- (void*) sg_virt(sg),
- tc, flags)) {
+ } else {
+ if (!au1xxx_dbdma_put_dest(ahwif->rx_chan,
+ sg_phys(sg), tc, flags)) {
printk(KERN_ERR "%s failed %d\n",
__func__, __LINE__);
}
@@ -300,8 +300,8 @@ static int auide_dma_test_irq(ide_drive_t *drive)
*/
drive->waiting_for_dma++;
if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
- printk(KERN_WARNING "%s: timeout waiting for ddma to \
- complete\n", drive->name);
+ printk(KERN_WARNING "%s: timeout waiting for ddma to complete\n",
+ drive->name);
return 1;
}
udelay(10);
@@ -321,10 +321,11 @@ static void auide_ddma_rx_callback(int irq, void *param)
}
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
-static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
+static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize,
+ u32 devwidth, u32 flags, u32 regbase)
{
dev->dev_id = dev_id;
- dev->dev_physaddr = (u32)IDE_PHYS_ADDR;
+ dev->dev_physaddr = CPHYSADDR(regbase);
dev->dev_intlevel = 0;
dev->dev_intpolarity = 0;
dev->dev_tsize = tsize;
@@ -348,7 +349,7 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
dbdev_tab_t source_dev_tab, target_dev_tab;
u32 dev_id, tsize, devwidth, flags;
- dev_id = IDE_DDMA_REQ;
+ dev_id = hwif->ddma_id;
tsize = 8; /* 1 */
devwidth = 32; /* 16 */
@@ -360,20 +361,17 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
#endif
/* setup dev_tab for tx channel */
- auide_init_dbdma_dev( &source_dev_tab,
- dev_id,
- tsize, devwidth, DEV_FLAGS_OUT | flags);
+ auide_init_dbdma_dev(&source_dev_tab, dev_id, tsize, devwidth,
+ DEV_FLAGS_OUT | flags, auide->regbase);
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
- auide_init_dbdma_dev( &source_dev_tab,
- dev_id,
- tsize, devwidth, DEV_FLAGS_IN | flags);
+ auide_init_dbdma_dev(&source_dev_tab, dev_id, tsize, devwidth,
+ DEV_FLAGS_IN | flags, auide->regbase);
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* We also need to add a target device for the DMA */
- auide_init_dbdma_dev( &target_dev_tab,
- (u32)DSCR_CMD0_ALWAYS,
- tsize, devwidth, DEV_FLAGS_ANYUSE);
+ auide_init_dbdma_dev(&target_dev_tab, (u32)DSCR_CMD0_ALWAYS, tsize,
+ devwidth, DEV_FLAGS_ANYUSE, auide->regbase);
auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
/* Get a channel for TX */
@@ -415,14 +413,12 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
#endif
/* setup dev_tab for tx channel */
- auide_init_dbdma_dev( &source_dev_tab,
- (u32)DSCR_CMD0_ALWAYS,
- 8, 32, DEV_FLAGS_OUT | flags);
+ auide_init_dbdma_dev(&source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32,
+ DEV_FLAGS_OUT | flags, auide->regbase);
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
- auide_init_dbdma_dev( &source_dev_tab,
- (u32)DSCR_CMD0_ALWAYS,
- 8, 32, DEV_FLAGS_IN | flags);
+ auide_init_dbdma_dev(&source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32,
+ DEV_FLAGS_IN | flags, auide->regbase);
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* Get a channel for TX */
@@ -449,7 +445,7 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
}
#endif
-static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif)
+static void auide_setup_ports(struct ide_hw *hw, _auide_hwif *ahwif)
{
int i;
unsigned long *ata_regs = hw->io_ports_array;
@@ -499,6 +495,7 @@ static const struct ide_port_info au1xxx_port_info = {
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
.mwdma_mask = ATA_MWDMA2,
#endif
+ .chipset = ide_au1xxx,
};
static int au_ide_probe(struct platform_device *dev)
@@ -507,7 +504,7 @@ static int au_ide_probe(struct platform_device *dev)
struct resource *res;
struct ide_host *host;
int ret = 0;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
char *mode = "MWDMA2";
@@ -531,26 +528,32 @@ static int au_ide_probe(struct platform_device *dev)
goto out;
}
- if (!request_mem_region(res->start, res->end - res->start + 1,
- dev->name)) {
+ if (!request_mem_region(res->start, resource_size(res), dev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
ret = -EBUSY;
goto out;
}
- ahwif->regbase = (u32)ioremap(res->start, res->end - res->start + 1);
+ ahwif->regbase = (u32)ioremap(res->start, resource_size(res));
if (ahwif->regbase == 0) {
ret = -ENOMEM;
goto out;
}
+ res = platform_get_resource(dev, IORESOURCE_DMA, 0);
+ if (!res) {
+ pr_debug("%s: no DDMA ID resource\n", DRV_NAME);
+ ret = -ENODEV;
+ goto out;
+ }
+ ahwif->ddma_id = res->start;
+
memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif);
hw.irq = ahwif->irq;
hw.dev = &dev->dev;
- hw.chipset = ide_au1xxx;
- ret = ide_host_add(&au1xxx_port_info, hws, &host);
+ ret = ide_host_add(&au1xxx_port_info, hws, 1, &host);
if (ret)
goto out;
@@ -575,7 +578,7 @@ static int au_ide_remove(struct platform_device *dev)
iounmap((void *)ahwif->regbase);
res = platform_get_resource(dev, IORESOURCE_MEM, 0);
- release_mem_region(res->start, res->end - res->start + 1);
+ release_mem_region(res->start, resource_size(res));
return 0;
}
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c
index d028f8864bc..46eaf58d881 100644
--- a/drivers/ide/buddha.c
+++ b/drivers/ide/buddha.c
@@ -23,6 +23,7 @@
#include <linux/zorro.h>
#include <linux/ide.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
@@ -99,7 +100,7 @@ static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };
* Check and acknowledge the interrupt status
*/
-static int buddha_ack_intr(ide_hwif_t *hwif)
+static int buddha_test_irq(ide_hwif_t *hwif)
{
unsigned char ch;
@@ -109,21 +110,16 @@ static int buddha_ack_intr(ide_hwif_t *hwif)
return 1;
}
-static int xsurf_ack_intr(ide_hwif_t *hwif)
+static void xsurf_clear_irq(ide_drive_t *drive)
{
- unsigned char ch;
-
- ch = z_readb(hwif->io_ports.irq_addr);
- /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */
- z_writeb(0, hwif->io_ports.irq_addr);
- if (!(ch & 0x80))
- return 0;
- return 1;
+ /*
+ * X-Surf needs 0 written to IRQ register to ensure ISA bit A11 stays at 0
+ */
+ z_writeb(0, drive->hwif->io_ports.irq_addr);
}
-static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
- unsigned long ctl, unsigned long irq_port,
- ide_ack_intr_t *ack_intr)
+static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base,
+ unsigned long ctl, unsigned long irq_port)
{
int i;
@@ -138,14 +134,22 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
- hw->ack_intr = ack_intr;
-
- hw->chipset = ide_generic;
}
+static const struct ide_port_ops buddha_port_ops = {
+ .test_irq = buddha_test_irq,
+};
+
+static const struct ide_port_ops xsurf_port_ops = {
+ .clear_irq = xsurf_clear_irq,
+ .test_irq = buddha_test_irq,
+};
+
static const struct ide_port_info buddha_port_info = {
+ .port_ops = &buddha_port_ops,
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
+ .chipset = ide_generic,
};
/*
@@ -161,7 +165,8 @@ static int __init buddha_init(void)
while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
unsigned long board;
- hw_regs_t hw[MAX_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
+ struct ide_hw hw[MAX_NUM_HWIFS], *hws[MAX_NUM_HWIFS];
+ struct ide_port_info d = buddha_port_info;
if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
buddha_num_hwifs = BUDDHA_NUM_HWIFS;
@@ -172,6 +177,7 @@ static int __init buddha_init(void)
} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) {
buddha_num_hwifs = XSURF_NUM_HWIFS;
type=BOARD_XSURF;
+ d.port_ops = &xsurf_port_ops;
} else
continue;
@@ -192,7 +198,7 @@ fail_base2:
continue;
}
}
- buddha_board = ZTWO_VADDR(board);
+ buddha_board = (unsigned long)ZTWO_VADDR(board);
/* write to BUDDHA_IRQ_MR to enable the board IRQ */
/* X-Surf doesn't have this. IRQs are always on */
@@ -204,28 +210,24 @@ fail_base2:
for (i = 0; i < buddha_num_hwifs; i++) {
unsigned long base, ctl, irq_port;
- ide_ack_intr_t *ack_intr;
if (type != BOARD_XSURF) {
base = buddha_board + buddha_bases[i];
ctl = base + BUDDHA_CONTROL;
irq_port = buddha_board + buddha_irqports[i];
- ack_intr = buddha_ack_intr;
} else {
base = buddha_board + xsurf_bases[i];
/* X-Surf has no CS1* (Control/AltStat) */
ctl = 0;
irq_port = buddha_board + xsurf_irqports[i];
- ack_intr = xsurf_ack_intr;
}
- buddha_setup_ports(&hw[i], base, ctl, irq_port,
- ack_intr);
+ buddha_setup_ports(&hw[i], base, ctl, irq_port);
hws[i] = &hw[i];
}
- ide_host_add(&buddha_port_info, hws, NULL);
+ ide_host_add(&d, hws, i, NULL);
}
return 0;
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c
index 8890276fef7..70f0a2754c1 100644
--- a/drivers/ide/cmd640.c
+++ b/drivers/ide/cmd640.c
@@ -105,12 +105,13 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/io.h>
#define DRV_NAME "cmd640"
-static int cmd640_vlb;
+static bool cmd640_vlb;
/*
* CMD640 specific registers definition.
@@ -153,6 +154,7 @@ static int cmd640_vlb;
#define ARTTIM23 0x57
#define ARTTIM23_DIS_RA2 0x04
#define ARTTIM23_DIS_RA3 0x08
+#define ARTTIM23_IDE23INTR 0x10
#define DRWTIM23 0x58
#define BRST 0x59
@@ -571,9 +573,10 @@ static void cmd640_set_mode(ide_drive_t *drive, unsigned int index,
program_drive_counts(drive, index);
}
-static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned int index = 0, cycle_time;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 b;
switch (pio) {
@@ -604,7 +607,7 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
-static void cmd640_init_dev(ide_drive_t *drive)
+static void __init cmd640_init_dev(ide_drive_t *drive)
{
unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);
@@ -629,12 +632,22 @@ static void cmd640_init_dev(ide_drive_t *drive)
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
}
+static int cmd640_test_irq(ide_hwif_t *hwif)
+{
+ int irq_reg = hwif->channel ? ARTTIM23 : CFR;
+ u8 irq_mask = hwif->channel ? ARTTIM23_IDE23INTR :
+ CFR_IDE01INTR;
+ u8 irq_stat = get_cmd640_reg(irq_reg);
+
+ return (irq_stat & irq_mask) ? 1 : 0;
+}
static const struct ide_port_ops cmd640_port_ops = {
.init_dev = cmd640_init_dev,
#ifdef CONFIG_BLK_DEV_CMD640_ENHANCED
.set_pio_mode = cmd640_set_pio_mode,
#endif
+ .test_irq = cmd640_test_irq,
};
static int pci_conf1(void)
@@ -672,7 +685,7 @@ static int pci_conf2(void)
return 0;
}
-static const struct ide_port_info cmd640_port_info __initdata = {
+static const struct ide_port_info cmd640_port_info __initconst = {
.chipset = ide_cmd640,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA |
@@ -708,7 +721,7 @@ static int __init cmd640x_init(void)
int second_port_cmd640 = 0, rc;
const char *bus_type, *port2;
u8 b, cfr;
- hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
+ struct ide_hw hw[2], *hws[2];
if (cmd640_vlb && probe_for_cmd640_vlb()) {
bus_type = "VLB";
@@ -762,11 +775,9 @@ static int __init cmd640x_init(void)
ide_std_init_ports(&hw[0], 0x1f0, 0x3f6);
hw[0].irq = 14;
- hw[0].chipset = ide_cmd640;
ide_std_init_ports(&hw[1], 0x170, 0x376);
hw[1].irq = 15;
- hw[1].chipset = ide_cmd640;
printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x"
"\n", 'a' + cmd640_chip_version - 1, bus_type, cfr);
@@ -824,7 +835,8 @@ static int __init cmd640x_init(void)
cmd640_dump_regs();
#endif
- return ide_host_add(&cmd640_port_info, hws, NULL);
+ return ide_host_add(&cmd640_port_info, hws, second_port_cmd640 ? 2 : 1,
+ NULL);
}
module_param_named(probe_vlb, cmd640_vlb, bool, 0);
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 80b777e4247..b127ed60c73 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -7,7 +7,8 @@
* Copyright (C) 1998 David S. Miller (davem@redhat.com)
*
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
- * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com>
*/
#include <linux/module.h>
@@ -20,14 +21,6 @@
#define DRV_NAME "cmd64x"
-#define CMD_DEBUG 0
-
-#if CMD_DEBUG
-#define cmdprintk(x...) printk(x)
-#else
-#define cmdprintk(x...)
-#endif
-
/*
* CMD64x specific registers definition.
*/
@@ -58,78 +51,42 @@
#define UDIDETCR1 0x7B
#define DTPR1 0x7C
-static u8 quantize_timing(int timing, int quant)
-{
- return (timing + quant - 1) / quant;
-}
-
-/*
- * This routine calculates active/recovery counts and then writes them into
- * the chipset registers.
- */
-static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_time)
+static void cmd64x_program_timings(ide_drive_t *drive, u8 mode)
{
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- int clock_time = 1000 / (ide_pci_clk ? ide_pci_clk : 33);
- u8 cycle_count, active_count, recovery_count, drwtim;
+ int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
+ const unsigned long T = 1000000 / bus_speed;
static const u8 recovery_values[] =
{15, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};
+ static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
+ static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
static const u8 drwtim_regs[4] = {DRWTIM0, DRWTIM1, DRWTIM2, DRWTIM3};
+ struct ide_timing t;
+ u8 arttim = 0;
- cmdprintk("program_cycle_times parameters: total=%d, active=%d\n",
- cycle_time, active_time);
-
- cycle_count = quantize_timing( cycle_time, clock_time);
- active_count = quantize_timing(active_time, clock_time);
- recovery_count = cycle_count - active_count;
+ ide_timing_compute(drive, mode, &t, T, 0);
/*
* In case we've got too long recovery phase, try to lengthen
* the active phase
*/
- if (recovery_count > 16) {
- active_count += recovery_count - 16;
- recovery_count = 16;
+ if (t.recover > 16) {
+ t.active += t.recover - 16;
+ t.recover = 16;
}
- if (active_count > 16) /* shouldn't actually happen... */
- active_count = 16;
-
- cmdprintk("Final counts: total=%d, active=%d, recovery=%d\n",
- cycle_count, active_count, recovery_count);
+ if (t.active > 16) /* shouldn't actually happen... */
+ t.active = 16;
/*
* Convert values to internal chipset representation
*/
- recovery_count = recovery_values[recovery_count];
- active_count &= 0x0f;
+ t.recover = recovery_values[t.recover];
+ t.active &= 0x0f;
/* Program the active/recovery counts into the DRWTIM register */
- drwtim = (active_count << 4) | recovery_count;
- (void) pci_write_config_byte(dev, drwtim_regs[drive->dn], drwtim);
- cmdprintk("Write 0x%02x to reg 0x%x\n", drwtim, drwtim_regs[drive->dn]);
-}
-
-/*
- * This routine writes into the chipset registers
- * PIO setup/active/recovery timings.
- */
-static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct pci_dev *dev = to_pci_dev(hwif->dev);
- struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
- unsigned int cycle_time;
- u8 setup_count, arttim = 0;
-
- static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
- static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
-
- cycle_time = ide_pio_cycle_time(drive, pio);
-
- program_cycle_times(drive, cycle_time, t->active);
-
- setup_count = quantize_timing(t->setup,
- 1000 / (ide_pci_clk ? ide_pci_clk : 33));
+ pci_write_config_byte(dev, drwtim_regs[drive->dn],
+ (t.active << 4) | t.recover);
/*
* The primary channel has individual address setup timing registers
@@ -140,15 +97,21 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
if (hwif->channel) {
ide_drive_t *pair = ide_get_pair_dev(drive);
- drive->drive_data = setup_count;
+ if (pair) {
+ struct ide_timing tp;
- if (pair)
- setup_count = max_t(u8, setup_count, pair->drive_data);
+ ide_timing_compute(pair, pair->pio_mode, &tp, T, 0);
+ ide_timing_merge(&t, &tp, &t, IDE_TIMING_SETUP);
+ if (pair->dma_mode) {
+ ide_timing_compute(pair, pair->dma_mode,
+ &tp, T, 0);
+ ide_timing_merge(&tp, &t, &t, IDE_TIMING_SETUP);
+ }
+ }
}
- if (setup_count > 5) /* shouldn't actually happen... */
- setup_count = 5;
- cmdprintk("Final address setup count: %d\n", setup_count);
+ if (t.setup > 5) /* shouldn't actually happen... */
+ t.setup = 5;
/*
* Program the address setup clocks into the ARTTIM registers.
@@ -158,9 +121,8 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
if (hwif->channel)
arttim &= ~ARTTIM23_INTR_CH1;
arttim &= ~0xc0;
- arttim |= setup_values[setup_count];
+ arttim |= setup_values[t.setup];
(void) pci_write_config_byte(dev, arttim_regs[drive->dn], arttim);
- cmdprintk("Write 0x%02x to reg 0x%x\n", arttim, arttim_regs[drive->dn]);
}
/*
@@ -168,8 +130,10 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
* Special cases are 8: prefetch off, 9: prefetch on (both never worked)
*/
-static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cmd64x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
+
/*
* Filter out the prefetch control values
* to prevent PIO5 from being programmed
@@ -177,20 +141,18 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
if (pio == 8 || pio == 9)
return;
- cmd64x_tune_pio(drive, pio);
+ cmd64x_program_timings(drive, XFER_PIO_0 + pio);
}
-static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void cmd64x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 unit = drive->dn & 0x01;
u8 regU = 0, pciU = hwif->channel ? UDIDETCR1 : UDIDETCR0;
+ const u8 speed = drive->dma_mode;
- if (speed >= XFER_SW_DMA_0) {
- (void) pci_read_config_byte(dev, pciU, &regU);
- regU &= ~(unit ? 0xCA : 0x35);
- }
+ pci_read_config_byte(dev, pciU, &regU);
+ regU &= ~(unit ? 0xCA : 0x35);
switch(speed) {
case XFER_UDMA_5:
@@ -212,25 +174,20 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
regU |= unit ? 0xC2 : 0x31;
break;
case XFER_MW_DMA_2:
- program_cycle_times(drive, 120, 70);
- break;
case XFER_MW_DMA_1:
- program_cycle_times(drive, 150, 80);
- break;
case XFER_MW_DMA_0:
- program_cycle_times(drive, 480, 215);
+ cmd64x_program_timings(drive, speed);
break;
}
- if (speed >= XFER_SW_DMA_0)
- (void) pci_write_config_byte(dev, pciU, regU);
+ pci_write_config_byte(dev, pciU, regU);
}
-static int cmd648_dma_end(ide_drive_t *drive)
+static void cmd648_clear_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- unsigned long base = hwif->dma_base - (hwif->channel * 8);
- int err = ide_dma_end(drive);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long base = pci_resource_start(dev, 4);
u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0;
u8 mrdmode = inb(base + 1);
@@ -238,11 +195,9 @@ static int cmd648_dma_end(ide_drive_t *drive)
/* clear the interrupt bit */
outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask,
base + 1);
-
- return err;
}
-static int cmd64x_dma_end(ide_drive_t *drive)
+static void cmd64x_clear_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -250,62 +205,40 @@ static int cmd64x_dma_end(ide_drive_t *drive)
u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 :
CFR_INTR_CH0;
u8 irq_stat = 0;
- int err = ide_dma_end(drive);
(void) pci_read_config_byte(dev, irq_reg, &irq_stat);
/* clear the interrupt bit */
(void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask);
-
- return err;
}
-static int cmd648_dma_test_irq(ide_drive_t *drive)
+static int cmd648_test_irq(ide_hwif_t *hwif)
{
- ide_hwif_t *hwif = drive->hwif;
- unsigned long base = hwif->dma_base - (hwif->channel * 8);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long base = pci_resource_start(dev, 4);
u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0;
- u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
u8 mrdmode = inb(base + 1);
-#ifdef DEBUG
- printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n",
- drive->name, dma_stat, mrdmode, irq_mask);
-#endif
- if (!(mrdmode & irq_mask))
- return 0;
+ pr_debug("%s: mrdmode: 0x%02x irq_mask: 0x%02x\n",
+ hwif->name, mrdmode, irq_mask);
- /* return 1 if INTR asserted */
- if (dma_stat & 4)
- return 1;
-
- return 0;
+ return (mrdmode & irq_mask) ? 1 : 0;
}
-static int cmd64x_dma_test_irq(ide_drive_t *drive)
+static int cmd64x_test_irq(ide_hwif_t *hwif)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int irq_reg = hwif->channel ? ARTTIM23 : CFR;
u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 :
CFR_INTR_CH0;
- u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
u8 irq_stat = 0;
(void) pci_read_config_byte(dev, irq_reg, &irq_stat);
-#ifdef DEBUG
- printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n",
- drive->name, dma_stat, irq_stat, irq_mask);
-#endif
- if (!(irq_stat & irq_mask))
- return 0;
-
- /* return 1 if INTR asserted */
- if (dma_stat & 4)
- return 1;
+ pr_debug("%s: irq_stat: 0x%02x irq_mask: 0x%02x\n",
+ hwif->name, irq_stat, irq_mask);
- return 0;
+ return (irq_stat & irq_mask) ? 1 : 0;
}
/*
@@ -370,18 +303,17 @@ static u8 cmd64x_cable_detect(ide_hwif_t *hwif)
static const struct ide_port_ops cmd64x_port_ops = {
.set_pio_mode = cmd64x_set_pio_mode,
.set_dma_mode = cmd64x_set_dma_mode,
+ .clear_irq = cmd64x_clear_irq,
+ .test_irq = cmd64x_test_irq,
.cable_detect = cmd64x_cable_detect,
};
-static const struct ide_dma_ops cmd64x_dma_ops = {
- .dma_host_set = ide_dma_host_set,
- .dma_setup = ide_dma_setup,
- .dma_start = ide_dma_start,
- .dma_end = cmd64x_dma_end,
- .dma_test_irq = cmd64x_dma_test_irq,
- .dma_lost_irq = ide_dma_lost_irq,
- .dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_sff_read_status = ide_dma_sff_read_status,
+static const struct ide_port_ops cmd648_port_ops = {
+ .set_pio_mode = cmd64x_set_pio_mode,
+ .set_dma_mode = cmd64x_set_dma_mode,
+ .clear_irq = cmd648_clear_irq,
+ .test_irq = cmd648_test_irq,
+ .cable_detect = cmd64x_cable_detect,
};
static const struct ide_dma_ops cmd646_rev1_dma_ops = {
@@ -395,26 +327,15 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_dma_ops cmd648_dma_ops = {
- .dma_host_set = ide_dma_host_set,
- .dma_setup = ide_dma_setup,
- .dma_start = ide_dma_start,
- .dma_end = cmd648_dma_end,
- .dma_test_irq = cmd648_dma_test_irq,
- .dma_lost_irq = ide_dma_lost_irq,
- .dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_sff_read_status = ide_dma_sff_read_status,
-};
-
-static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
+static const struct ide_port_info cmd64x_chipsets[] = {
{ /* 0: CMD643 */
.name = DRV_NAME,
.init_chipset = init_chipset_cmd64x,
.enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
.port_ops = &cmd64x_port_ops,
- .dma_ops = &cmd64x_dma_ops,
.host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
- IDE_HFLAG_ABUSE_PREFETCH,
+ IDE_HFLAG_ABUSE_PREFETCH |
+ IDE_HFLAG_SERIALIZE,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = 0x00, /* no udma */
@@ -423,10 +344,9 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .port_ops = &cmd64x_port_ops,
- .dma_ops = &cmd648_dma_ops,
- .host_flags = IDE_HFLAG_SERIALIZE |
- IDE_HFLAG_ABUSE_PREFETCH,
+ .port_ops = &cmd648_port_ops,
+ .host_flags = IDE_HFLAG_ABUSE_PREFETCH |
+ IDE_HFLAG_SERIALIZE,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
@@ -435,8 +355,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .port_ops = &cmd64x_port_ops,
- .dma_ops = &cmd648_dma_ops,
+ .port_ops = &cmd648_port_ops,
.host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
@@ -446,8 +365,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
.name = DRV_NAME,
.init_chipset = init_chipset_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
- .port_ops = &cmd64x_port_ops,
- .dma_ops = &cmd648_dma_ops,
+ .port_ops = &cmd648_port_ops,
.host_flags = IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
@@ -455,7 +373,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
}
};
-static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d;
u8 idx = id->driver_data;
@@ -484,10 +402,9 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic
*/
if (dev->revision < 3) {
d.enablebits[0].reg = 0;
+ d.port_ops = &cmd64x_port_ops;
if (dev->revision == 1)
d.dma_ops = &cmd646_rev1_dma_ops;
- else
- d.dma_ops = &cmd64x_dma_ops;
}
}
}
@@ -526,6 +443,6 @@ static void __exit cmd64x_ide_exit(void)
module_init(cmd64x_ide_init);
module_exit(cmd64x_ide_exit);
-MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick");
+MODULE_AUTHOR("Eddie Dost, David Miller, Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for CMD64x IDE");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index 87987a7d36c..6250aee3050 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -57,11 +57,11 @@ static struct pio_clocks cs5520_pio_clocks[]={
{1, 2, 1}
};
-static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5520_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *pdev = to_pci_dev(hwif->dev);
int controller = drive->dn > 1 ? 1 : 0;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
/* 8bit CAT/CRT - 8bit command timing for channel */
pci_write_config_byte(pdev, 0x62 + controller,
@@ -81,11 +81,12 @@ static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
(cs5520_pio_clocks[pio].assert));
}
-static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void cs5520_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
printk(KERN_ERR "cs55x0: bad ide timing.\n");
- cs5520_set_pio_mode(drive, 0);
+ drive->pio_mode = XFER_PIO_0 + 0;
+ cs5520_set_pio_mode(hwif, drive);
}
static const struct ide_port_ops cs5520_port_ops = {
@@ -93,7 +94,7 @@ static const struct ide_port_ops cs5520_port_ops = {
.set_dma_mode = cs5520_set_dma_mode,
};
-static const struct ide_port_info cyrix_chipset __devinitdata = {
+static const struct ide_port_info cyrix_chipset = {
.name = DRV_NAME,
.enablebits = { { 0x60, 0x01, 0x01 }, { 0x60, 0x02, 0x02 } },
.port_ops = &cs5520_port_ops,
@@ -107,10 +108,10 @@ static const struct ide_port_info cyrix_chipset __devinitdata = {
* work longhand.
*/
-static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct ide_port_info *d = &cyrix_chipset;
- hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
+ struct ide_hw hw[2], *hws[] = { NULL, NULL };
ide_setup_pci_noise(dev, d);
@@ -135,8 +136,9 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
hw[0].irq = 14;
+ hw[1].irq = 15;
- return ide_host_add(d, hws, NULL);
+ return ide_host_add(d, hws, 2, NULL);
}
static const struct pci_device_id cs5520_pci_tbl[] = {
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 40bf05eddf6..65371599b97 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -41,8 +41,8 @@ static unsigned int cs5530_pio_timings[2][5] = {
/**
* cs5530_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Handles setting of PIO mode for the chipset.
*
@@ -50,10 +50,11 @@ static unsigned int cs5530_pio_timings[2][5] = {
* will have valid default PIO timings set up before we get here.
*/
-static void cs5530_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5530_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- unsigned long basereg = CS5530_BASEREG(drive->hwif);
+ unsigned long basereg = CS5530_BASEREG(hwif);
unsigned int format = (inl(basereg + 4) >> 31) & 1;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
outl(cs5530_pio_timings[format][pio], basereg + ((drive->dn & 1)<<3));
}
@@ -99,12 +100,12 @@ out:
return mask;
}
-static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void cs5530_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long basereg;
unsigned int reg, timings = 0;
- switch (mode) {
+ switch (drive->dma_mode) {
case XFER_UDMA_0: timings = 0x00921250; break;
case XFER_UDMA_1: timings = 0x00911140; break;
case XFER_UDMA_2: timings = 0x00911030; break;
@@ -112,7 +113,7 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
case XFER_MW_DMA_1: timings = 0x00012121; break;
case XFER_MW_DMA_2: timings = 0x00002020; break;
}
- basereg = CS5530_BASEREG(drive->hwif);
+ basereg = CS5530_BASEREG(hwif);
reg = inl(basereg + 4); /* get drive0 config register */
timings |= reg & 0x80000000; /* preserve PIO format bit */
if ((drive-> dn & 1) == 0) { /* are we configuring drive0? */
@@ -225,7 +226,7 @@ out:
* performs channel-specific pre-initialization before drive probing.
*/
-static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
+static void init_hwif_cs5530 (ide_hwif_t *hwif)
{
unsigned long basereg;
u32 d0_timings;
@@ -244,7 +245,7 @@ static const struct ide_port_ops cs5530_port_ops = {
.udma_filter = cs5530_udma_filter,
};
-static const struct ide_port_info cs5530_chipset __devinitdata = {
+static const struct ide_port_info cs5530_chipset = {
.name = DRV_NAME,
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
@@ -256,7 +257,7 @@ static const struct ide_port_info cs5530_chipset __devinitdata = {
.udma_mask = ATA_UDMA2,
};
-static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &cs5530_chipset, NULL);
}
diff --git a/drivers/ide/cs5535.c b/drivers/ide/cs5535.c
index 983d957a018..3bc5b9a3401 100644
--- a/drivers/ide/cs5535.c
+++ b/drivers/ide/cs5535.c
@@ -86,7 +86,7 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
cmd = pioa = speed - XFER_PIO_0;
if (pair) {
- u8 piob = ide_get_best_pio_mode(pair, 255, 4);
+ u8 piob = pair->pio_mode - XFER_PIO_0;
if (piob < cmd)
cmd = piob;
@@ -129,28 +129,28 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed)
/**
* cs5535_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Programs the chipset for DMA mode.
*/
-static void cs5535_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void cs5535_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- cs5535_set_speed(drive, speed);
+ cs5535_set_speed(drive, drive->dma_mode);
}
/**
* cs5535_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* A callback from the upper layers for PIO-only tuning.
*/
-static void cs5535_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5535_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- cs5535_set_speed(drive, XFER_PIO_0 + pio);
+ cs5535_set_speed(drive, drive->pio_mode);
}
static u8 cs5535_cable_detect(ide_hwif_t *hwif)
@@ -170,7 +170,7 @@ static const struct ide_port_ops cs5535_port_ops = {
.cable_detect = cs5535_cable_detect,
};
-static const struct ide_port_info cs5535_chipset __devinitdata = {
+static const struct ide_port_info cs5535_chipset = {
.name = DRV_NAME,
.port_ops = &cs5535_port_ops,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE,
@@ -179,14 +179,14 @@ static const struct ide_port_info cs5535_chipset __devinitdata = {
.udma_mask = ATA_UDMA4,
};
-static int __devinit cs5535_init_one(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &cs5535_chipset, NULL);
}
static const struct pci_device_id cs5535_pci_tbl[] = {
{ PCI_VDEVICE(NS, PCI_DEVICE_ID_NS_CS5535_IDE), 0 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5535_IDE), },
{ 0, },
};
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
index 0332a95eefd..de9185db41d 100644
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -125,11 +125,11 @@ static u8 cs5536_cable_detect(ide_hwif_t *hwif)
/**
* cs5536_set_pio_mode - PIO timing setup
+ * @hwif: ATA port
* @drive: ATA device
- * @pio: PIO mode number
*/
-static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cs5536_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 drv_timings[5] = {
0x98, 0x55, 0x32, 0x21, 0x20,
@@ -143,17 +143,20 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
0x99, 0x92, 0x90, 0x22, 0x20,
};
- struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ struct pci_dev *pdev = to_pci_dev(hwif->dev);
ide_drive_t *pair = ide_get_pair_dev(drive);
int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT;
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u32 cast;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 cmd_pio = pio;
if (pair)
- cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
+ cmd_pio = min_t(u8, pio, pair->pio_mode - XFER_PIO_0);
- drive->drive_data &= (IDE_DRV_MASK << 8);
- drive->drive_data |= drv_timings[pio];
+ timings &= (IDE_DRV_MASK << 8);
+ timings |= drv_timings[pio];
+ ide_set_drivedata(drive, (void *)timings);
cs5536_program_dtc(drive, drv_timings[pio]);
@@ -170,11 +173,11 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* cs5536_set_dma_mode - DMA timing setup
+ * @hwif: ATA port
* @drive: ATA device
- * @mode: DMA mode
*/
-static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void cs5536_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 udma_timings[6] = {
0xc2, 0xc1, 0xc0, 0xc4, 0xc5, 0xc6,
@@ -184,9 +187,11 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
0x67, 0x21, 0x20,
};
- struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
+ struct pci_dev *pdev = to_pci_dev(hwif->dev);
int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u32 etc;
+ const u8 mode = drive->dma_mode;
cs5536_read(pdev, ETC, &etc);
@@ -195,8 +200,9 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
etc |= udma_timings[mode - XFER_UDMA_0] << dshift;
} else { /* MWDMA */
etc &= ~(IDE_ETC_UDMA_MASK << dshift);
- drive->drive_data &= IDE_DRV_MASK;
- drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
+ timings &= IDE_DRV_MASK;
+ timings |= mwdma_timings[mode - XFER_MW_DMA_0] << 8;
+ ide_set_drivedata(drive, (void *)timings);
}
cs5536_write(pdev, ETC, etc);
@@ -204,9 +210,11 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void cs5536_dma_start(ide_drive_t *drive)
{
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
+
if (drive->current_speed < XFER_UDMA_0 &&
- (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
- cs5536_program_dtc(drive, drive->drive_data >> 8);
+ (timings >> 8) != (timings & IDE_DRV_MASK))
+ cs5536_program_dtc(drive, timings >> 8);
ide_dma_start(drive);
}
@@ -214,10 +222,11 @@ static void cs5536_dma_start(ide_drive_t *drive)
static int cs5536_dma_end(ide_drive_t *drive)
{
int ret = ide_dma_end(drive);
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
if (drive->current_speed < XFER_UDMA_0 &&
- (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK))
- cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK);
+ (timings >> 8) != (timings & IDE_DRV_MASK))
+ cs5536_program_dtc(drive, timings & IDE_DRV_MASK);
return ret;
}
@@ -286,15 +295,7 @@ static struct pci_driver cs5536_pci_driver = {
.resume = ide_pci_resume,
};
-static int __init cs5536_init(void)
-{
- return pci_register_driver(&cs5536_pci_driver);
-}
-
-static void __exit cs5536_exit(void)
-{
- pci_unregister_driver(&cs5536_pci_driver);
-}
+module_pci_driver(cs5536_pci_driver);
MODULE_AUTHOR("Martin K. Petersen, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller");
@@ -303,6 +304,3 @@ MODULE_DEVICE_TABLE(pci, cs5536_pci_tbl);
module_param_named(msr, use_msr, int, 0644);
MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)");
-
-module_init(cs5536_init);
-module_exit(cs5536_exit);
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index 74fc5401f40..f5820079a28 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -1,43 +1,11 @@
/*
* Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
+ * Copyright (C) 2007-2011 Bartlomiej Zolnierkiewicz
*
* CYPRESS CY82C693 chipset IDE controller
*
* The CY82C693 chipset is used on Digital's PC-Alpha 164SX boards.
- * Writing the driver was quite simple, since most of the job is
- * done by the generic pci-ide support.
- * The hard part was finding the CY82C693's datasheet on Cypress's
- * web page :-(. But Altavista solved this problem :-).
- *
- *
- * Notes:
- * - I recently got a 16.8G IBM DTTA, so I was able to test it with
- * a large and fast disk - the results look great, so I'd say the
- * driver is working fine :-)
- * hdparm -t reports 8.17 MB/sec at about 6% CPU usage for the DTTA
- * - this is my first linux driver, so there's probably a lot of room
- * for optimizations and bug fixing, so feel free to do it.
- * - if using PIO mode it's a good idea to set the PIO mode and
- * 32-bit I/O support (if possible), e.g. hdparm -p2 -c1 /dev/hda
- * - I had some problems with my IBM DHEA with PIO modes < 2
- * (lost interrupts) ?????
- * - first tests with DMA look okay, they seem to work, but there is a
- * problem with sound - the BusMaster IDE TimeOut should fixed this
- *
- * Ancient History:
- * AMH@1999-08-24: v0.34 init_cy82c693_chip moved to pci_init_cy82c693
- * ASK@1999-01-23: v0.33 made a few minor code clean ups
- * removed DMA clock speed setting by default
- * added boot message
- * ASK@1998-11-01: v0.32 added support to set BusMaster IDE TimeOut
- * added support to set DMA Controller Clock Speed
- * ASK@1998-10-31: v0.31 fixed problem with setting to high DMA modes
- * on some drives.
- * ASK@1998-10-29: v0.3 added support to set DMA modes
- * ASK@1998-10-28: v0.2 added support to set PIO modes
- * ASK@1998-10-27: v0.1 first version - chipset detection
- *
*/
#include <linux/module.h>
@@ -51,11 +19,6 @@
#define DRV_NAME "cy82c693"
/*
- * The following are used to debug the driver.
- */
-#define CY82C693_DEBUG_INFO 0
-
-/*
* NOTE: the value for busmaster timeout is tricky and I got it by
* trial and error! By using a to low value will cause DMA timeouts
* and drop IDE performance, and by using a to high value will cause
@@ -86,87 +49,13 @@
#define CY82_INDEX_CHANNEL1 0x31
#define CY82_INDEX_TIMEOUT 0x32
-/* the min and max PCI bus speed in MHz - from datasheet */
-#define CY82C963_MIN_BUS_SPEED 25
-#define CY82C963_MAX_BUS_SPEED 33
-
-/* the struct for the PIO mode timings */
-typedef struct pio_clocks_s {
- u8 address_time; /* Address setup (clocks) */
- u8 time_16r; /* clocks for 16bit IOR (0xF0=Active/data, 0x0F=Recovery) */
- u8 time_16w; /* clocks for 16bit IOW (0xF0=Active/data, 0x0F=Recovery) */
- u8 time_8; /* clocks for 8bit (0xF0=Active/data, 0x0F=Recovery) */
-} pio_clocks_t;
-
-/*
- * calc clocks using bus_speed
- * returns (rounded up) time in bus clocks for time in ns
- */
-static int calc_clk(int time, int bus_speed)
-{
- int clocks;
-
- clocks = (time*bus_speed+999)/1000 - 1;
-
- if (clocks < 0)
- clocks = 0;
-
- if (clocks > 0x0F)
- clocks = 0x0F;
-
- return clocks;
-}
-
-/*
- * compute the values for the clock registers for PIO
- * mode and pci_clk [MHz] speed
- *
- * NOTE: for mode 0,1 and 2 drives 8-bit IDE command control registers are used
- * for mode 3 and 4 drives 8 and 16-bit timings are the same
- *
- */
-static void compute_clocks(u8 pio, pio_clocks_t *p_pclk)
-{
- struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
- int clk1, clk2;
- int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
-
- /* we don't check against CY82C693's min and max speed,
- * so you can play with the idebus=xx parameter
- */
-
- /* let's calc the address setup time clocks */
- p_pclk->address_time = (u8)calc_clk(t->setup, bus_speed);
-
- /* let's calc the active and recovery time clocks */
- clk1 = calc_clk(t->active, bus_speed);
-
- /* calc recovery timing */
- clk2 = t->cycle - t->active - t->setup;
-
- clk2 = calc_clk(clk2, bus_speed);
-
- clk1 = (clk1<<4)|clk2; /* combine active and recovery clocks */
-
- /* note: we use the same values for 16bit IOR and IOW
- * those are all the same, since I don't have other
- * timings than those from ide-lib.c
- */
-
- p_pclk->time_16r = (u8)clk1;
- p_pclk->time_16w = (u8)clk1;
-
- /* what are good values for 8bit ?? */
- p_pclk->time_8 = (u8)clk1;
-}
-
/*
* set DMA mode a specific channel for CY82C693
*/
-static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void cy82c693_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
+ const u8 mode = drive->dma_mode;
u8 single = (mode & 0x10) >> 4, index = 0, data = 0;
index = hwif->channel ? CY82_INDEX_CHANNEL1 : CY82_INDEX_CHANNEL0;
@@ -176,14 +65,9 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
outb(index, CY82_INDEX_PORT);
outb(data, CY82_DATA_PORT);
-#if CY82C693_DEBUG_INFO
- printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
- drive->name, hwif->channel, drive->dn & 1, mode & 3, single);
-#endif /* CY82C693_DEBUG_INFO */
-
/*
* note: below we set the value for Bus Master IDE TimeOut Register
- * I'm not absolutly sure what this does, but it solved my problem
+ * I'm not absolutely sure what this does, but it solved my problem
* with IDE DMA and sound, so I now can play sound and work with
* my IDE driver at the same time :-)
*
@@ -194,22 +78,19 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
data = BUSMASTER_TIMEOUT;
outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
outb(data, CY82_DATA_PORT);
-
-#if CY82C693_DEBUG_INFO
- printk(KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
- drive->name, data);
-#endif /* CY82C693_DEBUG_INFO */
}
-static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
- pio_clocks_t pclk;
+ int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
+ const unsigned long T = 1000000 / bus_speed;
unsigned int addrCtrl;
+ struct ide_timing t;
+ u8 time_16, time_8;
/* select primary or secondary channel */
- if (hwif->index > 0) { /* drive is on the secondary channel */
+ if (drive->dn > 1) { /* drive is on the secondary channel */
dev = pci_get_slot(dev->bus, dev->devfn+1);
if (!dev) {
printk(KERN_ERR "%s: tune_drive: "
@@ -219,8 +100,12 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
}
- /* let's calc the values for this PIO mode */
- compute_clocks(pio, &pclk);
+ ide_timing_compute(drive, drive->pio_mode, &t, T, 1);
+
+ time_16 = clamp_val(t.recover - 1, 0, 15) |
+ (clamp_val(t.active - 1, 0, 15) << 4);
+ time_8 = clamp_val(t.act8b - 1, 0, 15) |
+ (clamp_val(t.rec8b - 1, 0, 15) << 4);
/* now let's write the clocks registers */
if ((drive->dn & 1) == 0) {
@@ -232,15 +117,13 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF);
- addrCtrl |= (unsigned int)pclk.address_time;
+ addrCtrl |= clamp_val(t.setup - 1, 0, 15);
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
- pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, pclk.time_16r);
- pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, pclk.time_16w);
- pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, pclk.time_8);
-
- addrCtrl &= 0xF;
+ pci_write_config_byte(dev, CY82_IDE_MASTER_IOR, time_16);
+ pci_write_config_byte(dev, CY82_IDE_MASTER_IOW, time_16);
+ pci_write_config_byte(dev, CY82_IDE_MASTER_8BIT, time_8);
} else {
/*
* set slave drive
@@ -250,27 +133,19 @@ static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_read_config_dword(dev, CY82_IDE_ADDRSETUP, &addrCtrl);
addrCtrl &= (~0xF0);
- addrCtrl |= ((unsigned int)pclk.address_time<<4);
+ addrCtrl |= (clamp_val(t.setup - 1, 0, 15) << 4);
pci_write_config_dword(dev, CY82_IDE_ADDRSETUP, addrCtrl);
/* now let's set the remaining registers */
- pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, pclk.time_16r);
- pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, pclk.time_16w);
- pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, pclk.time_8);
-
- addrCtrl >>= 4;
- addrCtrl &= 0xF;
+ pci_write_config_byte(dev, CY82_IDE_SLAVE_IOR, time_16);
+ pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16);
+ pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8);
}
-
-#if CY82C693_DEBUG_INFO
- printk(KERN_INFO "%s (ch=%d, dev=%d): set PIO timing to "
- "(addr=0x%X, ior=0x%X, iow=0x%X, 8bit=0x%X)\n",
- drive->name, hwif->channel, drive->dn & 1,
- addrCtrl, pclk.time_16r, pclk.time_16w, pclk.time_8);
-#endif /* CY82C693_DEBUG_INFO */
+ if (drive->dn > 1)
+ pci_dev_put(dev);
}
-static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
+static void init_iops_cy82c693(ide_hwif_t *hwif)
{
static ide_hwif_t *primary;
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -288,7 +163,7 @@ static const struct ide_port_ops cy82c693_port_ops = {
.set_dma_mode = cy82c693_set_dma_mode,
};
-static const struct ide_port_info cy82c693_chipset __devinitdata = {
+static const struct ide_port_info cy82c693_chipset = {
.name = DRV_NAME,
.init_iops = init_iops_cy82c693,
.port_ops = &cy82c693_port_ops,
@@ -298,7 +173,8 @@ static const struct ide_port_info cy82c693_chipset __devinitdata = {
.mwdma_mask = ATA_MWDMA2,
};
-static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int cy82c693_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
struct pci_dev *dev2;
int ret = -ENODEV;
@@ -315,7 +191,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
return ret;
}
-static void __devexit cy82c693_remove(struct pci_dev *dev)
+static void cy82c693_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL;
@@ -334,7 +210,7 @@ static struct pci_driver cy82c693_pci_driver = {
.name = "Cypress_IDE",
.id_table = cy82c693_pci_tbl,
.probe = cy82c693_init_one,
- .remove = __devexit_p(cy82c693_remove),
+ .remove = cy82c693_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
@@ -352,6 +228,6 @@ static void __exit cy82c693_ide_exit(void)
module_init(cy82c693_ide_init);
module_exit(cy82c693_ide_exit);
-MODULE_AUTHOR("Andreas Krebs, Andre Hedrick");
+MODULE_AUTHOR("Andreas Krebs, Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for the Cypress CY82C693 IDE");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c
index f153b95619b..300daabaa57 100644
--- a/drivers/ide/delkin_cb.c
+++ b/drivers/ide/delkin_cb.c
@@ -68,15 +68,15 @@ static const struct ide_port_info delkin_cb_port_info = {
IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
.init_chipset = delkin_cb_init_chipset,
+ .chipset = ide_pci,
};
-static int __devinit
-delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
+static int delkin_cb_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_host *host;
unsigned long base;
int rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
rc = pci_enable_device(dev);
if (rc) {
@@ -97,9 +97,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
hw.irq = dev->irq;
hw.dev = &dev->dev;
- hw.chipset = ide_pci; /* this enables IRQ sharing */
- rc = ide_host_add(&delkin_cb_port_info, hws, &host);
+ rc = ide_host_add(&delkin_cb_port_info, hws, 1, &host);
if (rc)
goto out_disable;
@@ -158,7 +157,7 @@ static int delkin_cb_resume(struct pci_dev *dev)
#define delkin_cb_resume NULL
#endif
-static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = {
+static struct pci_device_id delkin_cb_pci_tbl[] = {
{ 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0, },
@@ -174,18 +173,7 @@ static struct pci_driver delkin_cb_pci_driver = {
.resume = delkin_cb_resume,
};
-static int __init delkin_cb_init(void)
-{
- return pci_register_driver(&delkin_cb_pci_driver);
-}
-
-static void __exit delkin_cb_exit(void)
-{
- pci_unregister_driver(&delkin_cb_pci_driver);
-}
-
-module_init(delkin_cb_init);
-module_exit(delkin_cb_exit);
+module_pci_driver(delkin_cb_pci_driver);
MODULE_AUTHOR("Mark Lord");
MODULE_DESCRIPTION("Basic support for Delkin/ASKA/Workbit Cardbus IDE");
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index c6b13812298..8722df329cb 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -68,11 +68,11 @@ static void sub22 (char b, char c)
static DEFINE_SPINLOCK(dtc2278_lock);
-static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void dtc2278_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned long flags;
- if (pio >= 3) {
+ if (drive->pio_mode >= XFER_PIO_3) {
spin_lock_irqsave(&dtc2278_lock, flags);
/*
* This enables PIO mode4 (3?) on the first interface
@@ -91,7 +91,7 @@ static const struct ide_port_ops dtc2278_port_ops = {
.set_pio_mode = dtc2278_set_pio_mode,
};
-static const struct ide_port_info dtc2278_port_info __initdata = {
+static const struct ide_port_info dtc2278_port_info __initconst = {
.name = DRV_NAME,
.chipset = ide_dtc2278,
.port_ops = &dtc2278_port_ops,
@@ -130,7 +130,7 @@ static int __init dtc2278_probe(void)
return ide_legacy_device_add(&dtc2278_port_info, 0);
}
-static int probe_dtc2278;
+static bool probe_dtc2278;
module_param_named(probe, probe_dtc2278, bool, 0);
MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index 0e2df6755ec..a5a07ccb81a 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -111,9 +111,10 @@ static const struct ide_port_info falconide_port_info = {
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
+ .chipset = ide_generic,
};
-static void __init falconide_setup_ports(hw_regs_t *hw)
+static void __init falconide_setup_ports(struct ide_hw *hw)
{
int i;
@@ -127,9 +128,6 @@ static void __init falconide_setup_ports(hw_regs_t *hw)
hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL;
hw->irq = IRQ_MFP_IDE;
- hw->ack_intr = NULL;
-
- hw->chipset = ide_generic;
}
/*
@@ -139,7 +137,7 @@ static void __init falconide_setup_ports(hw_regs_t *hw)
static int __init falconide_init(void)
{
struct ide_host *host;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
int rc;
if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE))
@@ -154,7 +152,7 @@ static int __init falconide_init(void)
falconide_setup_ports(&hw);
- host = ide_host_alloc(&falconide_port_info, hws);
+ host = ide_host_alloc(&falconide_port_info, hws, 1);
if (host == NULL) {
rc = -ENOMEM;
goto err;
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index c7119516c5a..97a2f9dc75d 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -16,6 +16,7 @@
#include <linux/init.h>
#include <linux/zorro.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
@@ -24,15 +25,6 @@
/*
- * Bases of the IDE interfaces
- */
-
-#define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */
-#define GAYLE_BASE_1200 0xda0000 /* A1200/A600 and E-Matrix 530 */
-
-#define GAYLE_IDEREG_SIZE 0x2000
-
- /*
* Offsets from one of the above bases
*/
@@ -58,7 +50,7 @@
GAYLE_NUM_HWIFS-1)
#define GAYLE_HAS_CONTROL_REG (!ide_doubler)
-static int ide_doubler;
+static bool ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
@@ -66,31 +58,26 @@ MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
* Check and acknowledge the interrupt status
*/
-static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
+static int gayle_test_irq(ide_hwif_t *hwif)
{
- unsigned char ch;
+ unsigned char ch;
- ch = z_readb(hwif->io_ports.irq_addr);
- if (!(ch & GAYLE_IRQ_IDE))
- return 0;
- return 1;
+ ch = z_readb(hwif->io_ports.irq_addr);
+ if (!(ch & GAYLE_IRQ_IDE))
+ return 0;
+ return 1;
}
-static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
+static void gayle_a1200_clear_irq(ide_drive_t *drive)
{
- unsigned char ch;
+ ide_hwif_t *hwif = drive->hwif;
- ch = z_readb(hwif->io_ports.irq_addr);
- if (!(ch & GAYLE_IRQ_IDE))
- return 0;
- (void)z_readb(hwif->io_ports.status_addr);
- z_writeb(0x7c, hwif->io_ports.irq_addr);
- return 1;
+ (void)z_readb(hwif->io_ports.status_addr);
+ z_writeb(0x7c, hwif->io_ports.irq_addr);
}
-static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
- unsigned long ctl, unsigned long irq_port,
- ide_ack_intr_t *ack_intr)
+static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base,
+ unsigned long ctl, unsigned long irq_port)
{
int i;
@@ -105,79 +92,98 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
- hw->ack_intr = ack_intr;
-
- hw->chipset = ide_generic;
}
+static const struct ide_port_ops gayle_a4000_port_ops = {
+ .test_irq = gayle_test_irq,
+};
+
+static const struct ide_port_ops gayle_a1200_port_ops = {
+ .clear_irq = gayle_a1200_clear_irq,
+ .test_irq = gayle_test_irq,
+};
+
static const struct ide_port_info gayle_port_info = {
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
+ .chipset = ide_generic,
};
/*
* Probe for a Gayle IDE interface (and optionally for an IDE doubler)
*/
-static int __init gayle_init(void)
+static int __init amiga_gayle_ide_probe(struct platform_device *pdev)
{
- unsigned long phys_base, res_start, res_n;
- unsigned long base, ctrlport, irqport;
- ide_ack_intr_t *ack_intr;
- int a4000, i, rc;
- hw_regs_t hw[GAYLE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
-
- if (!MACH_IS_AMIGA)
- return -ENODEV;
-
- if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE))
- goto found;
-
-#ifdef CONFIG_ZORRO
- if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE,
- NULL))
- goto found;
-#endif
- return -ENODEV;
-
-found:
- printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
- a4000 ? 4000 : 1200,
- ide_doubler ? ", IDE doubler" : "");
-
- if (a4000) {
- phys_base = GAYLE_BASE_4000;
- irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000);
- ack_intr = gayle_ack_intr_a4000;
- } else {
- phys_base = GAYLE_BASE_1200;
- irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
- ack_intr = gayle_ack_intr_a1200;
- }
-
- res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
- res_n = GAYLE_IDEREG_SIZE;
-
- if (!request_mem_region(res_start, res_n, "IDE"))
+ struct resource *res;
+ struct gayle_ide_platform_data *pdata;
+ unsigned long base, ctrlport, irqport;
+ unsigned int i;
+ int error;
+ struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS];
+ struct ide_port_info d = gayle_port_info;
+ struct ide_host *host;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ if (!request_mem_region(res->start, resource_size(res), "IDE"))
return -EBUSY;
- for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
- base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT);
- ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
+ pdata = dev_get_platdata(&pdev->dev);
+ pr_info("ide: Gayle IDE controller (A%u style%s)\n",
+ pdata->explicit_ack ? 1200 : 4000,
+ ide_doubler ? ", IDE doubler" : "");
+
+ base = (unsigned long)ZTWO_VADDR(pdata->base);
+ ctrlport = 0;
+ irqport = (unsigned long)ZTWO_VADDR(pdata->irqport);
+ if (pdata->explicit_ack)
+ d.port_ops = &gayle_a1200_port_ops;
+ else
+ d.port_ops = &gayle_a4000_port_ops;
+
+ for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++, base += GAYLE_NEXT_PORT) {
+ if (GAYLE_HAS_CONTROL_REG)
+ ctrlport = base + GAYLE_CONTROL;
+
+ gayle_setup_ports(&hw[i], base, ctrlport, irqport);
+ hws[i] = &hw[i];
+ }
- gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr);
+ error = ide_host_add(&d, hws, i, &host);
+ if (error)
+ goto out;
- hws[i] = &hw[i];
- }
+ platform_set_drvdata(pdev, host);
+ return 0;
- rc = ide_host_add(&gayle_port_info, hws, NULL);
- if (rc)
- release_mem_region(res_start, res_n);
+out:
+ release_mem_region(res->start, resource_size(res));
+ return error;
+}
- return rc;
+static int __exit amiga_gayle_ide_remove(struct platform_device *pdev)
+{
+ struct ide_host *host = platform_get_drvdata(pdev);
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ ide_host_remove(host);
+ release_mem_region(res->start, resource_size(res));
+ return 0;
}
-module_init(gayle_init);
+static struct platform_driver amiga_gayle_ide_driver = {
+ .remove = __exit_p(amiga_gayle_ide_remove),
+ .driver = {
+ .name = "amiga-gayle-ide",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver_probe(amiga_gayle_ide_driver, amiga_gayle_ide_probe);
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:amiga-gayle-ide");
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index 0feb66c720e..696b6c1ec94 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -12,7 +12,7 @@
*
*
* HighPoint has its own drivers (open source except for the RAID part)
- * available from http://www.highpoint-tech.com/BIOS%20+%20Driver/.
+ * available from http://www.highpoint-tech.com/USA_new/service_support.htm
* This may be useful to anyone wanting to work on this driver, however do not
* trust them too much since the code tends to become less and less meaningful
* as the time passes... :-/
@@ -128,6 +128,7 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
+#include <linux/slab.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -138,14 +139,6 @@
#undef HPT_RESET_STATE_ENGINE
#undef HPT_DELAY_INTERRUPT
-static const char *quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
static const char *bad_ata100_5[] = {
"IBM-DTLA-307075",
"IBM-DTLA-307060",
@@ -305,68 +298,6 @@ static u32 twenty_five_base_hpt36x[] = {
/* XFER_PIO_0 */ 0xc0d08585
};
-#if 0
-/* These are the timing tables from the HighPoint open source drivers... */
-static u32 thirty_three_base_hpt37x[] = {
- /* XFER_UDMA_6 */ 0x12446231, /* 0x12646231 ?? */
- /* XFER_UDMA_5 */ 0x12446231,
- /* XFER_UDMA_4 */ 0x12446231,
- /* XFER_UDMA_3 */ 0x126c6231,
- /* XFER_UDMA_2 */ 0x12486231,
- /* XFER_UDMA_1 */ 0x124c6233,
- /* XFER_UDMA_0 */ 0x12506297,
-
- /* XFER_MW_DMA_2 */ 0x22406c31,
- /* XFER_MW_DMA_1 */ 0x22406c33,
- /* XFER_MW_DMA_0 */ 0x22406c97,
-
- /* XFER_PIO_4 */ 0x06414e31,
- /* XFER_PIO_3 */ 0x06414e42,
- /* XFER_PIO_2 */ 0x06414e53,
- /* XFER_PIO_1 */ 0x06814e93,
- /* XFER_PIO_0 */ 0x06814ea7
-};
-
-static u32 fifty_base_hpt37x[] = {
- /* XFER_UDMA_6 */ 0x12848242,
- /* XFER_UDMA_5 */ 0x12848242,
- /* XFER_UDMA_4 */ 0x12ac8242,
- /* XFER_UDMA_3 */ 0x128c8242,
- /* XFER_UDMA_2 */ 0x120c8242,
- /* XFER_UDMA_1 */ 0x12148254,
- /* XFER_UDMA_0 */ 0x121882ea,
-
- /* XFER_MW_DMA_2 */ 0x22808242,
- /* XFER_MW_DMA_1 */ 0x22808254,
- /* XFER_MW_DMA_0 */ 0x228082ea,
-
- /* XFER_PIO_4 */ 0x0a81f442,
- /* XFER_PIO_3 */ 0x0a81f443,
- /* XFER_PIO_2 */ 0x0a81f454,
- /* XFER_PIO_1 */ 0x0ac1f465,
- /* XFER_PIO_0 */ 0x0ac1f48a
-};
-
-static u32 sixty_six_base_hpt37x[] = {
- /* XFER_UDMA_6 */ 0x1c869c62,
- /* XFER_UDMA_5 */ 0x1cae9c62, /* 0x1c8a9c62 */
- /* XFER_UDMA_4 */ 0x1c8a9c62,
- /* XFER_UDMA_3 */ 0x1c8e9c62,
- /* XFER_UDMA_2 */ 0x1c929c62,
- /* XFER_UDMA_1 */ 0x1c9a9c62,
- /* XFER_UDMA_0 */ 0x1c829c62,
-
- /* XFER_MW_DMA_2 */ 0x2c829c62,
- /* XFER_MW_DMA_1 */ 0x2c829c66,
- /* XFER_MW_DMA_0 */ 0x2c829d2e,
-
- /* XFER_PIO_4 */ 0x0c829c62,
- /* XFER_PIO_3 */ 0x0c829c84,
- /* XFER_PIO_2 */ 0x0c829ca6,
- /* XFER_PIO_1 */ 0x0d029d26,
- /* XFER_PIO_0 */ 0x0d029d5e
-};
-#else
/*
* The following are the new timing tables with PIO mode data/taskfile transfer
* overclocking fixed...
@@ -432,16 +363,13 @@ static u32 sixty_six_base_hpt37x[] = {
/* XFER_PIO_1 */ 0x0d02ff26,
/* XFER_PIO_0 */ 0x0d42ff7f
};
-#endif
-#define HPT366_DEBUG_DRIVE_INFO 0
#define HPT371_ALLOW_ATA133_6 1
#define HPT302_ALLOW_ATA133_6 1
#define HPT372_ALLOW_ATA133_6 1
#define HPT370_ALLOW_ATA100_5 0
#define HPT366_ALLOW_ATA66_4 1
#define HPT366_ALLOW_ATA66_3 1
-#define HPT366_MAX_DEVS 8
/* Supported ATA clock frequencies */
enum ata_clock {
@@ -515,7 +443,7 @@ static struct hpt_timings hpt37x_timings = {
}
};
-static const struct hpt_info hpt36x __devinitdata = {
+static const struct hpt_info hpt36x = {
.chip_name = "HPT36x",
.chip_type = HPT36x,
.udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
@@ -523,7 +451,7 @@ static const struct hpt_info hpt36x __devinitdata = {
.timings = &hpt36x_timings
};
-static const struct hpt_info hpt370 __devinitdata = {
+static const struct hpt_info hpt370 = {
.chip_name = "HPT370",
.chip_type = HPT370,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -531,7 +459,7 @@ static const struct hpt_info hpt370 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt370a __devinitdata = {
+static const struct hpt_info hpt370a = {
.chip_name = "HPT370A",
.chip_type = HPT370A,
.udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -539,7 +467,7 @@ static const struct hpt_info hpt370a __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt374 __devinitdata = {
+static const struct hpt_info hpt374 = {
.chip_name = "HPT374",
.chip_type = HPT374,
.udma_mask = ATA_UDMA5,
@@ -547,7 +475,7 @@ static const struct hpt_info hpt374 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372 __devinitdata = {
+static const struct hpt_info hpt372 = {
.chip_name = "HPT372",
.chip_type = HPT372,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -555,7 +483,7 @@ static const struct hpt_info hpt372 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372a __devinitdata = {
+static const struct hpt_info hpt372a = {
.chip_name = "HPT372A",
.chip_type = HPT372A,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -563,7 +491,7 @@ static const struct hpt_info hpt372a __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt302 __devinitdata = {
+static const struct hpt_info hpt302 = {
.chip_name = "HPT302",
.chip_type = HPT302,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -571,7 +499,7 @@ static const struct hpt_info hpt302 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt371 __devinitdata = {
+static const struct hpt_info hpt371 = {
.chip_name = "HPT371",
.chip_type = HPT371,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -579,7 +507,7 @@ static const struct hpt_info hpt371 __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt372n __devinitdata = {
+static const struct hpt_info hpt372n = {
.chip_name = "HPT372N",
.chip_type = HPT372N,
.udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -587,7 +515,7 @@ static const struct hpt_info hpt372n __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt302n __devinitdata = {
+static const struct hpt_info hpt302n = {
.chip_name = "HPT302N",
.chip_type = HPT302N,
.udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -595,7 +523,7 @@ static const struct hpt_info hpt302n __devinitdata = {
.timings = &hpt37x_timings
};
-static const struct hpt_info hpt371n __devinitdata = {
+static const struct hpt_info hpt371n = {
.chip_name = "HPT371N",
.chip_type = HPT371N,
.udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -700,14 +628,14 @@ static u32 get_speed_setting(u8 speed, struct hpt_info *info)
return info->timings->clock_table[info->clock][i];
}
-static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
+static void hpt3xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
struct hpt_timings *t = info->timings;
u8 itr_addr = 0x40 + (drive->dn * 4);
u32 old_itr = 0;
+ const u8 speed = drive->dma_mode;
u32 new_itr = get_speed_setting(speed, info);
u32 itr_mask = speed < XFER_MW_DMA_0 ? t->pio_mask :
(speed < XFER_UDMA_0 ? t->dma_mask :
@@ -724,23 +652,10 @@ static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_dword(dev, itr_addr, new_itr);
}
-static void hpt3xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- hpt3xx_set_mode(drive, XFER_PIO_0 + pio);
-}
-
-static void hpt3xx_quirkproc(ide_drive_t *drive)
+static void hpt3xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- char *m = (char *)&drive->id[ATA_ID_PROD];
- const char **list = quirk_drives;
-
- while (*list)
- if (strstr(m, *list++)) {
- drive->quirk_list = 1;
- return;
- }
-
- drive->quirk_list = 0;
+ drive->dma_mode = drive->pio_mode;
+ hpt3xx_set_mode(hwif, drive);
}
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
@@ -749,7 +664,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
- if (drive->quirk_list == 0)
+ if ((drive->dev_flags & IDE_DFLAG_NIEN_QUIRK) == 0)
return;
if (info->chip_type >= HPT370) {
@@ -923,7 +838,7 @@ static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode)
static void hpt3xxn_rw_disk(ide_drive_t *drive, struct request *rq)
{
- hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x23 : 0x21);
+ hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x21 : 0x23);
}
/**
@@ -1258,8 +1173,9 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
u16 mcr;
pci_read_config_word(dev, mcr_addr, &mcr);
- pci_write_config_word(dev, mcr_addr, (mcr | 0x8000));
- /* now read cable id register */
+ pci_write_config_word(dev, mcr_addr, mcr | 0x8000);
+ /* Debounce, then read cable ID register */
+ udelay(10);
pci_read_config_byte(dev, 0x5a, &scr1);
pci_write_config_word(dev, mcr_addr, mcr);
} else if (chip_type >= HPT370) {
@@ -1270,17 +1186,18 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
u8 scr2 = 0;
pci_read_config_byte(dev, 0x5b, &scr2);
- pci_write_config_byte(dev, 0x5b, (scr2 & ~1));
- /* now read cable id register */
+ pci_write_config_byte(dev, 0x5b, scr2 & ~1);
+ /* Debounce, then read cable ID register */
+ udelay(10);
pci_read_config_byte(dev, 0x5a, &scr1);
- pci_write_config_byte(dev, 0x5b, scr2);
+ pci_write_config_byte(dev, 0x5b, scr2);
} else
pci_read_config_byte(dev, 0x5a, &scr1);
return (scr1 & ata66) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
+static void init_hwif_hpt366(ide_hwif_t *hwif)
{
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
u8 chip_type = info->chip_type;
@@ -1304,7 +1221,7 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
}
}
-static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
+static int init_dma_hpt366(ide_hwif_t *hwif,
const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -1348,7 +1265,7 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
return 0;
}
-static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
+static void hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
{
if (dev2->irq != dev->irq) {
/* FIXME: we need a core pci_set_interrupt() */
@@ -1358,7 +1275,7 @@ static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2)
}
}
-static void __devinit hpt371_init(struct pci_dev *dev)
+static void hpt371_init(struct pci_dev *dev)
{
u8 mcr1 = 0;
@@ -1373,7 +1290,7 @@ static void __devinit hpt371_init(struct pci_dev *dev)
pci_write_config_byte(dev, 0x50, mcr1 & ~0x04);
}
-static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
+static int hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
{
u8 mcr1 = 0, pin1 = 0, pin2 = 0;
@@ -1404,7 +1321,6 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
static const struct ide_port_ops hpt3xx_port_ops = {
.set_pio_mode = hpt3xx_set_pio_mode,
.set_dma_mode = hpt3xx_set_mode,
- .quirkproc = hpt3xx_quirkproc,
.maskproc = hpt3xx_maskproc,
.mdma_filter = hpt3xx_mdma_filter,
.udma_filter = hpt3xx_udma_filter,
@@ -1445,7 +1361,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
+static const struct ide_port_info hpt366_chipsets[] = {
{ /* 0: HPT36x */
.name = DRV_NAME,
.init_chipset = init_chipset_hpt366,
@@ -1486,7 +1402,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
*/
-static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct hpt_info *info = NULL;
struct hpt_info *dyn_info;
@@ -1583,7 +1499,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
return ret;
}
-static void __devexit hpt366_remove(struct pci_dev *dev)
+static void hpt366_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct ide_info *info = host->host_priv;
@@ -1594,7 +1510,7 @@ static void __devexit hpt366_remove(struct pci_dev *dev)
kfree(info);
}
-static const struct pci_device_id hpt366_pci_tbl[] __devinitconst = {
+static const struct pci_device_id hpt366_pci_tbl[] = {
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), 0 },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), 1 },
{ PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), 2 },
@@ -1609,7 +1525,7 @@ static struct pci_driver hpt366_pci_driver = {
.name = "HPT366_IDE",
.id_table = hpt366_pci_tbl,
.probe = hpt366_init_one,
- .remove = __devexit_p(hpt366_remove),
+ .remove = hpt366_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index 2fb0f296500..1e0fd3aa962 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -10,7 +10,6 @@
* Author: Mikko Ala-Fossi <maf@iki.fi>
* Jan Evert van Grootheest <j.e.van.grootheest@caiway.nl>
*
- * Try: http://www.maf.iki.fi/~maf/ht6560b/
*/
#define DRV_NAME "ht6560b"
@@ -44,7 +43,12 @@
* bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?)
*/
#define HT_CONFIG_PORT 0x3e6
-#define HT_CONFIG(drivea) (u8)(((drivea)->drive_data & 0xff00) >> 8)
+
+static inline u8 HT_CONFIG(ide_drive_t *drive)
+{
+ return ((unsigned long)ide_get_drivedata(drive) & 0xff00) >> 8;
+}
+
/*
* FIFO + PREFETCH (both a/b-model)
*/
@@ -90,7 +94,11 @@
* Active Time for each drive. Smaller value gives higher speed.
* In case of failures you should probably fall back to a higher value.
*/
-#define HT_TIMING(drivea) (u8)((drivea)->drive_data & 0x00ff)
+static inline u8 HT_TIMING(ide_drive_t *drive)
+{
+ return (unsigned long)ide_get_drivedata(drive) & 0x00ff;
+}
+
#define HT_TIMING_DEFAULT 0xff
/*
@@ -242,23 +250,27 @@ static DEFINE_SPINLOCK(ht6560b_lock);
*/
static void ht_set_prefetch(ide_drive_t *drive, u8 state)
{
- unsigned long flags;
+ unsigned long flags, config;
int t = HT_PREFETCH_MODE << 8;
spin_lock_irqsave(&ht6560b_lock, flags);
+ config = (unsigned long)ide_get_drivedata(drive);
+
/*
* Prefetch mode and unmask irq seems to conflict
*/
if (state) {
- drive->drive_data |= t; /* enable prefetch mode */
+ config |= t; /* enable prefetch mode */
drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
drive->dev_flags &= ~IDE_DFLAG_UNMASK;
} else {
- drive->drive_data &= ~t; /* disable prefetch mode */
+ config &= ~t; /* disable prefetch mode */
drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK;
}
+ ide_set_drivedata(drive, (void *)config);
+
spin_unlock_irqrestore(&ht6560b_lock, flags);
#ifdef DEBUG
@@ -266,9 +278,10 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
#endif
}
-static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void ht6560b_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- unsigned long flags;
+ unsigned long flags, config;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 timing;
switch (pio) {
@@ -281,8 +294,10 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
timing = ht_pio2timings(drive, pio);
spin_lock_irqsave(&ht6560b_lock, flags);
- drive->drive_data &= 0xff00;
- drive->drive_data |= timing;
+ config = (unsigned long)ide_get_drivedata(drive);
+ config &= 0xff00;
+ config |= timing;
+ ide_set_drivedata(drive, (void *)config);
spin_unlock_irqrestore(&ht6560b_lock, flags);
#ifdef DEBUG
@@ -299,10 +314,10 @@ static void __init ht6560b_init_dev(ide_drive_t *drive)
if (hwif->channel)
t |= (HT_SECONDARY_IF << 8);
- drive->drive_data = t;
+ ide_set_drivedata(drive, (void *)t);
}
-static int probe_ht6560b;
+static bool probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
@@ -326,7 +341,7 @@ static const struct ide_port_ops ht6560b_port_ops = {
.set_pio_mode = ht6560b_set_pio_mode,
};
-static const struct ide_port_info ht6560b_port_info __initdata = {
+static const struct ide_port_info ht6560b_port_info __initconst = {
.name = DRV_NAME,
.chipset = ide_ht6560b,
.tp_ops = &ht6560b_tp_ops,
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 4e16ce68b06..9f0a48e39b8 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -234,9 +234,11 @@ static const struct ide_port_ops icside_v6_no_dma_port_ops = {
* MW1 80 50 50 150 C
* MW2 70 25 25 120 C
*/
-static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
+static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- int cycle_time, use_dma_info = 0;
+ unsigned long cycle_time = 0;
+ int use_dma_info = 0;
+ const u8 xfer_mode = drive->dma_mode;
switch (xfer_mode) {
case XFER_MW_DMA_2:
@@ -267,10 +269,11 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
if (use_dma_info && drive->id[ATA_ID_EIDE_DMA_TIME] > cycle_time)
cycle_time = drive->id[ATA_ID_EIDE_DMA_TIME];
- drive->drive_data = cycle_time;
+ ide_set_drivedata(drive, (void *)cycle_time);
- printk("%s: %s selected (peak %dMB/s)\n", drive->name,
- ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
+ printk(KERN_INFO "%s: %s selected (peak %luMB/s)\n",
+ drive->name, ide_xfer_verbose(xfer_mode),
+ 2000 / (cycle_time ? cycle_time : (unsigned long) -1));
}
static const struct ide_port_ops icside_v6_port_ops = {
@@ -332,7 +335,7 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/*
* Select the correct timing for this drive.
*/
- set_dma_speed(ec->dma, drive->drive_data);
+ set_dma_speed(ec->dma, (unsigned long)ide_get_drivedata(drive));
/*
* Tell the DMA engine about the SG table and
@@ -372,8 +375,6 @@ static const struct ide_dma_ops icside_v6_dma_ops = {
.dma_test_irq = icside_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
};
-#else
-#define icside_v6_dma_ops NULL
#endif
static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d)
@@ -381,7 +382,7 @@ static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d)
return -EOPNOTSUPP;
}
-static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
+static void icside_setup_ports(struct ide_hw *hw, void __iomem *base,
struct cardinfo *info, struct expansion_card *ec)
{
unsigned long port = (unsigned long)base + info->dataoffset;
@@ -398,19 +399,19 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
hw->irq = ec->irq;
hw->dev = &ec->dev;
- hw->chipset = ide_acorn;
}
static const struct ide_port_info icside_v5_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
+ .chipset = ide_acorn,
};
-static int __devinit
-icside_register_v5(struct icside_state *state, struct expansion_card *ec)
+static int icside_register_v5(struct icside_state *state,
+ struct expansion_card *ec)
{
void __iomem *base;
struct ide_host *host;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
int ret;
base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
@@ -431,7 +432,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
- host = ide_host_alloc(&icside_v5_port_info, hws);
+ host = ide_host_alloc(&icside_v5_port_info, hws, 1);
if (host == NULL)
return -ENODEV;
@@ -450,23 +451,23 @@ err_free:
return ret;
}
-static const struct ide_port_info icside_v6_port_info __initdata = {
+static const struct ide_port_info icside_v6_port_info __initconst = {
.init_dma = icside_dma_off_init,
.port_ops = &icside_v6_no_dma_port_ops,
- .dma_ops = &icside_v6_dma_ops,
.host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
.mwdma_mask = ATA_MWDMA2,
.swdma_mask = ATA_SWDMA2,
+ .chipset = ide_acorn,
};
-static int __devinit
-icside_register_v6(struct icside_state *state, struct expansion_card *ec)
+static int icside_register_v6(struct icside_state *state,
+ struct expansion_card *ec)
{
void __iomem *ioc_base, *easi_base;
struct ide_host *host;
unsigned int sel = 0;
int ret;
- hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL };
+ struct ide_hw hw[2], *hws[] = { &hw[0], &hw[1] };
struct ide_port_info d = icside_v6_port_info;
ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
@@ -506,7 +507,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec);
icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec);
- host = ide_host_alloc(&d, hws);
+ host = ide_host_alloc(&d, hws, 2);
if (host == NULL)
return -ENODEV;
@@ -514,11 +515,13 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
ecard_set_drvdata(ec, state);
+#ifdef CONFIG_BLK_DEV_IDEDMA_ICS
if (ec->dma != NO_DMA && !request_dma(ec->dma, DRV_NAME)) {
d.init_dma = icside_dma_init;
d.port_ops = &icside_v6_port_ops;
- d.dma_ops = NULL;
+ d.dma_ops = &icside_v6_dma_ops;
}
+#endif
ret = ide_host_register(host, &d, hws);
if (ret)
@@ -534,8 +537,7 @@ out:
return ret;
}
-static int __devinit
-icside_probe(struct expansion_card *ec, const struct ecard_id *id)
+static int icside_probe(struct expansion_card *ec, const struct ecard_id *id)
{
struct icside_state *state;
void __iomem *idmem;
@@ -601,7 +603,7 @@ icside_probe(struct expansion_card *ec, const struct ecard_id *id)
return ret;
}
-static void __devexit icside_remove(struct expansion_card *ec)
+static void icside_remove(struct expansion_card *ec)
{
struct icside_state *state = ecard_get_drvdata(ec);
@@ -663,7 +665,7 @@ static const struct ecard_id icside_ids[] = {
static struct ecard_driver icside_driver = {
.probe = icside_probe,
- .remove = __devexit_p(icside_remove),
+ .remove = icside_remove,
.shutdown = icside_shutdown,
.id_table = icside_ids,
.drv = {
diff --git a/drivers/ide/ide-4drives.c b/drivers/ide/ide-4drives.c
index 78aca75a2c4..547d7cf2e01 100644
--- a/drivers/ide/ide-4drives.c
+++ b/drivers/ide/ide-4drives.c
@@ -6,7 +6,7 @@
#define DRV_NAME "ide-4drives"
-static int probe_4drives;
+static bool probe_4drives;
module_param_named(probe, probe_4drives, bool, 0);
MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
@@ -25,12 +25,13 @@ static const struct ide_port_info ide_4drives_port_info = {
.port_ops = &ide_4drives_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA |
IDE_HFLAG_4DRIVES,
+ .chipset = ide_4drives,
};
static int __init ide_4drives_init(void)
{
unsigned long base = 0x1f0, ctl = 0x3f6;
- hw_regs_t hw, *hws[] = { &hw, &hw, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw, &hw };
if (probe_4drives == 0)
return -ENODEV;
@@ -52,9 +53,8 @@ static int __init ide_4drives_init(void)
ide_std_init_ports(&hw, base, ctl);
hw.irq = 14;
- hw.chipset = ide_4drives;
- return ide_host_add(&ide_4drives_port_info, hws, NULL);
+ return ide_host_add(&ide_4drives_port_info, hws, 2, NULL);
}
module_init(ide_4drives_init);
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 77f79d26b26..b6940992a6f 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -7,17 +7,17 @@
* Copyright (C) 2006 Hannes Reinecke
*/
+#include <linux/acpi.h>
#include <linux/ata.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <acpi/acpi.h>
+#include <linux/slab.h>
#include <linux/ide.h>
#include <linux/pci.h>
#include <linux/dmi.h>
-
-#include <acpi/acpi_bus.h>
+#include <linux/module.h>
#define REGS_PER_GTF 7
@@ -51,15 +51,15 @@ struct ide_acpi_hwif_link {
#define DEBPRINT(fmt, args...) do {} while (0)
#endif /* DEBUGGING */
-static int ide_noacpi;
+static bool ide_noacpi;
module_param_named(noacpi, ide_noacpi, bool, 0);
MODULE_PARM_DESC(noacpi, "disable IDE ACPI support");
-static int ide_acpigtf;
+static bool ide_acpigtf;
module_param_named(acpigtf, ide_acpigtf, bool, 0);
MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support");
-static int ide_acpionboot;
+static bool ide_acpionboot;
module_param_named(acpionboot, ide_acpionboot, bool, 0);
MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot");
@@ -92,6 +92,22 @@ int ide_acpi_init(void)
return 0;
}
+bool ide_port_acpi(ide_hwif_t *hwif)
+{
+ return ide_noacpi == 0 && hwif->acpidata;
+}
+
+static acpi_handle acpi_get_child(acpi_handle handle, u64 addr)
+{
+ struct acpi_device *adev;
+
+ if (!handle || acpi_bus_get_device(handle, &adev))
+ return NULL;
+
+ adev = acpi_find_child_device(adev, addr, false);
+ return adev ? adev->handle : NULL;
+}
+
/**
* ide_get_dev_handle - finds acpi_handle and PCI device.function
* @dev: device to locate
@@ -103,14 +119,12 @@ int ide_acpi_init(void)
* Returns 0 on success, <0 on error.
*/
static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
- acpi_integer *pcidevfn)
+ u64 *pcidevfn)
{
struct pci_dev *pdev = to_pci_dev(dev);
unsigned int bus, devnum, func;
- acpi_integer addr;
+ u64 addr;
acpi_handle dev_handle;
- struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER,
- .pointer = NULL};
acpi_status status;
struct acpi_device_info *dinfo = NULL;
int ret = -ENODEV;
@@ -119,22 +133,21 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle,
devnum = PCI_SLOT(pdev->devfn);
func = PCI_FUNC(pdev->devfn);
/* ACPI _ADR encoding for PCI bus: */
- addr = (acpi_integer)(devnum << 16 | func);
+ addr = (u64)(devnum << 16 | func);
DEBPRINT("ENTER: pci %02x:%02x.%01x\n", bus, devnum, func);
- dev_handle = DEVICE_ACPI_HANDLE(dev);
+ dev_handle = ACPI_HANDLE(dev);
if (!dev_handle) {
DEBPRINT("no acpi handle for device\n");
goto err;
}
- status = acpi_get_object_info(dev_handle, &buffer);
+ status = acpi_get_object_info(dev_handle, &dinfo);
if (ACPI_FAILURE(status)) {
DEBPRINT("get_object_info for device failed\n");
goto err;
}
- dinfo = buffer.pointer;
if (dinfo && (dinfo->valid & ACPI_VALID_ADR) &&
dinfo->address == addr) {
*pcidevfn = addr;
@@ -167,7 +180,7 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
{
struct device *dev = hwif->gendev.parent;
acpi_handle uninitialized_var(dev_handle);
- acpi_integer pcidevfn;
+ u64 pcidevfn;
acpi_handle chan_handle;
int err;
@@ -352,9 +365,6 @@ int ide_acpi_exec_tfs(ide_drive_t *drive)
unsigned long gtf_address;
unsigned long obj_loc;
- if (ide_noacpi)
- return 0;
-
DEBPRINT("call get_GTF, drive=%s port=%d\n", drive->name, drive->dn);
ret = do_drive_get_GTF(drive, &gtf_length, &gtf_address, &obj_loc);
@@ -389,16 +399,6 @@ void ide_acpi_get_timing(ide_hwif_t *hwif)
struct acpi_buffer output;
union acpi_object *out_obj;
- if (ide_noacpi)
- return;
-
- DEBPRINT("ENTER:\n");
-
- if (!hwif->acpidata) {
- DEBPRINT("no ACPI data for %s\n", hwif->name);
- return;
- }
-
/* Setting up output buffer for _GTM */
output.length = ACPI_ALLOCATE_BUFFER;
output.pointer = NULL; /* ACPI-CA sets this; save/free it later */
@@ -426,21 +426,21 @@ void ide_acpi_get_timing(ide_hwif_t *hwif)
out_obj = output.pointer;
if (out_obj->type != ACPI_TYPE_BUFFER) {
- kfree(output.pointer);
DEBPRINT("Run _GTM: error: "
"expected object type of ACPI_TYPE_BUFFER, "
"got 0x%x\n", out_obj->type);
+ kfree(output.pointer);
return;
}
if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
out_obj->buffer.length != sizeof(struct GTM_buffer)) {
- kfree(output.pointer);
printk(KERN_ERR
"%s: unexpected _GTM length (0x%x)[should be 0x%zx] or "
"addr (0x%p)\n",
__func__, out_obj->buffer.length,
sizeof(struct GTM_buffer), out_obj->buffer.pointer);
+ kfree(output.pointer);
return;
}
@@ -479,16 +479,6 @@ void ide_acpi_push_timing(ide_hwif_t *hwif)
struct ide_acpi_drive_link *master = &hwif->acpidata->master;
struct ide_acpi_drive_link *slave = &hwif->acpidata->slave;
- if (ide_noacpi)
- return;
-
- DEBPRINT("ENTER:\n");
-
- if (!hwif->acpidata) {
- DEBPRINT("no ACPI data for %s\n", hwif->name);
- return;
- }
-
/* Give the GTM buffer + drive Identify data to the channel via the
* _STM method: */
/* setup input parameters buffer for _STM */
@@ -527,16 +517,11 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
ide_drive_t *drive;
int i;
- if (ide_noacpi || ide_noacpi_psx)
+ if (ide_noacpi_psx)
return;
DEBPRINT("ENTER:\n");
- if (!hwif->acpidata) {
- DEBPRINT("no ACPI data for %s\n", hwif->name);
- return;
- }
-
/* channel first and then drives for power on and verse versa for power off */
if (on)
acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D0);
@@ -544,11 +529,12 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
ide_port_for_each_present_dev(i, drive, hwif) {
if (drive->acpidata->obj_handle)
acpi_bus_set_power(drive->acpidata->obj_handle,
- on ? ACPI_STATE_D0 : ACPI_STATE_D3);
+ on ? ACPI_STATE_D0 : ACPI_STATE_D3_COLD);
}
if (!on)
- acpi_bus_set_power(hwif->acpidata->obj_handle, ACPI_STATE_D3);
+ acpi_bus_set_power(hwif->acpidata->obj_handle,
+ ACPI_STATE_D3_COLD);
}
/**
@@ -616,7 +602,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
drive->name, err);
}
- if (!ide_acpionboot) {
+ if (ide_noacpi || ide_acpionboot == 0) {
DEBPRINT("ACPI methods disabled on boot\n");
return;
}
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 7201b176d75..fac3d9da2e0 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -5,11 +5,16 @@
#include <linux/kernel.h>
#include <linux/cdrom.h>
#include <linux/delay.h>
+#include <linux/export.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
+#include <linux/gfp.h>
#include <scsi/scsi.h>
+#define DRV_NAME "ide-atapi"
+#define PFX DRV_NAME ": "
+
#ifdef DEBUG
#define debug_log(fmt, args...) \
printk(KERN_INFO "ide: " fmt, ## args)
@@ -74,64 +79,36 @@ EXPORT_SYMBOL_GPL(ide_check_atapi_device);
void ide_init_pc(struct ide_atapi_pc *pc)
{
memset(pc, 0, sizeof(*pc));
- pc->buf = pc->pc_buf;
- pc->buf_size = IDE_PC_BUFFER_SIZE;
}
EXPORT_SYMBOL_GPL(ide_init_pc);
/*
- * Generate a new packet command request in front of the request queue, before
- * the current request, so that it will be processed immediately, on the next
- * pass through the driver.
- */
-static void ide_queue_pc_head(ide_drive_t *drive, struct gendisk *disk,
- struct ide_atapi_pc *pc, struct request *rq)
-{
- blk_rq_init(NULL, rq);
- rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->cmd_flags |= REQ_PREEMPT;
- rq->buffer = (char *)pc;
- rq->rq_disk = disk;
-
- if (pc->req_xfer) {
- rq->data = pc->buf;
- rq->data_len = pc->req_xfer;
- }
-
- memcpy(rq->cmd, pc->c, 12);
- if (drive->media == ide_tape)
- rq->cmd[13] = REQ_IDETAPE_PC1;
-
- drive->hwif->rq = NULL;
-
- elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
-}
-
-/*
* Add a special packet command request to the tail of the request queue,
* and wait for it to be serviced.
*/
int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
- struct ide_atapi_pc *pc)
+ struct ide_atapi_pc *pc, void *buf, unsigned int bufflen)
{
struct request *rq;
int error;
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_SPECIAL;
- rq->buffer = (char *)pc;
+ rq->special = (char *)pc;
- if (pc->req_xfer) {
- rq->data = pc->buf;
- rq->data_len = pc->req_xfer;
+ if (buf && bufflen) {
+ error = blk_rq_map_kern(drive->queue, rq, buf, bufflen,
+ GFP_NOIO);
+ if (error)
+ goto put_req;
}
memcpy(rq->cmd, pc->c, 12);
if (drive->media == ide_tape)
rq->cmd[13] = REQ_IDETAPE_PC1;
error = blk_execute_rq(drive->queue, disk, rq, 0);
+put_req:
blk_put_request(rq);
-
return error;
}
EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
@@ -143,7 +120,7 @@ int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk)
ide_init_pc(&pc);
pc.c[0] = TEST_UNIT_READY;
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_do_test_unit_ready);
@@ -158,7 +135,7 @@ int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start)
if (drive->media == ide_tape)
pc.flags |= PC_FLAG_WAIT_FOR_DSC;
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_do_start_stop);
@@ -173,7 +150,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
pc.c[0] = ALLOW_MEDIUM_REMOVAL;
pc.c[4] = on;
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_set_media_lock);
@@ -191,20 +168,108 @@ void ide_create_request_sense_cmd(ide_drive_t *drive, struct ide_atapi_pc *pc)
}
EXPORT_SYMBOL_GPL(ide_create_request_sense_cmd);
+void ide_prep_sense(ide_drive_t *drive, struct request *rq)
+{
+ struct request_sense *sense = &drive->sense_data;
+ struct request *sense_rq = &drive->sense_rq;
+ unsigned int cmd_len, sense_len;
+ int err;
+
+ switch (drive->media) {
+ case ide_floppy:
+ cmd_len = 255;
+ sense_len = 18;
+ break;
+ case ide_tape:
+ cmd_len = 20;
+ sense_len = 20;
+ break;
+ default:
+ cmd_len = 18;
+ sense_len = 18;
+ }
+
+ BUG_ON(sense_len > sizeof(*sense));
+
+ if (rq->cmd_type == REQ_TYPE_SENSE || drive->sense_rq_armed)
+ return;
+
+ memset(sense, 0, sizeof(*sense));
+
+ blk_rq_init(rq->q, sense_rq);
+
+ err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
+ GFP_NOIO);
+ if (unlikely(err)) {
+ if (printk_ratelimit())
+ printk(KERN_WARNING PFX "%s: failed to map sense "
+ "buffer\n", drive->name);
+ return;
+ }
+
+ sense_rq->rq_disk = rq->rq_disk;
+ sense_rq->cmd[0] = GPCMD_REQUEST_SENSE;
+ sense_rq->cmd[4] = cmd_len;
+ sense_rq->cmd_type = REQ_TYPE_SENSE;
+ sense_rq->cmd_flags |= REQ_PREEMPT;
+
+ if (drive->media == ide_tape)
+ sense_rq->cmd[13] = REQ_IDETAPE_PC1;
+
+ drive->sense_rq_armed = true;
+}
+EXPORT_SYMBOL_GPL(ide_prep_sense);
+
+int ide_queue_sense_rq(ide_drive_t *drive, void *special)
+{
+ /* deferred failure from ide_prep_sense() */
+ if (!drive->sense_rq_armed) {
+ printk(KERN_WARNING PFX "%s: error queuing a sense request\n",
+ drive->name);
+ return -ENOMEM;
+ }
+
+ drive->sense_rq.special = special;
+ drive->sense_rq_armed = false;
+
+ drive->hwif->rq = NULL;
+
+ elv_add_request(drive->queue, &drive->sense_rq, ELEVATOR_INSERT_FRONT);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ide_queue_sense_rq);
+
/*
* Called when an error was detected during the last packet command.
- * We queue a request sense packet command in the head of the request list.
+ * We queue a request sense packet command at the head of the request
+ * queue.
*/
-void ide_retry_pc(ide_drive_t *drive, struct gendisk *disk)
+void ide_retry_pc(ide_drive_t *drive)
{
- struct request *rq = &drive->request_sense_rq;
+ struct request *failed_rq = drive->hwif->rq;
+ struct request *sense_rq = &drive->sense_rq;
struct ide_atapi_pc *pc = &drive->request_sense_pc;
(void)ide_read_error(drive);
- ide_create_request_sense_cmd(drive, pc);
+
+ /* init pc from sense_rq */
+ ide_init_pc(pc);
+ memcpy(pc->c, sense_rq->cmd, 12);
+
if (drive->media == ide_tape)
- set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
- ide_queue_pc_head(drive, disk, pc, rq);
+ drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
+
+ /*
+ * Push back the failed request and put request sense on top
+ * of it. The failed command will be retried after sense data
+ * is acquired.
+ */
+ drive->hwif->rq = NULL;
+ ide_requeue_and_plug(drive, failed_rq);
+ if (ide_queue_sense_rq(drive, pc)) {
+ blk_start_request(failed_rq);
+ ide_complete_rq(drive, -EIO, blk_rq_bytes(failed_rq));
+ }
}
EXPORT_SYMBOL_GPL(ide_retry_pc);
@@ -231,7 +296,7 @@ int ide_cd_expiry(ide_drive_t *drive)
break;
default:
if (!(rq->cmd_flags & REQ_QUIET))
- printk(KERN_INFO "cmd 0x%x timed out\n",
+ printk(KERN_INFO PFX "cmd 0x%x timed out\n",
rq->cmd[0]);
wait = 0;
break;
@@ -242,13 +307,16 @@ EXPORT_SYMBOL_GPL(ide_cd_expiry);
int ide_cd_get_xferlen(struct request *rq)
{
- if (blk_fs_request(rq))
+ switch (rq->cmd_type) {
+ case REQ_TYPE_FS:
return 32768;
- else if (blk_sense_request(rq) || blk_pc_request(rq) ||
- rq->cmd_type == REQ_TYPE_ATA_PC)
- return rq->data_len;
- else
+ case REQ_TYPE_SENSE:
+ case REQ_TYPE_BLOCK_PC:
+ case REQ_TYPE_ATA_PC:
+ return blk_rq_bytes(rq);
+ default:
return 0;
+ }
}
EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
@@ -265,6 +333,55 @@ void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
/*
+ * Check the contents of the interrupt reason register and attempt to recover if
+ * there are problems.
+ *
+ * Returns:
+ * - 0 if everything's ok
+ * - 1 if the request has to be terminated.
+ */
+int ide_check_ireason(ide_drive_t *drive, struct request *rq, int len,
+ int ireason, int rw)
+{
+ ide_hwif_t *hwif = drive->hwif;
+
+ debug_log("ireason: 0x%x, rw: 0x%x\n", ireason, rw);
+
+ if (ireason == (!rw << 1))
+ return 0;
+ else if (ireason == (rw << 1)) {
+ printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n",
+ drive->name, __func__);
+
+ if (dev_is_idecd(drive))
+ ide_pad_transfer(drive, rw, len);
+ } else if (!rw && ireason == ATAPI_COD) {
+ if (dev_is_idecd(drive)) {
+ /*
+ * Some drives (ASUS) seem to tell us that status info
+ * is available. Just get it and ignore.
+ */
+ (void)hwif->tp_ops->read_status(hwif);
+ return 0;
+ }
+ } else {
+ if (ireason & ATAPI_COD)
+ printk(KERN_ERR PFX "%s: CoD != 0 in %s\n", drive->name,
+ __func__);
+
+ /* drive wants a command packet, or invalid ireason... */
+ printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n",
+ drive->name, __func__, ireason);
+ }
+
+ if (dev_is_idecd(drive) && rq->cmd_type == REQ_TYPE_ATA_PC)
+ rq->cmd_flags |= REQ_FAILED;
+
+ return 1;
+}
+EXPORT_SYMBOL_GPL(ide_check_ireason);
+
+/*
* This is the usual interrupt handler which will be called during a packet
* command. We will transfer some of the data (as requested by the drive)
* and will re-point interrupt handler to us.
@@ -276,7 +393,6 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xferfunc;
unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
@@ -299,25 +415,21 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
if (drive->media == ide_floppy)
- printk(KERN_ERR "%s: DMA %s error\n",
+ printk(KERN_ERR PFX "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
? "write" : "read");
pc->flags |= PC_FLAG_DMA_ERROR;
- } else {
- pc->xferred = pc->req_xfer;
- if (drive->pc_update_buffers)
- drive->pc_update_buffers(drive, pc);
- }
+ } else
+ rq->resid_len = 0;
debug_log("%s: DMA finished\n", drive->name);
}
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
int uptodate, error;
- unsigned int done;
debug_log("Packet command completed, %d bytes transferred\n",
- pc->xferred);
+ blk_rq_bytes(rq));
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
@@ -335,15 +447,15 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
pc->rq->errors++;
if (rq->cmd[0] == REQUEST_SENSE) {
- printk(KERN_ERR "%s: I/O error in request sense"
- " command\n", drive->name);
+ printk(KERN_ERR PFX "%s: I/O error in request "
+ "sense command\n", drive->name);
return ide_do_reset(drive);
}
debug_log("[cmd %x]: check condition\n", rq->cmd[0]);
/* Retry operation */
- ide_retry_pc(drive, rq->rq_disk);
+ ide_retry_pc(drive);
/* queued, but not started */
return ide_stopped;
@@ -353,39 +465,39 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if ((pc->flags & PC_FLAG_WAIT_FOR_DSC) && (stat & ATA_DSC) == 0)
dsc = 1;
+ /*
+ * ->pc_callback() might change rq->data_len for
+ * residual count, cache total length.
+ */
+ done = blk_rq_bytes(rq);
+
/* Command finished - Call the callback function */
uptodate = drive->pc_callback(drive, dsc);
if (uptodate == 0)
drive->failed_pc = NULL;
- if (blk_special_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_SPECIAL) {
rq->errors = 0;
- done = blk_rq_bytes(rq);
error = 0;
} else {
- if (blk_fs_request(rq) == 0 && uptodate <= 0) {
+ if (rq->cmd_type != REQ_TYPE_FS && uptodate <= 0) {
if (rq->errors == 0)
rq->errors = -EIO;
}
- if (drive->media == ide_tape)
- done = ide_rq_bytes(rq); /* FIXME */
- else
- done = blk_rq_bytes(rq);
-
error = uptodate ? 0 : -EIO;
}
- ide_complete_rq(drive, error, done);
+ ide_complete_rq(drive, error, blk_rq_bytes(rq));
return ide_stopped;
}
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
- printk(KERN_ERR "%s: The device wants to issue more interrupts "
- "in DMA mode\n", drive->name);
+ printk(KERN_ERR PFX "%s: The device wants to issue more "
+ "interrupts in DMA mode\n", drive->name);
ide_dma_off(drive);
return ide_do_reset(drive);
}
@@ -393,43 +505,22 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* Get the number of bytes to transfer on this interrupt. */
ide_read_bcount_and_ireason(drive, &bcount, &ireason);
- if (ireason & ATAPI_COD) {
- printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__);
+ if (ide_check_ireason(drive, rq, bcount, ireason, write))
return ide_do_reset(drive);
- }
- if (((ireason & ATAPI_IO) == ATAPI_IO) == write) {
- /* Hopefully, we will never get here */
- printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
- "to %s!\n", drive->name,
- (ireason & ATAPI_IO) ? "Write" : "Read",
- (ireason & ATAPI_IO) ? "Read" : "Write");
- return ide_do_reset(drive);
- }
-
- xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
-
- if (drive->media == ide_floppy && pc->buf == NULL) {
- done = min_t(unsigned int, bcount, cmd->nleft);
- ide_pio_bytes(drive, cmd, write, done);
- } else if (drive->media == ide_tape && pc->bh) {
- done = drive->pc_io_buffers(drive, pc, bcount, write);
- } else {
- done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
- xferfunc(drive, NULL, pc->cur_pos, done);
- }
+ done = min_t(unsigned int, bcount, cmd->nleft);
+ ide_pio_bytes(drive, cmd, write, done);
- /* Update the current position */
- pc->xferred += done;
- pc->cur_pos += done;
+ /* Update transferred byte count */
+ rq->resid_len -= done;
bcount -= done;
if (bcount)
ide_pad_transfer(drive, write, bcount);
- debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n",
- rq->cmd[0], done, bcount);
+ debug_log("[cmd %x] transferred %d bytes, padded %d bytes, resid: %u\n",
+ rq->cmd[0], done, bcount, rq->resid_len);
/* And set the interrupt handler again */
ide_set_handler(drive, ide_pc_intr, timeout);
@@ -463,13 +554,13 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
while (retries-- && ((ireason & ATAPI_COD) == 0 ||
(ireason & ATAPI_IO))) {
- printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
+ printk(KERN_ERR PFX "%s: (IO,CoD != (0,1) while issuing "
"a packet command, retrying\n", drive->name);
udelay(100);
ireason = ide_read_ireason(drive);
if (retries == 0) {
- printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing "
- "a packet command, ignoring\n",
+ printk(KERN_ERR PFX "%s: (IO,CoD != (0,1) while issuing"
+ " a packet command, ignoring\n",
drive->name);
ireason |= ATAPI_COD;
ireason &= ~ATAPI_IO;
@@ -500,7 +591,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
u8 ireason;
if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) {
- printk(KERN_ERR "%s: Strange, packet command initiated yet "
+ printk(KERN_ERR PFX "%s: Strange, packet command initiated yet "
"DRQ isn't asserted\n", drive->name);
return startstop;
}
@@ -525,7 +616,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
/*
* If necessary schedule the packet transfer to occur 'timeout'
- * miliseconds later in ide_delayed_transfer_pc() after the
+ * milliseconds later in ide_delayed_transfer_pc() after the
* device says it's ready for a packet.
*/
if (drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) {
@@ -542,8 +633,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
ireason = ide_wait_ireason(drive, ireason);
if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) {
- printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing "
- "a packet command\n", drive->name);
+ printk(KERN_ERR PFX "%s: (IO,CoD) != (0,1) while "
+ "issuing a packet command\n", drive->name);
return ide_do_reset(drive);
}
@@ -581,7 +672,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
ide_hwif_t *hwif = drive->hwif;
ide_expiry_t *expiry = NULL;
struct request *rq = hwif->rq;
- unsigned int timeout;
+ unsigned int timeout, bytes;
u16 bcount;
u8 valid_tf;
u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
@@ -597,14 +688,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
} else {
pc = drive->pc;
- /* We haven't transferred any data yet */
- pc->xferred = 0;
- pc->cur_pos = pc->buf;
-
valid_tf = IDE_VALID_DEVICE;
- bcount = ((drive->media == ide_tape) ?
- pc->req_xfer :
- min(pc->req_xfer, 63 * 1024));
+ bytes = blk_rq_bytes(rq);
+ bcount = ((drive->media == ide_tape) ? bytes
+ : min_t(unsigned int,
+ bytes, 63 * 1024));
+
+ /* We haven't transferred any data yet */
+ rq->resid_len = bcount;
if (pc->flags & PC_FLAG_DMA_ERROR) {
pc->flags &= ~PC_FLAG_DMA_ERROR;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3d4e0996976..0b510bafd90 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -30,6 +30,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
@@ -42,7 +43,6 @@
/* For SCSI -> ATAPI command conversion */
#include <scsi/scsi.h>
-#include <linux/irq.h>
#include <linux/io.h>
#include <asm/byteorder.h>
#include <linux/uaccess.h>
@@ -50,6 +50,7 @@
#include "ide-cd.h"
+static DEFINE_MUTEX(ide_cd_mutex);
static DEFINE_MUTEX(idecd_ref_mutex);
static void ide_cd_release(struct device *);
@@ -92,16 +93,16 @@ static void cdrom_saw_media_change(ide_drive_t *drive)
drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
}
-static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
- struct request_sense *sense)
+static int cdrom_log_sense(ide_drive_t *drive, struct request *rq)
{
+ struct request_sense *sense = &drive->sense_data;
int log = 0;
- ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
-
if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
return 0;
+ ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
+
switch (sense->sense_key) {
case NO_SENSE:
case RECOVERED_ERROR:
@@ -140,12 +141,12 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
}
static void cdrom_analyze_sense_data(ide_drive_t *drive,
- struct request *failed_command,
- struct request_sense *sense)
+ struct request *failed_command)
{
+ struct request_sense *sense = &drive->sense_data;
+ struct cdrom_info *info = drive->driver_data;
unsigned long sector;
unsigned long bio_sectors;
- struct cdrom_info *info = drive->driver_data;
ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
sense->error_code, sense->sense_key);
@@ -154,7 +155,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
failed_command->cmd[0]);
- if (!cdrom_log_sense(drive, failed_command, sense))
+ if (!cdrom_log_sense(drive, failed_command))
return;
/*
@@ -175,14 +176,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
if (!sense->valid)
break;
if (failed_command == NULL ||
- !blk_fs_request(failed_command))
+ failed_command->cmd_type != REQ_TYPE_FS)
break;
sector = (sense->information[0] << 24) |
(sense->information[1] << 16) |
(sense->information[2] << 8) |
(sense->information[3]);
- if (drive->queue->hardsect_size == 2048)
+ if (queue_logical_block_size(drive->queue) == 2048)
/* device sector size is 2K */
sector <<= 2;
@@ -206,63 +207,33 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
ide_cd_log_error(drive->name, failed_command, sense);
}
-static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
- struct request *failed_command)
-{
- struct cdrom_info *info = drive->driver_data;
- struct request *rq = &drive->request_sense_rq;
-
- ide_debug_log(IDE_DBG_SENSE, "enter");
-
- if (sense == NULL)
- sense = &info->sense_data;
-
- /* stuff the sense request in front of our current request */
- blk_rq_init(NULL, rq);
- rq->cmd_type = REQ_TYPE_ATA_PC;
- rq->rq_disk = info->disk;
-
- rq->data = sense;
- rq->cmd[0] = GPCMD_REQUEST_SENSE;
- rq->cmd[4] = 18;
- rq->data_len = 18;
-
- rq->cmd_type = REQ_TYPE_SENSE;
- rq->cmd_flags |= REQ_PREEMPT;
-
- /* NOTE! Save the failed command in "rq->buffer" */
- rq->buffer = (void *) failed_command;
-
- if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
- failed_command->cmd[0]);
-
- drive->hwif->rq = NULL;
-
- elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
-}
-
static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
/*
- * For REQ_TYPE_SENSE, "rq->buffer" points to the original
- * failed request
+ * For REQ_TYPE_SENSE, "rq->special" points to the original
+ * failed request. Also, the sense data should be read
+ * directly from rq which might be different from the original
+ * sense buffer if it got copied during mapping.
*/
- struct request *failed = (struct request *)rq->buffer;
- struct cdrom_info *info = drive->driver_data;
- void *sense = &info->sense_data;
+ struct request *failed = (struct request *)rq->special;
+ void *sense = bio_data(rq->bio);
if (failed) {
if (failed->sense) {
- sense = failed->sense;
+ /*
+ * Sense is always read into drive->sense_data.
+ * Copy back if the failed request has its
+ * sense pointer set.
+ */
+ memcpy(failed->sense, sense, 18);
failed->sense_len = rq->sense_len;
}
- cdrom_analyze_sense_data(drive, failed, sense);
+ cdrom_analyze_sense_data(drive, failed);
if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
BUG();
} else
- cdrom_analyze_sense_data(drive, NULL, sense);
+ cdrom_analyze_sense_data(drive, NULL);
}
@@ -286,17 +257,10 @@ static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
if (time_after(jiffies, info->write_timeout))
return 0;
else {
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
/*
- * take a breather relying on the unplug timer to kick us again
+ * take a breather
*/
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_plug_device(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
+ blk_delay_queue(drive->queue, 1);
return 1;
}
}
@@ -312,7 +276,6 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->rq;
int err, sense_key, do_end_request = 0;
- u8 quiet = rq->cmd_flags & REQ_QUIET;
/* get the IDE error register */
err = ide_read_error(drive);
@@ -322,7 +285,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
"stat 0x%x",
rq->cmd[0], rq->cmd_type, err, stat);
- if (blk_sense_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_SENSE) {
/*
* We got an error trying to get sense info from the drive
* (probably while trying to recover from a former error).
@@ -333,7 +296,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
}
/* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
- if (blk_pc_request(rq) && !rq->errors)
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !rq->errors)
rq->errors = SAM_STAT_CHECK_CONDITION;
if (blk_noretry_request(rq))
@@ -341,13 +304,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
switch (sense_key) {
case NOT_READY:
- if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) {
+ if (rq->cmd_type == REQ_TYPE_FS && rq_data_dir(rq) == WRITE) {
if (ide_cd_breathe(drive, rq))
return 1;
} else {
cdrom_saw_media_change(drive);
- if (blk_fs_request(rq) && !quiet)
+ if (rq->cmd_type == REQ_TYPE_FS &&
+ !(rq->cmd_flags & REQ_QUIET))
printk(KERN_ERR PFX "%s: tray open\n",
drive->name);
}
@@ -356,7 +320,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
case UNIT_ATTENTION:
cdrom_saw_media_change(drive);
- if (blk_fs_request(rq) == 0)
+ if (rq->cmd_type != REQ_TYPE_FS)
return 0;
/*
@@ -382,7 +346,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
* No point in retrying after an illegal request or data
* protect error.
*/
- if (!quiet)
+ if (!(rq->cmd_flags & REQ_QUIET))
ide_dump_status(drive, "command error", stat);
do_end_request = 1;
break;
@@ -391,20 +355,20 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
* No point in re-trying a zillion times on a bad sector.
* If we got here the error is not correctable.
*/
- if (!quiet)
+ if (!(rq->cmd_flags & REQ_QUIET))
ide_dump_status(drive, "media error "
"(bad sector)", stat);
do_end_request = 1;
break;
case BLANK_CHECK:
/* disk appears blank? */
- if (!quiet)
+ if (!(rq->cmd_flags & REQ_QUIET))
ide_dump_status(drive, "media error (blank)",
stat);
do_end_request = 1;
break;
default:
- if (blk_fs_request(rq) == 0)
+ if (rq->cmd_type != REQ_TYPE_FS)
break;
if (err & ~ATA_ABORTED) {
/* go to the default handler for other errors */
@@ -415,7 +379,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
do_end_request = 1;
}
- if (blk_fs_request(rq) == 0) {
+ if (rq->cmd_type != REQ_TYPE_FS) {
rq->cmd_flags |= REQ_FAILED;
do_end_request = 1;
}
@@ -429,70 +393,17 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
/* if we got a CHECK_CONDITION status, queue a request sense command */
if (stat & ATA_ERR)
- cdrom_queue_request_sense(drive, NULL, NULL);
+ return ide_queue_sense_rq(drive, NULL) ? 2 : 1;
return 1;
end_request:
if (stat & ATA_ERR) {
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blkdev_dequeue_request(rq);
- spin_unlock_irqrestore(q->queue_lock, flags);
-
hwif->rq = NULL;
-
- cdrom_queue_request_sense(drive, rq->sense, rq);
- return 1;
+ return ide_queue_sense_rq(drive, rq) ? 2 : 1;
} else
return 2;
}
-/*
- * Check the contents of the interrupt reason register from the cdrom
- * and attempt to recover if there are problems. Returns 0 if everything's
- * ok; nonzero if the request has been terminated.
- */
-static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
- int len, int ireason, int rw)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
-
- /*
- * ireason == 0: the drive wants to receive data from us
- * ireason == 2: the drive is expecting to transfer data to us
- */
- if (ireason == (!rw << 1))
- return 0;
- else if (ireason == (rw << 1)) {
-
- /* whoops... */
- printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n",
- drive->name, __func__);
-
- ide_pad_transfer(drive, rw, len);
- } else if (rw == 0 && ireason == 1) {
- /*
- * Some drives (ASUS) seem to tell us that status info is
- * available. Just get it and ignore.
- */
- (void)hwif->tp_ops->read_status(hwif);
- return 0;
- } else {
- /* drive wants a command packet, or invalid ireason... */
- printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n",
- drive->name, __func__, ireason);
- }
-
- if (rq->cmd_type == REQ_TYPE_ATA_PC)
- rq->cmd_flags |= REQ_FAILED;
-
- return -1;
-}
-
static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct request *rq = cmd->rq;
@@ -504,14 +415,8 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
* and some drives don't send them. Sigh.
*/
if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
- cmd->nleft > 0 && cmd->nleft <= 5) {
- unsigned int ofs = cmd->nbytes - cmd->nleft;
-
- while (cmd->nleft > 0) {
- *((u8 *)rq->data + ofs++) = 0;
- cmd->nleft--;
- }
- }
+ cmd->nleft > 0 && cmd->nleft <= 5)
+ cmd->nleft = 0;
}
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -544,14 +449,18 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
rq->cmd_flags |= cmd_flags;
rq->timeout = timeout;
if (buffer) {
- rq->data = buffer;
- rq->data_len = *bufflen;
+ error = blk_rq_map_kern(drive->queue, rq, buffer,
+ *bufflen, GFP_NOIO);
+ if (error) {
+ blk_put_request(rq);
+ return error;
+ }
}
error = blk_execute_rq(drive->queue, info->disk, rq, 0);
if (buffer)
- *bufflen = rq->data_len;
+ *bufflen = rq->resid_len;
flags = rq->cmd_flags;
blk_put_request(rq);
@@ -591,15 +500,22 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}
-static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
+/*
+ * returns true if rq has been completed
+ */
+static bool ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
if (cmd->tf_flags & IDE_TFLAG_WRITE)
nr_bytes -= cmd->last_xfer_len;
- if (nr_bytes > 0)
+ if (nr_bytes > 0) {
ide_complete_rq(drive, 0, nr_bytes);
+ return true;
+ }
+
+ return false;
}
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
@@ -609,8 +525,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
struct request *rq = hwif->rq;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors;
- int sense = blk_sense_request(rq);
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0;
+ int sense = (rq->cmd_type == REQ_TYPE_SENSE);
unsigned int timeout;
u16 len;
u8 ireason, stat;
@@ -653,7 +569,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
ide_read_bcount_and_ireason(drive, &len, &ireason);
- thislen = blk_fs_request(rq) ? len : cmd->nleft;
+ thislen = (rq->cmd_type == REQ_TYPE_FS) ? len : cmd->nleft;
if (thislen > len)
thislen = len;
@@ -662,7 +578,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/* If DRQ is clear, the command has completed. */
if ((stat & ATA_DRQ) == 0) {
- if (blk_fs_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_FS) {
/*
* If we're not done reading/writing, complain.
* Otherwise, complete the command normally.
@@ -676,18 +592,27 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
rq->cmd_flags |= REQ_FAILED;
uptodate = 0;
}
- } else if (!blk_pc_request(rq)) {
+ } else if (rq->cmd_type != REQ_TYPE_BLOCK_PC) {
ide_cd_request_sense_fixup(drive, cmd);
- /* complain if we still have data left to transfer */
+
uptodate = cmd->nleft ? 0 : 1;
- if (uptodate == 0)
+
+ /*
+ * suck out the remaining bytes from the drive in an
+ * attempt to complete the data xfer. (see BZ#13399)
+ */
+ if (!(stat & ATA_ERR) && !uptodate && thislen) {
+ ide_pio_bytes(drive, cmd, write, thislen);
+ uptodate = cmd->nleft ? 0 : 1;
+ }
+
+ if (!uptodate)
rq->cmd_flags |= REQ_FAILED;
}
goto out_end;
}
- /* check which way to transfer data */
- rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+ rc = ide_check_ireason(drive, rq, len, ireason, write);
if (rc)
goto out_end;
@@ -716,7 +641,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/* pad, if necessary */
if (len > 0) {
- if (blk_fs_request(rq) == 0 || write == 0)
+ if (rq->cmd_type != REQ_TYPE_FS || write == 0)
ide_pad_transfer(drive, write, len);
else {
printk(KERN_ERR PFX "%s: confused, missing data\n",
@@ -725,11 +650,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
}
}
- if (blk_pc_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
timeout = rq->timeout;
} else {
timeout = ATAPI_WAIT_PC;
- if (!blk_fs_request(rq))
+ if (rq->cmd_type != REQ_TYPE_FS)
expiry = ide_cd_expiry;
}
@@ -738,20 +663,15 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
return ide_started;
out_end:
- if (blk_pc_request(rq) && rc == 0) {
- unsigned int dlen = rq->data_len;
-
- rq->data_len = 0;
-
- if (blk_end_request(rq, 0, dlen))
- BUG();
-
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) {
+ rq->resid_len = 0;
+ blk_end_request_all(rq, 0);
hwif->rq = NULL;
} else {
if (sense && uptodate)
ide_cd_complete_failed_rq(drive, rq);
- if (blk_fs_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_FS) {
if (cmd->nleft == 0)
uptodate = 1;
} else {
@@ -759,25 +679,18 @@ out_end:
rq->errors = -EIO;
}
- if (uptodate == 0)
- ide_cd_error_cmd(drive, cmd);
+ if (uptodate == 0 && rq->bio)
+ if (ide_cd_error_cmd(drive, cmd))
+ return ide_stopped;
/* make sure it's fully ended */
- if (blk_pc_request(rq))
- nsectors = (rq->data_len + 511) >> 9;
- else
- nsectors = rq->hard_nr_sectors;
-
- if (nsectors == 0)
- nsectors = 1;
-
- if (blk_fs_request(rq) == 0) {
- rq->data_len -= (cmd->nbytes - cmd->nleft);
+ if (rq->cmd_type != REQ_TYPE_FS) {
+ rq->resid_len -= cmd->nbytes - cmd->nleft;
if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
- rq->data_len += cmd->last_xfer_len;
+ rq->resid_len += cmd->last_xfer_len;
}
- ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, blk_rq_bytes(rq));
if (sense && rc == 2)
ide_error(drive, "request sense failure", stat);
@@ -791,7 +704,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
- queue_hardsect_size(q) >> SECTOR_BITS;
+ queue_logical_block_size(q) >> SECTOR_BITS;
ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
"secs_per_frame: %u",
@@ -810,8 +723,8 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
}
/* fs requests *must* be hardware frame aligned */
- if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
- (rq->sector & (sectors_per_frame - 1)))
+ if ((blk_rq_sectors(rq) & (sectors_per_frame - 1)) ||
+ (blk_rq_pos(rq) & (sectors_per_frame - 1)))
return ide_stopped;
/* use DMA, if possible */
@@ -831,7 +744,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
rq->cmd[0], rq->cmd_type);
- if (blk_pc_request(rq))
+ if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
rq->cmd_flags |= REQ_QUIET;
else
rq->cmd_flags &= ~REQ_FAILED;
@@ -839,15 +752,10 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
drive->dma = 0;
/* sg request */
- if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) {
+ if (rq->bio) {
struct request_queue *q = drive->queue;
+ char *buf = bio_data(rq->bio);
unsigned int alignment;
- char *buf;
-
- if (rq->bio)
- buf = bio_data(rq->bio);
- else
- buf = rq->data;
drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
@@ -859,7 +767,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
*/
alignment = queue_dma_alignment(q) | q->dma_pad_mask;
if ((unsigned long)buf & alignment
- || rq->data_len & q->dma_pad_mask
+ || blk_rq_bytes(rq) & q->dma_pad_mask
|| object_is_on_stack(buf))
drive->dma = 0;
}
@@ -869,7 +777,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
sector_t block)
{
struct ide_cmd cmd;
- int uptodate = 0, nsectors;
+ int uptodate = 0;
+ unsigned int nsectors;
ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
rq->cmd[0], (unsigned long long)block);
@@ -877,26 +786,30 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
if (drive->debug_mask & IDE_DBG_RQ)
blk_dump_rq_flags(rq, "ide_cd_do_request");
- if (blk_fs_request(rq)) {
+ switch (rq->cmd_type) {
+ case REQ_TYPE_FS:
if (cdrom_start_rw(drive, rq) == ide_stopped)
goto out_end;
- } else if (blk_sense_request(rq) || blk_pc_request(rq) ||
- rq->cmd_type == REQ_TYPE_ATA_PC) {
+ break;
+ case REQ_TYPE_SENSE:
+ case REQ_TYPE_BLOCK_PC:
+ case REQ_TYPE_ATA_PC:
if (!rq->timeout)
rq->timeout = ATAPI_WAIT_PC;
cdrom_do_block_pc(drive, rq);
- } else if (blk_special_request(rq)) {
+ break;
+ case REQ_TYPE_SPECIAL:
/* right now this can only be a reset... */
uptodate = 1;
goto out_end;
- } else {
- blk_dump_rq_flags(rq, DRV_NAME " bad flags");
- if (rq->errors == 0)
- rq->errors = -EIO;
- goto out_end;
+ default:
+ BUG();
}
+ /* prepare sense request for this command */
+ ide_prep_sense(drive, rq);
+
memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq))
@@ -904,15 +817,14 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
cmd.rq = rq;
- if (blk_fs_request(rq) || rq->data_len) {
- ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9)
- : rq->data_len);
+ if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) {
+ ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
ide_map_sg(drive, &cmd);
}
return ide_issue_pc(drive, &cmd);
out_end:
- nsectors = rq->hard_nr_sectors;
+ nsectors = blk_rq_sectors(rq);
if (nsectors == 0)
nsectors = 1;
@@ -983,9 +895,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
return stat;
/*
- * Sanity check the given block size
+ * Sanity check the given block size, in so far as making
+ * sure the sectors_per_frame we give to the caller won't
+ * end up being bogus.
*/
blocklen = be32_to_cpu(capbuf.blocklen);
+ blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS;
switch (blocklen) {
case 512:
case 1024:
@@ -993,10 +908,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
case 4096:
break;
default:
- printk(KERN_ERR PFX "%s: weird block size %u\n",
+ printk_once(KERN_ERR PFX "%s: weird block size %u; "
+ "setting default block size to 2048\n",
drive->name, blocklen);
- printk(KERN_ERR PFX "%s: default to 2kb block size\n",
- drive->name);
blocklen = 2048;
break;
}
@@ -1078,8 +992,8 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* save a private copy of the TOC capacity for error handling */
drive->probed_capacity = toc->capacity * sectors_per_frame;
- blk_queue_hardsect_size(drive->queue,
- sectors_per_frame << SECTOR_BITS);
+ blk_queue_logical_block_size(drive->queue,
+ sectors_per_frame << SECTOR_BITS);
/* first read just the header, so we know how long the TOC is */
stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
@@ -1241,8 +1155,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
curspeed, maxspeed);
- cd->current_speed = (curspeed + (176/2)) / 176;
- cd->max_speed = (maxspeed + (176/2)) / 176;
+ cd->current_speed = DIV_ROUND_CLOSEST(curspeed, 176);
+ cd->max_speed = DIV_ROUND_CLOSEST(maxspeed, 176);
}
#define IDE_CD_CAPABILITIES \
@@ -1256,7 +1170,7 @@ static struct cdrom_device_ops ide_cdrom_dops = {
.open = ide_cdrom_open_real,
.release = ide_cdrom_release_real,
.drive_status = ide_cdrom_drive_status,
- .media_changed = ide_cdrom_check_media_change_real,
+ .check_events = ide_cdrom_check_events_real,
.tray_move = ide_cdrom_tray_move,
.lock_door = ide_cdrom_lock_door,
.select_speed = ide_cdrom_select_speed,
@@ -1395,9 +1309,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
/* standard prep_rq_fn that builds 10 byte cmds */
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
{
- int hard_sect = queue_hardsect_size(q);
- long block = (long)rq->hard_sector / (hard_sect >> 9);
- unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
+ int hard_sect = queue_logical_block_size(q);
+ long block = (long)blk_rq_pos(rq) / (hard_sect >> 9);
+ unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9);
memset(rq->cmd, 0, BLK_MAX_CDB);
@@ -1459,9 +1373,9 @@ static int ide_cdrom_prep_pc(struct request *rq)
static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
{
- if (blk_fs_request(rq))
+ if (rq->cmd_type == REQ_TYPE_FS)
return ide_cdrom_prep_fs(q, rq);
- else if (blk_pc_request(rq))
+ else if (rq->cmd_type == REQ_TYPE_BLOCK_PC)
return ide_cdrom_prep_pc(rq);
return 0;
@@ -1484,19 +1398,30 @@ static sector_t ide_cdrom_capacity(ide_drive_t *drive)
return capacity * sectors_per_frame;
}
-static int proc_idecd_read_capacity(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int idecd_capacity_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t *drive = data;
- int len;
+ ide_drive_t *drive = m->private;
- len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "%llu\n", (long long)ide_cdrom_capacity(drive));
+ return 0;
}
+static int idecd_capacity_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, idecd_capacity_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations idecd_capacity_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idecd_capacity_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static ide_proc_entry_t idecd_proc[] = {
- { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
- { NULL, 0, NULL, NULL }
+ { "capacity", S_IFREG|S_IRUGO, &idecd_capacity_proc_fops },
+ {}
};
static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
@@ -1582,8 +1507,6 @@ static int ide_cdrom_setup(ide_drive_t *drive)
blk_queue_dma_alignment(q, 31);
blk_queue_update_dma_pad(q, 15);
- q->unplug_delay = max((1 * HZ) / 1000, 1);
-
drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
@@ -1600,7 +1523,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities(drive);
- blk_queue_hardsect_size(q, CD_FRAMESIZE);
+ blk_queue_logical_block_size(q, CD_FRAMESIZE);
if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1667,29 +1590,31 @@ static struct ide_driver ide_cdrom_driver = {
static int idecd_open(struct block_device *bdev, fmode_t mode)
{
- struct cdrom_info *info = ide_cd_get(bdev->bd_disk);
- int rc = -ENOMEM;
+ struct cdrom_info *info;
+ int rc = -ENXIO;
+ mutex_lock(&ide_cd_mutex);
+ info = ide_cd_get(bdev->bd_disk);
if (!info)
- return -ENXIO;
+ goto out;
rc = cdrom_open(&info->devinfo, bdev, mode);
-
if (rc < 0)
ide_cd_put(info);
-
+out:
+ mutex_unlock(&ide_cd_mutex);
return rc;
}
-static int idecd_release(struct gendisk *disk, fmode_t mode)
+static void idecd_release(struct gendisk *disk, fmode_t mode)
{
struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
+ mutex_lock(&ide_cd_mutex);
cdrom_release(&info->devinfo, mode);
ide_cd_put(info);
-
- return 0;
+ mutex_unlock(&ide_cd_mutex);
}
static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
@@ -1731,7 +1656,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
return 0;
}
-static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
+static int idecd_locked_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
@@ -1753,10 +1678,24 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
return err;
}
-static int idecd_media_changed(struct gendisk *disk)
+static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret;
+
+ mutex_lock(&ide_cd_mutex);
+ ret = idecd_locked_ioctl(bdev, mode, cmd, arg);
+ mutex_unlock(&ide_cd_mutex);
+
+ return ret;
+}
+
+
+static unsigned int idecd_check_events(struct gendisk *disk,
+ unsigned int clearing)
{
struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
- return cdrom_media_changed(&info->devinfo);
+ return cdrom_check_events(&info->devinfo, clearing);
}
static int idecd_revalidate_disk(struct gendisk *disk)
@@ -1769,12 +1708,12 @@ static int idecd_revalidate_disk(struct gendisk *disk)
return 0;
}
-static struct block_device_operations idecd_ops = {
+static const struct block_device_operations idecd_ops = {
.owner = THIS_MODULE,
.open = idecd_open,
.release = idecd_release,
- .locked_ioctl = idecd_ioctl,
- .media_changed = idecd_media_changed,
+ .ioctl = idecd_ioctl,
+ .check_events = idecd_check_events,
.revalidate_disk = idecd_revalidate_disk
};
@@ -1817,7 +1756,7 @@ static int ide_cd_probe(ide_drive_t *drive)
info->dev.parent = &drive->gendev;
info->dev.release = ide_cd_release;
- dev_set_name(&info->dev, dev_name(&drive->gendev));
+ dev_set_name(&info->dev, "%s", dev_name(&drive->gendev));
if (device_register(&info->dev))
goto out_free_disk;
@@ -1840,7 +1779,7 @@ static int ide_cd_probe(ide_drive_t *drive)
ide_cd_read_toc(drive, &sense);
g->fops = &idecd_ops;
- g->flags |= GENHD_FL_REMOVABLE;
+ g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
add_disk(g);
return 0;
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index 1d97101099c..1efc936f5b6 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -87,10 +87,6 @@ struct cdrom_info {
struct atapi_toc *toc;
- /* The result of the last successful request sense command
- on this device. */
- struct request_sense sense_data;
-
u8 max_speed; /* Max speed of the drive. */
u8 current_speed; /* Current speed of the drive. */
@@ -115,7 +111,8 @@ int cdrom_check_status(ide_drive_t *, struct request_sense *);
int ide_cdrom_open_real(struct cdrom_device_info *, int);
void ide_cdrom_release_real(struct cdrom_device_info *);
int ide_cdrom_drive_status(struct cdrom_device_info *, int);
-int ide_cdrom_check_media_change_real(struct cdrom_device_info *, int);
+unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *,
+ unsigned int clearing, int slot_nr);
int ide_cdrom_tray_move(struct cdrom_device_info *, int);
int ide_cdrom_lock_door(struct cdrom_device_info *, int);
int ide_cdrom_select_speed(struct cdrom_device_info *, int);
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index df3df0041eb..02caa7dd51c 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -8,6 +8,7 @@
#include <linux/kernel.h>
#include <linux/cdrom.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
#include <scsi/scsi.h>
@@ -78,8 +79,14 @@ int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr)
return CDS_DRIVE_NOT_READY;
}
-int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
- int slot_nr)
+/*
+ * ide-cd always generates media changed event if media is missing, which
+ * makes it impossible to use for proper event reporting, so disk->events
+ * is cleared to 0 and the following function is used only to trigger
+ * revalidation and never propagated to userland.
+ */
+unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
+ unsigned int clearing, int slot_nr)
{
ide_drive_t *drive = cdi->handle;
int retval;
@@ -88,9 +95,9 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
(void) cdrom_check_status(drive, NULL);
retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
- return retval;
+ return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
} else {
- return -EINVAL;
+ return 0;
}
}
@@ -453,7 +460,7 @@ int ide_cdrom_packet(struct cdrom_device_info *cdi,
touch it at all. */
if (cgc->data_direction == CGC_DATA_WRITE)
- flags |= REQ_RW;
+ flags |= REQ_WRITE;
if (cgc->sense)
memset(cgc->sense, 0, sizeof(struct request_sense));
diff --git a/drivers/ide/ide-cd_verbose.c b/drivers/ide/ide-cd_verbose.c
index 6490a2dea96..f079ca2f260 100644
--- a/drivers/ide/ide-cd_verbose.c
+++ b/drivers/ide/ide-cd_verbose.c
@@ -9,7 +9,9 @@
#include <linux/kernel.h>
#include <linux/blkdev.h>
#include <linux/cdrom.h>
+#include <linux/ide.h>
#include <scsi/scsi.h>
+#include "ide-cd.h"
#ifndef CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS
void ide_cd_log_error(const char *name, struct request *failed_command,
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 9e47f3529d5..f1e922e2479 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -41,10 +41,7 @@
#include <linux/major.h>
#include <linux/delay.h>
#include <asm/io.h>
-#include <asm/system.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>
@@ -60,22 +57,12 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
MODULE_LICENSE("Dual MPL/GPL");
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-#ifdef CONFIG_PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
-
/*====================================================================*/
typedef struct ide_info_t {
struct pcmcia_device *p_dev;
struct ide_host *host;
- int ndev;
- dev_node_t node;
+ int ndev;
} ide_info_t;
static void ide_release(struct pcmcia_device *);
@@ -83,22 +70,11 @@ static int ide_config(struct pcmcia_device *);
static void ide_detach(struct pcmcia_device *p_dev);
-
-
-
-/*======================================================================
-
- ide_attach() creates an "instance" of the driver, allocating
- local data structures for one device. The device is registered
- with Card Services.
-
-======================================================================*/
-
static int ide_probe(struct pcmcia_device *link)
{
ide_info_t *info;
- DEBUG(0, "ide_attach()\n");
+ dev_dbg(&link->dev, "ide_attach()\n");
/* Create new ide device */
info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -108,42 +84,20 @@ static int ide_probe(struct pcmcia_device *link)
info->p_dev = link;
link->priv = info;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = 3;
- link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
- link->irq.IRQInfo1 = IRQ_LEVEL_ID;
- link->conf.Attributes = CONF_ENABLE_IRQ;
- link->conf.IntType = INT_MEMORY_AND_IO;
+ link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO |
+ CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
return ide_config(link);
} /* ide_attach */
-/*======================================================================
-
- This deletes a driver "instance". The device is de-registered
- with Card Services. If it has been released, all local data
- structures are freed. Otherwise, the structures will be freed
- when the device is released.
-
-======================================================================*/
-
static void ide_detach(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
- ide_hwif_t *hwif = info->host->ports[0];
- unsigned long data_addr, ctl_addr;
-
- DEBUG(0, "ide_detach(0x%p)\n", link);
- data_addr = hwif->io_ports.data_addr;
- ctl_addr = hwif->io_ports.ctl_addr;
+ dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
ide_release(link);
- release_region(ctl_addr, 1);
- release_region(data_addr, 8);
-
kfree(info);
} /* ide_detach */
@@ -155,6 +109,7 @@ static const struct ide_port_info idecs_port_info = {
.port_ops = &idecs_port_ops,
.host_flags = IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
+ .chipset = ide_pci,
};
static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
@@ -163,7 +118,7 @@ static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
struct ide_host *host;
ide_hwif_t *hwif;
int i, rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
if (!request_region(io, 8, DRV_NAME)) {
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
@@ -181,10 +136,9 @@ static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, io, ctl);
hw.irq = irq;
- hw.chipset = ide_pci;
hw.dev = &handle->dev;
- rc = ide_host_add(&idecs_port_info, hws, &host);
+ rc = ide_host_add(&idecs_port_info, hws, 1, &host);
if (rc)
goto out_release;
@@ -209,105 +163,59 @@ out_release:
return NULL;
}
-/*======================================================================
-
- ide_config() is scheduled to run after a CARD_INSERTION event
- is received, to configure the PCMCIA socket, and to make the
- ide device available to the system.
-
-======================================================================*/
-
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-struct pcmcia_config_check {
- unsigned long ctl_base;
- int skip_vcc;
- int is_kme;
-};
-
-static int pcmcia_check_one_config(struct pcmcia_device *pdev,
- cistpl_cftable_entry_t *cfg,
- cistpl_cftable_entry_t *dflt,
- unsigned int vcc,
- void *priv_data)
+static int pcmcia_check_one_config(struct pcmcia_device *pdev, void *priv_data)
{
- struct pcmcia_config_check *stk = priv_data;
-
- /* Check for matching Vcc, unless we're desperate */
- if (!stk->skip_vcc) {
- if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
- if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000)
- return -ENODEV;
- } else if (dflt->vcc.present & (1 << CISTPL_POWER_VNOM)) {
- if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM] / 10000)
- return -ENODEV;
- }
- }
+ int *is_kme = priv_data;
- if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
- pdev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
- else if (dflt->vpp1.present & (1 << CISTPL_POWER_VNOM))
- pdev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-
- if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
- pdev->conf.ConfigIndex = cfg->index;
- pdev->io.BasePort1 = io->win[0].base;
- pdev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (!(io->flags & CISTPL_IO_16BIT))
- pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- if (io->nwin == 2) {
- pdev->io.NumPorts1 = 8;
- pdev->io.BasePort2 = io->win[1].base;
- pdev->io.NumPorts2 = (stk->is_kme) ? 2 : 1;
- if (pcmcia_request_io(pdev, &pdev->io) != 0)
- return -ENODEV;
- stk->ctl_base = pdev->io.BasePort2;
- } else if ((io->nwin == 1) && (io->win[0].len >= 16)) {
- pdev->io.NumPorts1 = io->win[0].len;
- pdev->io.NumPorts2 = 0;
- if (pcmcia_request_io(pdev, &pdev->io) != 0)
- return -ENODEV;
- stk->ctl_base = pdev->io.BasePort1 + 0x0e;
- } else
+ if ((pdev->resource[0]->flags & IO_DATA_PATH_WIDTH)
+ != IO_DATA_PATH_WIDTH_8) {
+ pdev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ pdev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+ }
+ pdev->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+ pdev->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+
+ if (pdev->resource[1]->end) {
+ pdev->resource[0]->end = 8;
+ pdev->resource[1]->end = (*is_kme) ? 2 : 1;
+ } else {
+ if (pdev->resource[0]->end < 16)
return -ENODEV;
- /* If we've got this far, we're done */
- return 0;
}
- return -ENODEV;
+
+ return pcmcia_request_io(pdev);
}
static int ide_config(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
- struct pcmcia_config_check *stk = NULL;
- int last_ret = 0, last_fn = 0, is_kme = 0;
+ int ret = 0, is_kme = 0;
unsigned long io_base, ctl_base;
struct ide_host *host;
- DEBUG(0, "ide_config(0x%p)\n", link);
+ dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
is_kme = ((link->manf_id == MANFID_KME) &&
((link->card_id == PRODID_KME_KXLC005_A) ||
(link->card_id == PRODID_KME_KXLC005_B)));
- stk = kzalloc(sizeof(*stk), GFP_KERNEL);
- if (!stk)
- goto err_mem;
- stk->is_kme = is_kme;
- stk->skip_vcc = io_base = ctl_base = 0;
-
- if (pcmcia_loop_config(link, pcmcia_check_one_config, stk)) {
- stk->skip_vcc = 1;
- if (pcmcia_loop_config(link, pcmcia_check_one_config, stk))
+ if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme)) {
+ link->config_flags &= ~CONF_AUTO_CHECK_VCC;
+ if (pcmcia_loop_config(link, pcmcia_check_one_config, &is_kme))
goto failed; /* No suitable config found */
}
- io_base = link->io.BasePort1;
- ctl_base = stk->ctl_base;
+ io_base = link->resource[0]->start;
+ if (link->resource[1]->end)
+ ctl_base = link->resource[1]->start;
+ else
+ ctl_base = link->resource[0]->start + 0x0e;
+
+ if (!link->irq)
+ goto failed;
- CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
- CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+ ret = pcmcia_enable_device(link);
+ if (ret)
+ goto failed;
/* disable drive interrupts during IDE probe */
outb(0x02, ctl_base);
@@ -316,76 +224,55 @@ static int ide_config(struct pcmcia_device *link)
if (is_kme)
outb(0x81, ctl_base+1);
- host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link);
- if (host == NULL && link->io.NumPorts1 == 0x20) {
+ host = idecs_register(io_base, ctl_base, link->irq, link);
+ if (host == NULL && resource_size(link->resource[0]) == 0x20) {
outb(0x02, ctl_base + 0x10);
host = idecs_register(io_base + 0x10, ctl_base + 0x10,
- link->irq.AssignedIRQ, link);
+ link->irq, link);
}
if (host == NULL)
goto failed;
info->ndev = 1;
- sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2);
- info->node.major = host->ports[0]->major;
- info->node.minor = 0;
info->host = host;
- link->dev_node = &info->node;
- printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n",
- info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10);
+ dev_info(&link->dev, "ide-cs: hd%c: Vpp = %d.%d\n",
+ 'a' + host->ports[0]->index * 2,
+ link->vpp / 10, link->vpp % 10);
- kfree(stk);
return 0;
-err_mem:
- printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
- goto failed;
-
-cs_failed:
- cs_error(link, last_fn, last_ret);
failed:
- kfree(stk);
ide_release(link);
return -ENODEV;
} /* ide_config */
-/*======================================================================
-
- After a card is removed, ide_release() will unregister the net
- device, and release the PCMCIA configuration. If the device is
- still open, this will be postponed until it is closed.
-
-======================================================================*/
-
static void ide_release(struct pcmcia_device *link)
{
ide_info_t *info = link->priv;
struct ide_host *host = info->host;
- DEBUG(0, "ide_release(0x%p)\n", link);
+ dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
+
+ if (info->ndev) {
+ ide_hwif_t *hwif = host->ports[0];
+ unsigned long data_addr, ctl_addr;
+
+ data_addr = hwif->io_ports.data_addr;
+ ctl_addr = hwif->io_ports.ctl_addr;
- if (info->ndev)
- /* FIXME: if this fails we need to queue the cleanup somehow
- -- need to investigate the required PCMCIA magic */
ide_host_remove(host);
+ info->ndev = 0;
- info->ndev = 0;
+ release_region(ctl_addr, 1);
+ release_region(data_addr, 8);
+ }
pcmcia_disable_device(link);
} /* ide_release */
-/*======================================================================
-
- The card status event handler. Mostly, this schedules other
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the ide drivers from
- talking to the ports.
-
-======================================================================*/
-
-static struct pcmcia_device_id ide_ids[] = {
+static const struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_FUNC_ID(4),
PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000), /* Corsair */
PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000), /* Hitachi */
@@ -408,6 +295,7 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
+ PCMCIA_DEVICE_PROD_ID12("CNF ", "CD-ROM", 0x46d7db81, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
@@ -420,6 +308,8 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Hyperstone", "Model1", 0x3d5b9ef5, 0xca6ab420),
PCMCIA_DEVICE_PROD_ID12("IBM", "microdrive", 0xb569a6e5, 0xa6d76178),
PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),
+ PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 1GB", 0x2e6d1829, 0x55d5bffb),
+ PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF CARD 4GB", 0x2e6d1829, 0x531e7d10),
PCMCIA_DEVICE_PROD_ID12("KINGSTON", "CF8GB", 0x2e6d1829, 0xacbe682e),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2 ", 0x547e66dc, 0x8671043b),
PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149),
@@ -440,6 +330,8 @@ static struct pcmcia_device_id ide_ids[] = {
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS2GCF120", 0x709b1bf1, 0x969aa4f2),
PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF133", 0x709b1bf1, 0x7558f133),
+ PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS8GCF133", 0x709b1bf1, 0xb2f89b47),
PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852),
PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918),
PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209),
@@ -452,9 +344,7 @@ MODULE_DEVICE_TABLE(pcmcia, ide_ids);
static struct pcmcia_driver ide_cs_driver = {
.owner = THIS_MODULE,
- .drv = {
- .name = "ide-cs",
- },
+ .name = "ide-cs",
.probe = ide_probe,
.remove = ide_detach,
.id_table = ide_ids,
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
index 5bf958e5b1d..9e98122f646 100644
--- a/drivers/ide/ide-devsets.c
+++ b/drivers/ide/ide-devsets.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
DEFINE_MUTEX(ide_setting_mtx);
@@ -105,15 +106,17 @@ static int set_pio_mode(ide_drive_t *drive, int arg)
return -ENOSYS;
if (set_pio_mode_abuse(drive->hwif, arg)) {
+ drive->pio_mode = arg + XFER_PIO_0;
+
if (arg == 8 || arg == 9) {
unsigned long flags;
/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
spin_lock_irqsave(&hwif->lock, flags);
- port_ops->set_pio_mode(drive, arg);
+ port_ops->set_pio_mode(hwif, drive);
spin_unlock_irqrestore(&hwif->lock, flags);
} else
- port_ops->set_pio_mode(drive, arg);
+ port_ops->set_pio_mode(hwif, drive);
} else {
int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
@@ -183,6 +186,6 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
err = setfunc(drive, *(int *)&rq->cmd[1]);
if (err)
rq->errors = err;
- ide_complete_rq(drive, err, ide_rq_bytes(rq));
+ ide_complete_rq(drive, err, blk_rq_bytes(rq));
return ide_stopped;
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index a9fbe2c3121..ee880382e3b 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -82,7 +82,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
sector_t block)
{
ide_hwif_t *hwif = drive->hwif;
- u16 nsectors = (u16)rq->nr_sectors;
+ u16 nsectors = (u16)blk_rq_sectors(rq);
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
struct ide_cmd cmd;
@@ -90,7 +90,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
ide_startstop_t rc;
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
- if (block + rq->nr_sectors > 1ULL << 28)
+ if (block + blk_rq_sectors(rq) > 1ULL << 28)
dma = 0;
else
lba48 = 0;
@@ -184,21 +184,13 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
ide_hwif_t *hwif = drive->hwif;
BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED);
-
- if (!blk_fs_request(rq)) {
- blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
- if (rq->errors == 0)
- rq->errors = -EIO;
- ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
- return ide_stopped;
- }
+ BUG_ON(rq->cmd_type != REQ_TYPE_FS);
ledtrig_ide_activity();
- pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
+ pr_debug("%s: %sing: block=%llu, sectors=%u\n",
drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
- (unsigned long long)block, rq->nr_sectors,
- (unsigned long)rq->buffer);
+ (unsigned long long)block, blk_rq_sectors(rq));
if (hwif->rw_disk)
hwif->rw_disk(drive, rq);
@@ -302,14 +294,12 @@ static const struct drive_list_entry hpa_list[] = {
{ NULL, NULL }
};
-static void idedisk_check_hpa(ide_drive_t *drive)
+static u64 ide_disk_hpa_get_native_capacity(ide_drive_t *drive, int lba48)
{
- unsigned long long capacity, set_max;
- int lba48 = ata_id_lba48_enabled(drive->id);
+ u64 capacity, set_max;
capacity = drive->capacity64;
-
- set_max = idedisk_read_native_max_address(drive, lba48);
+ set_max = idedisk_read_native_max_address(drive, lba48);
if (ide_in_drive_list(drive->id, hpa_list)) {
/*
@@ -320,9 +310,31 @@ static void idedisk_check_hpa(ide_drive_t *drive)
set_max--;
}
+ return set_max;
+}
+
+static u64 ide_disk_hpa_set_capacity(ide_drive_t *drive, u64 set_max, int lba48)
+{
+ set_max = idedisk_set_max_address(drive, set_max, lba48);
+ if (set_max)
+ drive->capacity64 = set_max;
+
+ return set_max;
+}
+
+static void idedisk_check_hpa(ide_drive_t *drive)
+{
+ u64 capacity, set_max;
+ int lba48 = ata_id_lba48_enabled(drive->id);
+
+ capacity = drive->capacity64;
+ set_max = ide_disk_hpa_get_native_capacity(drive, lba48);
+
if (set_max <= capacity)
return;
+ drive->probed_capacity = set_max;
+
printk(KERN_INFO "%s: Host Protected Area detected.\n"
"\tcurrent capacity is %llu sectors (%llu MB)\n"
"\tnative capacity is %llu sectors (%llu MB)\n",
@@ -330,13 +342,13 @@ static void idedisk_check_hpa(ide_drive_t *drive)
capacity, sectors_to_MB(capacity),
set_max, sectors_to_MB(set_max));
- set_max = idedisk_set_max_address(drive, set_max, lba48);
+ if ((drive->dev_flags & IDE_DFLAG_NOHPA) == 0)
+ return;
- if (set_max) {
- drive->capacity64 = set_max;
+ set_max = ide_disk_hpa_set_capacity(drive, set_max, lba48);
+ if (set_max)
printk(KERN_INFO "%s: Host Protected Area disabled.\n",
drive->name);
- }
}
static int ide_disk_get_capacity(ide_drive_t *drive)
@@ -358,6 +370,8 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
drive->capacity64 = drive->cyl * drive->head * drive->sect;
}
+ drive->probed_capacity = drive->capacity64;
+
if (lba) {
drive->dev_flags |= IDE_DFLAG_LBA;
@@ -376,7 +390,7 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
"%llu sectors (%llu MB)\n",
drive->name, (unsigned long long)drive->capacity64,
sectors_to_MB(drive->capacity64));
- drive->capacity64 = 1ULL << 28;
+ drive->probed_capacity = drive->capacity64 = 1ULL << 28;
}
if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
@@ -392,15 +406,44 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
return 0;
}
-static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
+static void ide_disk_unlock_native_capacity(ide_drive_t *drive)
+{
+ u16 *id = drive->id;
+ int lba48 = ata_id_lba48_enabled(id);
+
+ if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 ||
+ ata_id_hpa_enabled(id) == 0)
+ return;
+
+ /*
+ * according to the spec the SET MAX ADDRESS command shall be
+ * immediately preceded by a READ NATIVE MAX ADDRESS command
+ */
+ if (!ide_disk_hpa_get_native_capacity(drive, lba48))
+ return;
+
+ if (ide_disk_hpa_set_capacity(drive, drive->probed_capacity, lba48))
+ drive->dev_flags |= IDE_DFLAG_NOHPA; /* disable HPA on resume */
+}
+
+static int idedisk_prep_fn(struct request_queue *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
- struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
+ struct ide_cmd *cmd;
+
+ if (!(rq->cmd_flags & REQ_FLUSH))
+ return BLKPREP_OK;
+
+ if (rq->special) {
+ cmd = rq->special;
+ memset(cmd, 0, sizeof(*cmd));
+ } else {
+ cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+ }
/* FIXME: map struct ide_taskfile on rq->cmd[] */
BUG_ON(cmd == NULL);
- memset(cmd, 0, sizeof(*cmd));
if (ata_id_flush_ext_enabled(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
cmd->tf.command = ATA_CMD_FLUSH_EXT;
@@ -411,8 +454,10 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
- rq->cmd_flags |= REQ_SOFTBARRIER;
rq->special = cmd;
+ cmd->rq = rq;
+
+ return BLKPREP_OK;
}
ide_devset_get(multcount, mult_count);
@@ -429,14 +474,14 @@ static int set_multcount(ide_drive_t *drive, int arg)
if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff))
return -EINVAL;
- if (drive->special.b.set_multmode)
+ if (drive->special_flags & IDE_SFLAG_SET_MULTMODE)
return -EBUSY;
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
drive->mult_req = arg;
- drive->special.b.set_multmode = 1;
+ drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
@@ -474,11 +519,10 @@ static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
return ide_no_data_taskfile(drive, &cmd);
}
-static void update_ordered(ide_drive_t *drive)
+static void update_flush(ide_drive_t *drive)
{
u16 *id = drive->id;
- unsigned ordered = QUEUE_ORDERED_NONE;
- prepare_flush_fn *prep_fn = NULL;
+ unsigned flush = 0;
if (drive->dev_flags & IDE_DFLAG_WCACHE) {
unsigned long long capacity;
@@ -502,13 +546,12 @@ static void update_ordered(ide_drive_t *drive)
drive->name, barrier ? "" : "not ");
if (barrier) {
- ordered = QUEUE_ORDERED_DRAIN_FLUSH;
- prep_fn = idedisk_prepare_flush;
+ flush = REQ_FLUSH;
+ blk_queue_prep_rq(drive->queue, idedisk_prep_fn);
}
- } else
- ordered = QUEUE_ORDERED_DRAIN;
+ }
- blk_queue_ordered(drive->queue, ordered, prep_fn);
+ blk_queue_flush(drive->queue, flush);
}
ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE);
@@ -531,7 +574,7 @@ static int set_wcache(ide_drive_t *drive, int arg)
}
}
- update_ordered(drive);
+ update_flush(drive);
return err;
}
@@ -636,11 +679,11 @@ static void ide_disk_setup(ide_drive_t *drive)
if (max_s > hwif->rqsize)
max_s = hwif->rqsize;
- blk_queue_max_sectors(q, max_s);
+ blk_queue_max_hw_sectors(q, max_s);
}
printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
- q->max_sectors / 2);
+ queue_max_sectors(q) / 2);
if (ata_id_is_ssd(id))
queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
@@ -740,12 +783,13 @@ static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
}
const struct ide_disk_ops ide_ata_disk_ops = {
- .check = ide_disk_check,
- .get_capacity = ide_disk_get_capacity,
- .setup = ide_disk_setup,
- .flush = ide_disk_flush,
- .init_media = ide_disk_init_media,
- .set_doorlock = ide_disk_set_doorlock,
- .do_request = ide_do_rw_disk,
- .ioctl = ide_disk_ioctl,
+ .check = ide_disk_check,
+ .unlock_native_capacity = ide_disk_unlock_native_capacity,
+ .get_capacity = ide_disk_get_capacity,
+ .setup = ide_disk_setup,
+ .flush = ide_disk_flush,
+ .init_media = ide_disk_init_media,
+ .set_doorlock = ide_disk_set_doorlock,
+ .do_request = ide_do_rw_disk,
+ .ioctl = ide_disk_ioctl,
};
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c
index 7b783dd7c0b..da36f729ff3 100644
--- a/drivers/ide/ide-disk_ioctl.c
+++ b/drivers/ide/ide-disk_ioctl.c
@@ -1,9 +1,11 @@
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/hdreg.h>
+#include <linux/mutex.h>
#include "ide-disk.h"
+static DEFINE_MUTEX(ide_disk_ioctl_mutex);
static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
{ HDIO_GET_ADDRESS, HDIO_SET_ADDRESS, &ide_devset_address },
{ HDIO_GET_MULTCOUNT, HDIO_SET_MULTCOUNT, &ide_devset_multcount },
@@ -18,9 +20,13 @@ int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode,
{
int err;
+ mutex_lock(&ide_disk_ioctl_mutex);
err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
if (err != -EOPNOTSUPP)
- return err;
+ goto out;
- return generic_ide_ioctl(drive, bdev, cmd, arg);
+ err = generic_ide_ioctl(drive, bdev, cmd, arg);
+out:
+ mutex_unlock(&ide_disk_ioctl_mutex);
+ return err;
}
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 19f263bf0a9..0d1fae6cba6 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -1,5 +1,8 @@
#include <linux/kernel.h>
#include <linux/ide.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/seq_file.h>
#include "ide-disk.h"
@@ -37,77 +40,117 @@ static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
return ide_raw_taskfile(drive, &cmd, buf, 1);
}
-static int proc_idedisk_read_cache
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idedisk_cache_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t *drive = (ide_drive_t *) data;
- char *out = page;
- int len;
+ ide_drive_t *drive = (ide_drive_t *) m->private;
if (drive->dev_flags & IDE_DFLAG_ID_READ)
- len = sprintf(out, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
+ seq_printf(m, "%i\n", drive->id[ATA_ID_BUF_SIZE] / 2);
else
- len = sprintf(out, "(none)\n");
+ seq_printf(m, "(none)\n");
+ return 0;
+}
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int idedisk_cache_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, idedisk_cache_proc_show, PDE_DATA(inode));
}
-static int proc_idedisk_read_capacity
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations idedisk_cache_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idedisk_cache_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int idedisk_capacity_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t*drive = (ide_drive_t *)data;
- int len;
+ ide_drive_t*drive = (ide_drive_t *)m->private;
- len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
+ seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
+ return 0;
+}
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int idedisk_capacity_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, idedisk_capacity_proc_show, PDE_DATA(inode));
}
-static int proc_idedisk_read_smart(char *page, char **start, off_t off,
- int count, int *eof, void *data, u8 sub_cmd)
+static const struct file_operations idedisk_capacity_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idedisk_capacity_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __idedisk_proc_show(struct seq_file *m, ide_drive_t *drive, u8 sub_cmd)
{
- ide_drive_t *drive = (ide_drive_t *)data;
- int len = 0, i = 0;
+ u8 *buf;
+
+ buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
(void)smart_enable(drive);
- if (get_smart_data(drive, page, sub_cmd) == 0) {
- unsigned short *val = (unsigned short *) page;
- char *out = (char *)val + SECTOR_SIZE;
-
- page = out;
- do {
- out += sprintf(out, "%04x%c", le16_to_cpu(*val),
- (++i & 7) ? ' ' : '\n');
- val += 1;
- } while (i < SECTOR_SIZE / 2);
- len = out - page;
+ if (get_smart_data(drive, buf, sub_cmd) == 0) {
+ __le16 *val = (__le16 *)buf;
+ int i;
+
+ for (i = 0; i < SECTOR_SIZE / 2; i++) {
+ seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
+ (i % 8) == 7 ? '\n' : ' ');
+ }
}
+ kfree(buf);
+ return 0;
+}
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int idedisk_sv_proc_show(struct seq_file *m, void *v)
+{
+ return __idedisk_proc_show(m, m->private, ATA_SMART_READ_VALUES);
}
-static int proc_idedisk_read_sv
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idedisk_sv_proc_open(struct inode *inode, struct file *file)
{
- return proc_idedisk_read_smart(page, start, off, count, eof, data,
- ATA_SMART_READ_VALUES);
+ return single_open(file, idedisk_sv_proc_show, PDE_DATA(inode));
}
-static int proc_idedisk_read_st
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations idedisk_sv_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idedisk_sv_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int idedisk_st_proc_show(struct seq_file *m, void *v)
{
- return proc_idedisk_read_smart(page, start, off, count, eof, data,
- ATA_SMART_READ_THRESHOLDS);
+ return __idedisk_proc_show(m, m->private, ATA_SMART_READ_THRESHOLDS);
}
+static int idedisk_st_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, idedisk_st_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations idedisk_st_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idedisk_st_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
ide_proc_entry_t ide_disk_proc[] = {
- { "cache", S_IFREG|S_IRUGO, proc_idedisk_read_cache, NULL },
- { "capacity", S_IFREG|S_IRUGO, proc_idedisk_read_capacity, NULL },
- { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
- { "smart_values", S_IFREG|S_IRUSR, proc_idedisk_read_sv, NULL },
- { "smart_thresholds", S_IFREG|S_IRUSR, proc_idedisk_read_st, NULL },
- { NULL, 0, NULL, NULL }
+ { "cache", S_IFREG|S_IRUGO, &idedisk_cache_proc_fops },
+ { "capacity", S_IFREG|S_IRUGO, &idedisk_capacity_proc_fops },
+ { "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops },
+ { "smart_values", S_IFREG|S_IRUSR, &idedisk_sv_proc_fops },
+ { "smart_thresholds", S_IFREG|S_IRUSR, &idedisk_st_proc_fops },
+ {}
};
ide_devset_rw_field(bios_cyl, bios_cyl);
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index e4cdf78cc3e..289d16c87b8 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -1,5 +1,6 @@
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index a0b8cab1d9a..17a65ac5649 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -29,7 +29,9 @@
*/
#include <linux/types.h>
+#include <linux/gfp.h>
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
@@ -103,7 +105,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive)
ide_finish_cmd(drive, cmd, stat);
else
ide_complete_rq(drive, 0,
- cmd->rq->nr_sectors << 9);
+ blk_rq_sectors(cmd->rq) << 9);
return ide_stopped;
}
printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
@@ -347,7 +349,6 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode)
return mode;
}
-EXPORT_SYMBOL_GPL(ide_find_dma_mode);
static int ide_tune_dma(ide_drive_t *drive)
{
@@ -362,9 +363,6 @@ static int ide_tune_dma(ide_drive_t *drive)
if (__ide_dma_bad_drive(drive))
return 0;
- if (ide_id_dma_bug(drive))
- return 0;
-
if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
return config_drive_for_dma(drive);
@@ -395,24 +393,6 @@ static int ide_dma_check(ide_drive_t *drive)
return -1;
}
-int ide_id_dma_bug(ide_drive_t *drive)
-{
- u16 *id = drive->id;
-
- if (id[ATA_ID_FIELD_VALID] & 4) {
- if ((id[ATA_ID_UDMA_MODES] >> 8) &&
- (id[ATA_ID_MWDMA_MODES] >> 8))
- goto err_out;
- } else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
- (id[ATA_ID_SWDMA_MODES] >> 8))
- goto err_out;
-
- return 0;
-err_out:
- printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
- return 1;
-}
-
int ide_set_dma(ide_drive_t *drive)
{
int rc;
@@ -470,7 +450,6 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
ide_hwif_t *hwif = drive->hwif;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
struct ide_cmd *cmd = &hwif->cmd;
- struct request *rq;
ide_startstop_t ret = ide_stopped;
/*
@@ -508,25 +487,10 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
ide_dma_off_quietly(drive);
/*
- * un-busy drive etc and make sure request is sane
+ * make sure request is sane
*/
-
- rq = hwif->rq;
- if (!rq)
- goto out;
-
- hwif->rq = NULL;
-
- rq->errors = 0;
-
- if (!rq->bio)
- goto out;
-
- rq->sector = rq->bio->bi_sector;
- rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->buffer = bio_data(rq->bio);
-out:
+ if (hwif->rq)
+ hwif->rq->errors = 0;
return ret;
}
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
index 5d5fb961b5c..32970664c27 100644
--- a/drivers/ide/ide-eh.c
+++ b/drivers/ide/ide-eh.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/ide.h>
#include <linux/delay.h>
@@ -52,7 +53,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq,
}
if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
+ drive->special_flags |= IDE_SFLAG_RECALIBRATE;
++rq->errors;
@@ -122,7 +123,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
return ide_stopped;
/* retry only "normal" I/O: */
- if (!blk_fs_request(rq)) {
+ if (rq->cmd_type != REQ_TYPE_FS) {
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
struct ide_cmd *cmd = rq->special;
@@ -146,10 +147,11 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
{
struct request *rq = drive->hwif->rq;
- if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) {
+ if (rq && rq->cmd_type == REQ_TYPE_SPECIAL &&
+ rq->cmd[0] == REQ_DRIVE_RESET) {
if (err <= 0 && rq->errors == 0)
rq->errors = -EIO;
- ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq));
+ ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq));
}
}
@@ -268,9 +270,8 @@ static void ide_disk_pre_reset(ide_drive_t *drive)
{
int legacy = (drive->id[ATA_ID_CFS_ENABLE_2] & 0x0400) ? 0 : 1;
- drive->special.all = 0;
- drive->special.b.set_geometry = legacy;
- drive->special.b.recalibrate = legacy;
+ drive->special_flags =
+ legacy ? (IDE_SFLAG_SET_GEOMETRY | IDE_SFLAG_RECALIBRATE) : 0;
drive->mult_count = 0;
drive->dev_flags &= ~IDE_DFLAG_PARKED;
@@ -280,7 +281,7 @@ static void ide_disk_pre_reset(ide_drive_t *drive)
drive->mult_req = 0;
if (drive->mult_req != drive->mult_count)
- drive->special.b.set_multmode = 1;
+ drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
}
static void pre_reset(ide_drive_t *drive)
@@ -408,8 +409,9 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
/* more than enough time */
udelay(10);
/* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 0 : ATA_NIEN) |
- ATA_DEVCTL_OBS);
+ tp_ops->write_devctl(hwif,
+ ((drive->dev_flags & IDE_DFLAG_NIEN_QUIRK) ? 0 : ATA_NIEN) |
+ ATA_DEVCTL_OBS);
/* more than enough time */
udelay(10);
hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 2b4868d95f8..3d42043fec5 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -25,7 +25,6 @@
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
-#include <linux/slab.h>
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/hdreg.h>
@@ -36,7 +35,6 @@
#include <scsi/scsi_ioctl.h>
#include <asm/byteorder.h>
-#include <linux/irq.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <asm/unaligned.h>
@@ -74,10 +72,11 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
drive->failed_pc = NULL;
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
- (rq && blk_pc_request(rq)))
+ rq->cmd_type == REQ_TYPE_BLOCK_PC)
uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
- u8 *buf = pc->buf;
+
+ u8 *buf = bio_data(rq->bio);
if (!pc->error) {
floppy->sense_key = buf[2] & 0x0F;
@@ -98,7 +97,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
"Aborting request!\n");
}
- if (blk_special_request(rq))
+ if (rq->cmd_type == REQ_TYPE_SPECIAL)
rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
return uptodate;
@@ -107,7 +106,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
static void ide_floppy_report_error(struct ide_disk_obj *floppy,
struct ide_atapi_pc *pc)
{
- /* supress error messages resulting from Medium not present */
+ /* suppress error messages resulting from Medium not present */
if (floppy->sense_key == 0x02 &&
floppy->asc == 0x3a &&
floppy->ascq == 0x00)
@@ -134,13 +133,17 @@ static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
drive->pc = pc;
if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) {
+ unsigned int done = blk_rq_bytes(drive->hwif->rq);
+
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc);
+
/* Giving up */
pc->error = IDE_DRV_ERROR_GENERAL;
drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
+ ide_complete_rq(drive, -EIO, done);
return ide_stopped;
}
@@ -190,7 +193,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
{
struct ide_disk_obj *floppy = drive->driver_data;
int block = sector / floppy->bs_factor;
- int blocks = rq->nr_sectors / floppy->bs_factor;
+ int blocks = blk_rq_sectors(rq) / floppy->bs_factor;
int cmd = rq_data_dir(rq);
ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
@@ -203,10 +206,9 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
memcpy(rq->cmd, pc->c, 12);
pc->rq = rq;
- if (rq->cmd_flags & REQ_RW)
+ if (rq->cmd_flags & REQ_WRITE)
pc->flags |= PC_FLAG_WRITING;
- pc->buf = NULL;
- pc->req_xfer = pc->buf_size = blocks * floppy->block_size;
+
pc->flags |= PC_FLAG_DMA_OK;
}
@@ -216,16 +218,11 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
- if (rq->data_len && rq_data_dir(rq) == WRITE)
- pc->flags |= PC_FLAG_WRITING;
- pc->buf = rq->data;
- if (rq->bio)
+ if (blk_rq_bytes(rq)) {
pc->flags |= PC_FLAG_DMA_OK;
- /*
- * possibly problematic, doesn't look like ide-floppy correctly
- * handled scattered requests if dma fails...
- */
- pc->req_xfer = pc->buf_size = rq->data_len;
+ if (rq_data_dir(rq) == WRITE)
+ pc->flags |= PC_FLAG_WRITING;
+ }
}
static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
@@ -249,32 +246,39 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
} else
printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
- if (blk_special_request(rq)) {
+ if (rq->cmd_type == REQ_TYPE_SPECIAL) {
rq->errors = 0;
ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
} else
goto out_end;
}
- if (blk_fs_request(rq)) {
- if (((long)rq->sector % floppy->bs_factor) ||
- (rq->nr_sectors % floppy->bs_factor)) {
+
+ switch (rq->cmd_type) {
+ case REQ_TYPE_FS:
+ if (((long)blk_rq_pos(rq) % floppy->bs_factor) ||
+ (blk_rq_sectors(rq) % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
goto out_end;
}
pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
- } else if (blk_special_request(rq)) {
- pc = (struct ide_atapi_pc *) rq->buffer;
- } else if (blk_pc_request(rq)) {
+ break;
+ case REQ_TYPE_SPECIAL:
+ case REQ_TYPE_SENSE:
+ pc = (struct ide_atapi_pc *)rq->special;
+ break;
+ case REQ_TYPE_BLOCK_PC:
pc = &floppy->queued_pc;
idefloppy_blockpc_cmd(floppy, pc, rq);
- } else {
- blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- goto out_end;
+ break;
+ default:
+ BUG();
}
+ ide_prep_sense(drive, rq);
+
memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq))
@@ -282,8 +286,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
cmd.rq = rq;
- if (blk_fs_request(rq) || pc->req_xfer) {
- ide_init_sg_cmd(&cmd, pc->req_xfer);
+ if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) {
+ ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
ide_map_sg(drive, &cmd);
}
@@ -292,9 +296,9 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
return ide_floppy_issue_pc(drive, &cmd, pc);
out_end:
drive->failed_pc = NULL;
- if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ if (rq->cmd_type != REQ_TYPE_FS && rq->errors == 0)
rq->errors = -EIO;
- ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+ ide_complete_rq(drive, -EIO, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -307,33 +311,33 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive,
{
struct ide_disk_obj *floppy = drive->driver_data;
struct gendisk *disk = floppy->disk;
- u8 *page;
+ u8 *page, buf[40];
int capacity, lba_capacity;
u16 transfer_rate, sector_size, cyls, rpm;
u8 heads, sectors;
ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE);
- if (ide_queue_pc_tail(drive, disk, pc)) {
+ if (ide_queue_pc_tail(drive, disk, pc, buf, pc->req_xfer)) {
printk(KERN_ERR PFX "Can't get flexible disk page params\n");
return 1;
}
- if (pc->buf[3] & 0x80)
+ if (buf[3] & 0x80)
drive->dev_flags |= IDE_DFLAG_WP;
else
drive->dev_flags &= ~IDE_DFLAG_WP;
set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP));
- page = &pc->buf[8];
+ page = &buf[8];
- transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]);
- sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]);
- cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]);
- rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]);
- heads = pc->buf[8 + 4];
- sectors = pc->buf[8 + 5];
+ transfer_rate = be16_to_cpup((__be16 *)&buf[8 + 2]);
+ sector_size = be16_to_cpup((__be16 *)&buf[8 + 6]);
+ cyls = be16_to_cpup((__be16 *)&buf[8 + 8]);
+ rpm = be16_to_cpup((__be16 *)&buf[8 + 28]);
+ heads = buf[8 + 4];
+ sectors = buf[8 + 5];
capacity = cyls * heads * sectors * sector_size;
@@ -383,22 +387,19 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive->capacity64 = 0;
ide_floppy_create_read_capacity_cmd(&pc);
- pc.buf = &pc_buf[0];
- pc.buf_size = sizeof(pc_buf);
-
- if (ide_queue_pc_tail(drive, disk, &pc)) {
+ if (ide_queue_pc_tail(drive, disk, &pc, pc_buf, pc.req_xfer)) {
printk(KERN_ERR PFX "Can't get floppy parameters\n");
return 1;
}
- header_len = pc.buf[3];
- cap_desc = &pc.buf[4];
+ header_len = pc_buf[3];
+ cap_desc = &pc_buf[4];
desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
for (i = 0; i < desc_cnt; i++) {
unsigned int desc_start = 4 + i*8;
- blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]);
- length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
+ blocks = be32_to_cpup((__be32 *)&pc_buf[desc_start]);
+ length = be16_to_cpup((__be16 *)&pc_buf[desc_start + 6]);
ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
"%d sector size",
@@ -411,7 +412,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
* the code below is valid only for the 1st descriptor, ie i=0
*/
- switch (pc.buf[desc_start + 4] & 0x03) {
+ switch (pc_buf[desc_start + 4] & 0x03) {
/* Clik! drive returns this instead of CAPACITY_CURRENT */
case CAPACITY_UNFORMATTED:
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
@@ -460,7 +461,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
break;
}
ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
- pc.buf[desc_start + 4] & 0x03);
+ pc_buf[desc_start + 4] & 0x03);
}
/* Clik! disk does not support get_flexible_disk_page */
@@ -490,7 +491,7 @@ static void ide_floppy_setup(ide_drive_t *drive)
drive->atapi_flags |= IDE_AFLAG_ZIP_DRIVE;
/* This value will be visible in the /proc/ide/hdx/settings */
drive->pc_delay = IDEFLOPPY_PC_DELAY;
- blk_queue_max_sectors(drive->queue, 64);
+ blk_queue_max_hw_sectors(drive->queue, 64);
}
/*
@@ -498,7 +499,7 @@ static void ide_floppy_setup(ide_drive_t *drive)
* nasty clicking noises without it, so please don't remove this.
*/
if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) {
- blk_queue_max_sectors(drive->queue, 64);
+ blk_queue_max_hw_sectors(drive->queue, 64);
drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
/* IOMEGA Clik! drives do not support lock/unlock commands */
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index cd8a42027ed..a22ca846701 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -5,6 +5,7 @@
#include <linux/kernel.h>
#include <linux/ide.h>
#include <linux/cdrom.h>
+#include <linux/mutex.h>
#include <asm/unaligned.h>
@@ -31,6 +32,7 @@
* On exit we set nformats to the number of records we've actually initialized.
*/
+static DEFINE_MUTEX(ide_floppy_ioctl_mutex);
static int ide_floppy_get_format_capacities(ide_drive_t *drive,
struct ide_atapi_pc *pc,
int __user *arg)
@@ -47,15 +49,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return -EINVAL;
ide_floppy_create_read_capacity_cmd(pc);
- pc->buf = &pc_buf[0];
- pc->buf_size = sizeof(pc_buf);
- if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
+ if (ide_queue_pc_tail(drive, floppy->disk, pc, pc_buf, pc->req_xfer)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
}
- header_len = pc->buf[3];
+ header_len = pc_buf[3];
desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */
u_index = 0;
@@ -72,8 +72,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
if (u_index >= u_array_size)
break; /* User-supplied buffer too small */
- blocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]);
- length = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]);
+ blocks = be32_to_cpup((__be32 *)&pc_buf[desc_start]);
+ length = be16_to_cpup((__be16 *)&pc_buf[desc_start + 6]);
if (put_user(blocks, argp))
return -EFAULT;
@@ -94,40 +94,42 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return 0;
}
-static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
- int l, int flags)
+static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc,
+ u8 *buf, int b, int l,
+ int flags)
{
ide_init_pc(pc);
pc->c[0] = GPCMD_FORMAT_UNIT;
pc->c[1] = 0x17;
- memset(pc->buf, 0, 12);
- pc->buf[1] = 0xA2;
+ memset(buf, 0, 12);
+ buf[1] = 0xA2;
/* Default format list header, u8 1: FOV/DCRT/IMM bits set */
if (flags & 1) /* Verify bit on... */
- pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */
- pc->buf[3] = 8;
+ buf[1] ^= 0x20; /* ... turn off DCRT bit */
+ buf[3] = 8;
- put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4]));
- put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8]));
- pc->buf_size = 12;
+ put_unaligned(cpu_to_be32(b), (unsigned int *)(&buf[4]));
+ put_unaligned(cpu_to_be32(l), (unsigned int *)(&buf[8]));
+ pc->req_xfer = 12;
pc->flags |= PC_FLAG_WRITING;
}
static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc)
{
struct ide_disk_obj *floppy = drive->driver_data;
+ u8 buf[20];
drive->atapi_flags &= ~IDE_AFLAG_SRFP;
ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE);
pc->flags |= PC_FLAG_SUPPRESS_ERROR;
- if (ide_queue_pc_tail(drive, floppy->disk, pc))
+ if (ide_queue_pc_tail(drive, floppy->disk, pc, buf, pc->req_xfer))
return 1;
- if (pc->buf[8 + 2] & 0x40)
+ if (buf[8 + 2] & 0x40)
drive->atapi_flags |= IDE_AFLAG_SRFP;
return 0;
@@ -137,6 +139,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
+ u8 buf[12];
int blocks, length, flags, err = 0;
if (floppy->openers > 1) {
@@ -170,9 +173,9 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
ide_floppy_get_sfrp_bit(drive, pc);
- ide_floppy_create_format_unit_cmd(pc, blocks, length, flags);
+ ide_floppy_create_format_unit_cmd(pc, buf, blocks, length, flags);
- if (ide_queue_pc_tail(drive, floppy->disk, pc))
+ if (ide_queue_pc_tail(drive, floppy->disk, pc, buf, pc->req_xfer))
err = -EIO;
out:
@@ -196,11 +199,13 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
+ u8 sense_buf[18];
int progress_indication = 0x10000;
if (drive->atapi_flags & IDE_AFLAG_SRFP) {
ide_create_request_sense_cmd(drive, pc);
- if (ide_queue_pc_tail(drive, floppy->disk, pc))
+ if (ide_queue_pc_tail(drive, floppy->disk, pc, sense_buf,
+ pc->req_xfer))
return -EIO;
if (floppy->sense_key == 2 &&
@@ -272,23 +277,27 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
void __user *argp = (void __user *)arg;
int err;
- if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR)
- return ide_floppy_lockdoor(drive, &pc, arg, cmd);
+ mutex_lock(&ide_floppy_ioctl_mutex);
+ if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) {
+ err = ide_floppy_lockdoor(drive, &pc, arg, cmd);
+ goto out;
+ }
err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp);
if (err != -ENOTTY)
- return err;
+ goto out;
/*
* skip SCSI_IOCTL_SEND_COMMAND (deprecated)
* and CDROM_SEND_PACKET (legacy) ioctls
*/
if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
- err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk,
- mode, cmd, argp);
+ err = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
if (err == -ENOTTY)
err = generic_ide_ioctl(drive, bdev, cmd, arg);
+out:
+ mutex_unlock(&ide_floppy_ioctl_mutex);
return err;
}
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c
index fcd4d8153df..e7a25ea757d 100644
--- a/drivers/ide/ide-floppy_proc.c
+++ b/drivers/ide/ide-floppy_proc.c
@@ -1,22 +1,35 @@
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/ide.h>
+#include <linux/seq_file.h>
#include "ide-floppy.h"
-static int proc_idefloppy_read_capacity(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int idefloppy_capacity_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t*drive = (ide_drive_t *)data;
- int len;
+ ide_drive_t*drive = (ide_drive_t *)m->private;
- len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "%llu\n", (long long)ide_gd_capacity(drive));
+ return 0;
}
+static int idefloppy_capacity_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, idefloppy_capacity_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations idefloppy_capacity_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idefloppy_capacity_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
ide_proc_entry_t ide_floppy_proc[] = {
- { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL },
- { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL },
- { NULL, 0, NULL, NULL }
+ { "capacity", S_IFREG|S_IRUGO, &idefloppy_capacity_proc_fops },
+ { "geometry", S_IFREG|S_IRUGO, &ide_geometry_proc_fops },
+ {}
};
ide_devset_rw_field(bios_cyl, bios_cyl);
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 4b6b71e2cdf..838996a0039 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -8,6 +8,7 @@
#include <linux/ide.h>
#include <linux/hdreg.h>
#include <linux/dmi.h>
+#include <linux/slab.h>
#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
#define IDE_DISK_MINORS (1 << PARTN_BITS)
@@ -21,6 +22,7 @@
#define IDE_GD_VERSION "1.18"
/* module parameters */
+static DEFINE_MUTEX(ide_gd_mutex);
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);
@@ -91,7 +93,7 @@ static void ide_disk_release(struct device *dev)
/*
* On HPA drives the capacity needs to be
- * reinitilized on resume otherwise the disk
+ * reinitialized on resume otherwise the disk
* can not be used and a hard reset is required
*/
static void ide_gd_resume(ide_drive_t *drive)
@@ -236,13 +238,26 @@ out_put_idkp:
return ret;
}
-static int ide_gd_release(struct gendisk *disk, fmode_t mode)
+static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode)
+{
+ int ret;
+
+ mutex_lock(&ide_gd_mutex);
+ ret = ide_gd_open(bdev, mode);
+ mutex_unlock(&ide_gd_mutex);
+
+ return ret;
+}
+
+
+static void ide_gd_release(struct gendisk *disk, fmode_t mode)
{
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
ide_debug_log(IDE_DBG_FUNC, "enter");
+ mutex_lock(&ide_gd_mutex);
if (idkp->openers == 1)
drive->disk_ops->flush(drive);
@@ -254,8 +269,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
idkp->openers--;
ide_disk_put(idkp);
-
- return 0;
+ mutex_unlock(&ide_gd_mutex);
}
static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
@@ -269,11 +283,12 @@ static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}
-static int ide_gd_media_changed(struct gendisk *disk)
+static unsigned int ide_gd_check_events(struct gendisk *disk,
+ unsigned int clearing)
{
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
- int ret;
+ bool ret;
/* do not scan partitions twice if this is a removable device */
if (drive->dev_flags & IDE_DFLAG_ATTACH) {
@@ -281,10 +296,26 @@ static int ide_gd_media_changed(struct gendisk *disk)
return 0;
}
- ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
+ /*
+ * The following is used to force revalidation on the first open on
+ * removeable devices, and never gets reported to userland as
+ * genhd->events is 0. This is intended as removeable ide disk
+ * can't really detect MEDIA_CHANGE events.
+ */
+ ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED;
drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
- return ret;
+ return ret ? DISK_EVENT_MEDIA_CHANGE : 0;
+}
+
+static void ide_gd_unlock_native_capacity(struct gendisk *disk)
+{
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+ const struct ide_disk_ops *disk_ops = drive->disk_ops;
+
+ if (disk_ops->unlock_native_capacity)
+ disk_ops->unlock_native_capacity(drive);
}
static int ide_gd_revalidate_disk(struct gendisk *disk)
@@ -292,7 +323,7 @@ static int ide_gd_revalidate_disk(struct gendisk *disk)
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
- if (ide_gd_media_changed(disk))
+ if (ide_gd_check_events(disk, 0))
drive->disk_ops->get_capacity(drive);
set_capacity(disk, ide_gd_capacity(drive));
@@ -308,13 +339,14 @@ static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode,
return drive->disk_ops->ioctl(drive, bdev, mode, cmd, arg);
}
-static struct block_device_operations ide_gd_ops = {
+static const struct block_device_operations ide_gd_ops = {
.owner = THIS_MODULE,
- .open = ide_gd_open,
+ .open = ide_gd_unlocked_open,
.release = ide_gd_release,
- .locked_ioctl = ide_gd_ioctl,
+ .ioctl = ide_gd_ioctl,
.getgeo = ide_gd_getgeo,
- .media_changed = ide_gd_media_changed,
+ .check_events = ide_gd_check_events,
+ .unlock_native_capacity = ide_gd_unlock_native_capacity,
.revalidate_disk = ide_gd_revalidate_disk
};
@@ -360,7 +392,7 @@ static int ide_gd_probe(ide_drive_t *drive)
idkp->dev.parent = &drive->gendev;
idkp->dev.release = ide_disk_release;
- dev_set_name(&idkp->dev, dev_name(&drive->gendev));
+ dev_set_name(&idkp->dev, "%s", dev_name(&drive->gendev));
if (device_register(&idkp->dev))
goto out_free_disk;
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 7812ca0be13..54d7c4685d2 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -29,6 +29,7 @@ MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
static const struct ide_port_info ide_generic_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
+ .chipset = ide_generic,
};
#ifdef CONFIG_ARM
@@ -85,7 +86,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
static int __init ide_generic_init(void)
{
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
unsigned long io_addr;
int i, rc = 0, primary = 0, secondary = 0;
@@ -132,9 +133,7 @@ static int __init ide_generic_init(void)
#else
hw.irq = legacy_irqs[i];
#endif
- hw.chipset = ide_generic;
-
- rc = ide_host_add(&ide_generic_port_info, hws, NULL);
+ rc = ide_host_add(&ide_generic_port_info, hws, 1, NULL);
if (rc) {
release_region(io_addr + 0x206, 1);
release_region(io_addr, 8);
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
deleted file mode 100644
index c06ebdc4a13..00000000000
--- a/drivers/ide/ide-h8300.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * H8/300 generic IDE interface
- */
-
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#define DRV_NAME "ide-h8300"
-
-#define bswap(d) \
-({ \
- u16 r; \
- __asm__("mov.b %w1,r1h\n\t" \
- "mov.b %x1,r1l\n\t" \
- "mov.w r1,%0" \
- :"=r"(r) \
- :"r"(d) \
- :"er1"); \
- (r); \
-})
-
-static void mm_outsw(unsigned long addr, void *buf, u32 len)
-{
- unsigned short *bp = (unsigned short *)buf;
- for (; len > 0; len--, bp++)
- *(volatile u16 *)addr = bswap(*bp);
-}
-
-static void mm_insw(unsigned long addr, void *buf, u32 len)
-{
- unsigned short *bp = (unsigned short *)buf;
- for (; len > 0; len--, bp++)
- *bp = bswap(*(volatile u16 *)addr);
-}
-
-static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
- void *buf, unsigned int len)
-{
- mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
-}
-
-static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
- void *buf, unsigned int len)
-{
- mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
-}
-
-static const struct ide_tp_ops h8300_tp_ops = {
- .exec_command = ide_exec_command,
- .read_status = ide_read_status,
- .read_altstatus = ide_read_altstatus,
- .write_devctl = ide_write_devctl,
-
- .dev_select = ide_dev_select,
- .tf_load = ide_tf_load,
- .tf_read = ide_tf_read,
-
- .input_data = h8300_input_data,
- .output_data = h8300_output_data,
-};
-
-#define H8300_IDE_GAP (2)
-
-static inline void hw_setup(hw_regs_t *hw)
-{
- int i;
-
- memset(hw, 0, sizeof(hw_regs_t));
- for (i = 0; i <= 7; i++)
- hw->io_ports_array[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
- hw->io_ports.ctl_addr = CONFIG_H8300_IDE_ALT;
- hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
- hw->chipset = ide_generic;
-}
-
-static const struct ide_port_info h8300_port_info = {
- .tp_ops = &h8300_tp_ops,
- .host_flags = IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_NO_DMA,
-};
-
-static int __init h8300_ide_init(void)
-{
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n");
-
- if (!request_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8, "ide-h8300"))
- goto out_busy;
- if (!request_region(CONFIG_H8300_IDE_ALT, H8300_IDE_GAP, "ide-h8300")) {
- release_region(CONFIG_H8300_IDE_BASE, H8300_IDE_GAP*8);
- goto out_busy;
- }
-
- hw_setup(&hw);
-
- return ide_host_add(&h8300_port_info, hws, NULL);
-
-out_busy:
- printk(KERN_ERR "ide-h8300: IDE I/F resource already used.\n");
-
- return -EBUSY;
-}
-
-module_init(h8300_ide_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 46721c45451..19763977568 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -1,5 +1,6 @@
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/ide.h>
#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 35dc38d3b2c..177db6d5b2f 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -112,16 +112,6 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
}
}
-/* obsolete, blk_rq_bytes() should be used instead */
-unsigned int ide_rq_bytes(struct request *rq)
-{
- if (blk_pc_request(rq))
- return rq->data_len;
- else
- return rq->hard_cur_sectors << 9;
-}
-EXPORT_SYMBOL_GPL(ide_rq_bytes);
-
int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
{
ide_hwif_t *hwif = drive->hwif;
@@ -133,7 +123,7 @@ int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
* and complete the whole request right now
*/
if (blk_noretry_request(rq) && error <= 0)
- nr_bytes = rq->hard_nr_sectors << 9;
+ nr_bytes = blk_rq_sectors(rq) << 9;
rc = ide_end_rq(drive, rq, error, nr_bytes);
if (rc == 0)
@@ -145,21 +135,21 @@ EXPORT_SYMBOL(ide_complete_rq);
void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
- u8 drv_req = blk_special_request(rq) && rq->rq_disk;
+ u8 drv_req = (rq->cmd_type == REQ_TYPE_SPECIAL) && rq->rq_disk;
u8 media = drive->media;
drive->failed_pc = NULL;
if ((media == ide_floppy || media == ide_tape) && drv_req) {
rq->errors = 0;
- ide_complete_rq(drive, 0, blk_rq_bytes(rq));
} else {
if (media == ide_tape)
rq->errors = IDE_DRV_ERROR_GENERAL;
- else if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ else if (rq->cmd_type != REQ_TYPE_FS && rq->errors == 0)
rq->errors = -EIO;
- ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
}
+
+ ide_complete_rq(drive, -EIO, blk_rq_bytes(rq));
}
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
@@ -184,29 +174,42 @@ static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
tf->command = ATA_CMD_SET_MULTI;
}
-static ide_startstop_t ide_disk_special(ide_drive_t *drive)
+/**
+ * do_special - issue some special commands
+ * @drive: drive the command is for
+ *
+ * do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS,
+ * ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive.
+ */
+
+static ide_startstop_t do_special(ide_drive_t *drive)
{
- special_t *s = &drive->special;
struct ide_cmd cmd;
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: %s: 0x%02x\n", drive->name, __func__,
+ drive->special_flags);
+#endif
+ if (drive->media != ide_disk) {
+ drive->special_flags = 0;
+ drive->mult_req = 0;
+ return ide_stopped;
+ }
+
memset(&cmd, 0, sizeof(cmd));
cmd.protocol = ATA_PROT_NODATA;
- if (s->b.set_geometry) {
- s->b.set_geometry = 0;
+ if (drive->special_flags & IDE_SFLAG_SET_GEOMETRY) {
+ drive->special_flags &= ~IDE_SFLAG_SET_GEOMETRY;
ide_tf_set_specify_cmd(drive, &cmd.tf);
- } else if (s->b.recalibrate) {
- s->b.recalibrate = 0;
+ } else if (drive->special_flags & IDE_SFLAG_RECALIBRATE) {
+ drive->special_flags &= ~IDE_SFLAG_RECALIBRATE;
ide_tf_set_restore_cmd(drive, &cmd.tf);
- } else if (s->b.set_multmode) {
- s->b.set_multmode = 0;
+ } else if (drive->special_flags & IDE_SFLAG_SET_MULTMODE) {
+ drive->special_flags &= ~IDE_SFLAG_SET_MULTMODE;
ide_tf_set_setmult_cmd(drive, &cmd.tf);
- } else if (s->all) {
- int special = s->all;
- s->all = 0;
- printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special);
- return ide_stopped;
- }
+ } else
+ BUG();
cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
@@ -217,45 +220,13 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
return ide_started;
}
-/**
- * do_special - issue some special commands
- * @drive: drive the command is for
- *
- * do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS,
- * ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive.
- *
- * It used to do much more, but has been scaled back.
- */
-
-static ide_startstop_t do_special (ide_drive_t *drive)
-{
- special_t *s = &drive->special;
-
-#ifdef DEBUG
- printk("%s: do_special: 0x%02x\n", drive->name, s->all);
-#endif
- if (drive->media == ide_disk)
- return ide_disk_special(drive);
-
- s->all = 0;
- drive->mult_req = 0;
- return ide_stopped;
-}
-
void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
struct request *rq = cmd->rq;
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- cmd->sg_nents = 1;
- } else if (!rq->bio) {
- sg_init_one(sg, rq->data, rq->data_len);
- cmd->sg_nents = 1;
- } else
- cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
+ cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
}
EXPORT_SYMBOL_GPL(ide_map_sg);
@@ -286,7 +257,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
if (cmd) {
if (cmd->protocol == ATA_PROT_PIO) {
- ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
+ ide_init_sg_cmd(cmd, blk_rq_sectors(rq) << 9);
ide_map_sg(drive, cmd);
}
@@ -336,7 +307,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{
ide_startstop_t startstop;
- BUG_ON(!blk_rq_started(rq));
+ BUG_ON(!(rq->cmd_flags & REQ_STARTED));
#ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n",
@@ -358,7 +329,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
return startstop;
}
- if (!drive->special.all) {
+
+ if (drive->special_flags == 0) {
struct ide_driver *drv;
/*
@@ -371,7 +343,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
return execute_drive_cmd(drive, rq);
else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
#ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n",
drive->name, pm->pm_step);
@@ -381,7 +353,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
pm->pm_step == IDE_PM_COMPLETED)
ide_complete_pm_rq(drive, rq);
return startstop;
- } else if (!rq->rq_disk && blk_special_request(rq))
+ } else if (!rq->rq_disk && rq->cmd_type == REQ_TYPE_SPECIAL)
/*
* TODO: Once all ULDs have been modified to
* check for specific op codes rather than
@@ -394,7 +366,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
drv = *(struct ide_driver **)rq->rq_disk->private_data;
- return drv->do_request(drive, rq, rq->sector);
+ return drv->do_request(drive, rq, blk_rq_pos(rq));
}
return do_special(drive);
kill_rq:
@@ -458,6 +430,26 @@ static inline void ide_unlock_host(struct ide_host *host)
}
}
+static void __ide_requeue_and_plug(struct request_queue *q, struct request *rq)
+{
+ if (rq)
+ blk_requeue_request(q, rq);
+ if (rq || blk_peek_request(q)) {
+ /* Use 3ms as that was the old plug delay */
+ blk_delay_queue(q, 3);
+ }
+}
+
+void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
+{
+ struct request_queue *q = drive->queue;
+ unsigned long flags;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ __ide_requeue_and_plug(q, rq);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
/*
* Issue a new request to a device.
*/
@@ -468,22 +460,13 @@ void do_ide_request(struct request_queue *q)
struct ide_host *host = hwif->host;
struct request *rq = NULL;
ide_startstop_t startstop;
-
- /*
- * drive is doing pre-flush, ordered write, post-flush sequence. even
- * though that is 3 requests, it must be seen as a single transaction.
- * we must not preempt this drive until that is complete
- */
- if (blk_queue_flushing(q))
- /*
- * small race where queue could get replugged during
- * the 3-request flush cycle, just yank the plug since
- * we want it to finish asap
- */
- blk_remove_plug(q);
+ unsigned long queue_run_ms = 3; /* old plug delay */
spin_unlock_irq(q->queue_lock);
+ /* HLD do_request() callback might sleep, make sure it's okay */
+ might_sleep();
+
if (ide_lock_host(host, hwif))
goto plug_device_2;
@@ -491,23 +474,30 @@ void do_ide_request(struct request_queue *q)
if (!ide_lock_port(hwif)) {
ide_hwif_t *prev_port;
+
+ WARN_ON_ONCE(hwif->rq);
repeat:
prev_port = hwif->host->cur_port;
- hwif->rq = NULL;
-
if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
time_after(drive->sleep, jiffies)) {
+ unsigned long left = jiffies - drive->sleep;
+
+ queue_run_ms = jiffies_to_msecs(left + 1);
ide_unlock_port(hwif);
goto plug_device;
}
if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
hwif != prev_port) {
+ ide_drive_t *cur_dev =
+ prev_port ? prev_port->cur_dev : NULL;
+
/*
* set nIEN for previous port, drives in the
- * quirk_list may not like intr setups/cleanups
+ * quirk list may not like intr setups/cleanups
*/
- if (prev_port && prev_port->cur_dev->quirk_list == 0)
+ if (cur_dev &&
+ (cur_dev->dev_flags & IDE_DFLAG_NIEN_QUIRK) == 0)
prev_port->tp_ops->write_devctl(prev_port,
ATA_NIEN |
ATA_DEVCTL_OBS);
@@ -523,7 +513,9 @@ repeat:
* we know that the queue isn't empty, but this can happen
* if the q->prep_rq_fn() decides to kill a request
*/
- rq = elv_next_request(drive->queue);
+ if (!rq)
+ rq = blk_fetch_request(drive->queue);
+
spin_unlock_irq(q->queue_lock);
spin_lock_irq(&hwif->lock);
@@ -535,7 +527,7 @@ repeat:
/*
* Sanity: don't accept a request that isn't a PM request
* if we are currently power managed. This is very important as
- * blk_stop_queue() doesn't prevent the elv_next_request()
+ * blk_stop_queue() doesn't prevent the blk_fetch_request()
* above to return us whatever is in the queue. Since we call
* ide_do_request() ourselves, we end up taking requests while
* the queue is blocked...
@@ -559,8 +551,11 @@ repeat:
startstop = start_request(drive, rq);
spin_lock_irq(&hwif->lock);
- if (startstop == ide_stopped)
+ if (startstop == ide_stopped) {
+ rq = hwif->rq;
+ hwif->rq = NULL;
goto repeat;
+ }
} else
goto plug_device;
out:
@@ -575,20 +570,7 @@ plug_device:
ide_unlock_host(host);
plug_device_2:
spin_lock_irq(q->queue_lock);
-
- if (!elv_queue_empty(q))
- blk_plug_device(q);
-}
-
-static void ide_plug_device(ide_drive_t *drive)
-{
- struct request_queue *q = drive->queue;
- unsigned long flags;
-
- spin_lock_irqsave(q->queue_lock, flags);
- if (!elv_queue_empty(q))
- blk_plug_device(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
+ __ide_requeue_and_plug(q, rq);
}
static int drive_is_ready(ide_drive_t *drive)
@@ -636,6 +618,7 @@ void ide_timer_expiry (unsigned long data)
unsigned long flags;
int wait = -1;
int plug_device = 0;
+ struct request *uninitialized_var(rq_in_flight);
spin_lock_irqsave(&hwif->lock, flags);
@@ -682,8 +665,9 @@ void ide_timer_expiry (unsigned long data)
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
hwif->dma_ops->dma_lost_irq(drive);
- if (hwif->ack_intr)
- hwif->ack_intr(hwif);
+ if (hwif->port_ops && hwif->port_ops->clear_irq)
+ hwif->port_ops->clear_irq(drive);
+
printk(KERN_WARNING "%s: lost interrupt\n",
drive->name);
startstop = handler(drive);
@@ -696,7 +680,9 @@ void ide_timer_expiry (unsigned long data)
}
spin_lock_irq(&hwif->lock);
enable_irq(hwif->irq);
- if (startstop == ide_stopped) {
+ if (startstop == ide_stopped && hwif->polling == 0) {
+ rq_in_flight = hwif->rq;
+ hwif->rq = NULL;
ide_unlock_port(hwif);
plug_device = 1;
}
@@ -705,7 +691,7 @@ void ide_timer_expiry (unsigned long data)
if (plug_device) {
ide_unlock_host(hwif->host);
- ide_plug_device(drive);
+ ide_requeue_and_plug(drive, rq_in_flight);
}
}
@@ -791,6 +777,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
ide_startstop_t startstop;
irqreturn_t irq_ret = IRQ_NONE;
int plug_device = 0;
+ struct request *uninitialized_var(rq_in_flight);
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
if (hwif != host->cur_port)
@@ -799,7 +786,8 @@ irqreturn_t ide_intr (int irq, void *dev_id)
spin_lock_irqsave(&hwif->lock, flags);
- if (hwif->ack_intr && hwif->ack_intr(hwif) == 0)
+ if (hwif->port_ops && hwif->port_ops->test_irq &&
+ hwif->port_ops->test_irq(hwif) == 0)
goto out;
handler = hwif->handler;
@@ -868,8 +856,10 @@ irqreturn_t ide_intr (int irq, void *dev_id)
* same irq as is currently being serviced here, and Linux
* won't allow another of the same (on any CPU) until we return.
*/
- if (startstop == ide_stopped) {
+ if (startstop == ide_stopped && hwif->polling == 0) {
BUG_ON(hwif->handler);
+ rq_in_flight = hwif->rq;
+ hwif->rq = NULL;
ide_unlock_port(hwif);
plug_device = 1;
}
@@ -879,7 +869,7 @@ out:
out_early:
if (plug_device) {
ide_unlock_host(hwif->host);
- ide_plug_device(drive);
+ ide_requeue_and_plug(drive, rq_in_flight);
}
return irq_ret;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index c1c25ebbaa1..6233fa2cb8a 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -2,8 +2,10 @@
* IDE ioctls handling.
*/
+#include <linux/export.h>
#include <linux/hdreg.h>
#include <linux/ide.h>
+#include <linux/slab.h>
static const struct ide_ioctl_devset ide_ioctl_settings[] = {
{ HDIO_GET_32BIT, HDIO_SET_32BIT, &ide_devset_io_32bit },
@@ -64,7 +66,8 @@ static int ide_get_identity_ioctl(ide_drive_t *drive, unsigned int cmd,
goto out;
}
- id = kmalloc(size, GFP_KERNEL);
+ /* ata_id_to_hd_driveid() relies on 'id' to be fully allocated. */
+ id = kmalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
if (id == NULL) {
rc = -ENOMEM;
goto out;
@@ -118,7 +121,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
u8 args[4], xfer_rate = 0;
struct ide_cmd cmd;
struct ide_taskfile *tf = &cmd.tf;
- u16 *id = drive->id;
if (NULL == (void *) arg) {
struct request *rq;
@@ -139,8 +141,8 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
if (args[0] == ATA_CMD_SMART) {
tf->nsect = args[3];
tf->lbal = args[1];
- tf->lbam = 0x4f;
- tf->lbah = 0xc2;
+ tf->lbam = ATA_SMART_LBAM_PASS;
+ tf->lbah = ATA_SMART_LBAH_PASS;
cmd.valid.out.tf = IDE_VALID_OUT_TF;
cmd.valid.in.tf = IDE_VALID_NSECT;
} else {
@@ -161,16 +163,14 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
if (tf->command == ATA_CMD_SET_FEATURES &&
tf->feature == SETFEATURES_XFER &&
- tf->nsect >= XFER_SW_DMA_0 &&
- (id[ATA_ID_UDMA_MODES] ||
- id[ATA_ID_MWDMA_MODES] ||
- id[ATA_ID_SWDMA_MODES])) {
- xfer_rate = args[1];
- if (tf->nsect > XFER_UDMA_2 && !eighty_ninty_three(drive)) {
- printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot "
- "be set\n", drive->name);
+ tf->nsect >= XFER_SW_DMA_0) {
+ xfer_rate = ide_find_dma_mode(drive, tf->nsect);
+ if (xfer_rate != tf->nsect) {
+ err = -EINVAL;
goto abort;
}
+
+ cmd.tf_flags |= IDE_TFLAG_SET_XFER;
}
err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
@@ -178,12 +178,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
args[0] = tf->status;
args[1] = tf->error;
args[2] = tf->nsect;
-
- if (!err && xfer_rate) {
- /* active-retuning-calls future */
- ide_set_xfer_rate(drive, xfer_rate);
- ide_driveid_update(drive);
- }
abort:
if (copy_to_user((void __user *)arg, &args, 4))
err = -EFAULT;
@@ -231,7 +225,6 @@ static int generic_drive_reset(ide_drive_t *drive)
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd_len = 1;
rq->cmd[0] = REQ_DRIVE_RESET;
- rq->cmd_flags |= REQ_SOFTBARRIER;
if (blk_execute_rq(drive->queue, NULL, rq, 1))
ret = rq->errors;
blk_put_request(rq);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index c19a221b1e1..376f2dc410c 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -102,8 +102,8 @@ EXPORT_SYMBOL(ide_fixstring);
* setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out.
*/
-static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
- unsigned long timeout, u8 *rstat)
+int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
+ unsigned long timeout, u8 *rstat)
{
ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -206,12 +206,11 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list);
/*
* Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
- * We list them here and depend on the device side cable detection for them.
- *
* Some optical devices with the buggy firmwares have the same problem.
*/
static const struct drive_list_entry ivb_list[] = {
{ "QUANTUM FIREBALLlct10 05" , "A03.0900" },
+ { "QUANTUM FIREBALLlct20 30" , "APL.0900" },
{ "TSSTcorp CDDVDW SH-S202J" , "SB00" },
{ "TSSTcorp CDDVDW SH-S202J" , "SB01" },
{ "TSSTcorp CDDVDW SH-S202N" , "SB00" },
@@ -232,7 +231,7 @@ u8 eighty_ninty_three(ide_drive_t *drive)
u16 *id = drive->id;
int ivb = ide_in_drive_list(id, ivb_list);
- if (hwif->cbl == ATA_CBL_PATA40_SHORT)
+ if (hwif->cbl == ATA_CBL_SATA || hwif->cbl == ATA_CBL_PATA40_SHORT)
return 1;
if (ivb)
@@ -251,10 +250,25 @@ u8 eighty_ninty_three(ide_drive_t *drive)
* - force bit13 (80c cable present) check also for !ivb devices
* (unless the slave device is pre-ATA3)
*/
- if ((id[ATA_ID_HW_CONFIG] & 0x4000) ||
- (ivb && (id[ATA_ID_HW_CONFIG] & 0x2000)))
+ if (id[ATA_ID_HW_CONFIG] & 0x4000)
return 1;
+ if (ivb) {
+ const char *model = (char *)&id[ATA_ID_PROD];
+
+ if (strstr(model, "TSSTcorp CDDVDW SH-S202")) {
+ /*
+ * These ATAPI devices always report 80c cable
+ * so we have to depend on the host in this case.
+ */
+ if (hwif->cbl == ATA_CBL_PATA80)
+ return 1;
+ } else {
+ /* Depend on the device side cable detection. */
+ if (id[ATA_ID_HW_CONFIG] & 0x2000)
+ return 1;
+ }
+ }
no_80w:
if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED)
return 0;
@@ -269,6 +283,30 @@ no_80w:
return 0;
}
+static const char *nien_quirk_list[] = {
+ "QUANTUM FIREBALLlct08 08",
+ "QUANTUM FIREBALLP KA6.4",
+ "QUANTUM FIREBALLP KA9.1",
+ "QUANTUM FIREBALLP KX13.6",
+ "QUANTUM FIREBALLP KX20.5",
+ "QUANTUM FIREBALLP KX27.3",
+ "QUANTUM FIREBALLP LM20.4",
+ "QUANTUM FIREBALLP LM20.5",
+ "FUJITSU MHZ2160BH G2",
+ NULL
+};
+
+void ide_check_nien_quirk_list(ide_drive_t *drive)
+{
+ const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
+
+ for (list = nien_quirk_list; *list != NULL; list++)
+ if (strstr(m, *list) != NULL) {
+ drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
+ return;
+ }
+}
+
int ide_driveid_update(ide_drive_t *drive)
{
u16 *id;
@@ -279,7 +317,7 @@ int ide_driveid_update(ide_drive_t *drive)
return 0;
SELECT_MASK(drive, 1);
- rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id);
+ rc = ide_dev_read_id(drive, ATA_CMD_ID_ATA, id, 1);
SELECT_MASK(drive, 0);
if (rc)
@@ -293,12 +331,8 @@ int ide_driveid_update(ide_drive_t *drive)
kfree(id);
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive))
- ide_dma_off(drive);
-
return 1;
out_err:
- SELECT_MASK(drive, 0);
if (rc == 2)
printk(KERN_ERR "%s: %s: bad status\n", drive->name, __func__);
kfree(id);
@@ -330,14 +364,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* this point (lost interrupt).
*/
- /*
- * FIXME: we race against the running IRQ here if
- * this is called from non IRQ context. If we use
- * disable_irq() we hang on the error path. Work
- * is needed.
- */
- disable_irq_nosync(hwif->irq);
-
udelay(1);
tp_ops->dev_select(drive);
SELECT_MASK(drive, 1);
@@ -352,7 +378,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
- if (drive->quirk_list == 2)
+ if (drive->dev_flags & IDE_DFLAG_NIEN_QUIRK)
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
error = __ide_wait_stat(drive, drive->ready_stat,
@@ -361,8 +387,6 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
SELECT_MASK(drive, 0);
- enable_irq(hwif->irq);
-
if (error) {
(void) ide_dump_status(drive, "set_drive_speed_status", stat);
return error;
diff --git a/drivers/ide/ide-legacy.c b/drivers/ide/ide-legacy.c
index 8c5dcbf2254..30fe3630734 100644
--- a/drivers/ide/ide-legacy.c
+++ b/drivers/ide/ide-legacy.c
@@ -1,7 +1,8 @@
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/ide.h>
-static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw,
+static void ide_legacy_init_one(struct ide_hw **hws, struct ide_hw *hw,
u8 port_no, const struct ide_port_info *d,
unsigned long config)
{
@@ -33,7 +34,6 @@ static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw,
ide_std_init_ports(hw, base, ctl);
hw->irq = irq;
- hw->chipset = d->chipset;
hw->config = config;
hws[port_no] = hw;
@@ -41,7 +41,7 @@ static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw,
int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
{
- hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
+ struct ide_hw hw[2], *hws[] = { NULL, NULL };
memset(&hw, 0, sizeof(hw));
@@ -53,6 +53,6 @@ int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
(d->host_flags & IDE_HFLAG_SINGLE))
return -ENOENT;
- return ide_host_add(d, hws, NULL);
+ return ide_host_add(d, hws, 2, NULL);
}
EXPORT_SYMBOL_GPL(ide_legacy_device_add);
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 56ff8c46c7d..d9c9829c8b2 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -1,6 +1,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/ide.h>
#include <linux/bitops.h>
@@ -31,24 +32,6 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
blk_queue_bounce_limit(drive->queue, addr);
}
-static void ide_dump_opcode(ide_drive_t *drive)
-{
- struct request *rq = drive->hwif->rq;
- struct ide_cmd *cmd = NULL;
-
- if (!rq)
- return;
-
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
- cmd = rq->special;
-
- printk(KERN_ERR "ide: failed opcode was: ");
- if (cmd == NULL)
- printk(KERN_CONT "unknown\n");
- else
- printk(KERN_CONT "0x%02x\n", cmd->tf.command);
-}
-
u64 ide_get_lba_addr(struct ide_cmd *cmd, int lba48)
{
struct ide_taskfile *tf = &cmd->tf;
@@ -91,7 +74,7 @@ static void ide_dump_sector(ide_drive_t *drive)
static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
{
- printk(KERN_ERR "{ ");
+ printk(KERN_CONT "{ ");
if (err & ATA_ABORTED)
printk(KERN_CONT "DriveStatusError ");
if (err & ATA_ICRC)
@@ -114,14 +97,14 @@ static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
if (rq)
printk(KERN_CONT ", sector=%llu",
- (unsigned long long)rq->sector);
+ (unsigned long long)blk_rq_pos(rq));
}
printk(KERN_CONT "\n");
}
static void ide_dump_atapi_error(ide_drive_t *drive, u8 err)
{
- printk(KERN_ERR "{ ");
+ printk(KERN_CONT "{ ");
if (err & ATAPI_ILI)
printk(KERN_CONT "IllegalLengthIndication ");
if (err & ATAPI_EOM)
@@ -179,7 +162,10 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat)
else
ide_dump_atapi_error(drive, err);
}
- ide_dump_opcode(drive);
+
+ printk(KERN_ERR "%s: possibly failed opcode: 0x%02x\n",
+ drive->name, drive->hwif->cmd.tf.command);
+
return err;
}
EXPORT_SYMBOL(ide_dump_status);
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 310d03f2b5b..f41558a0bcd 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -1,4 +1,5 @@
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
#include <linux/jiffies.h>
#include <linux/blkdev.h>
@@ -24,11 +25,8 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
start_queue = 1;
spin_unlock_irq(&hwif->lock);
- if (start_queue) {
- spin_lock_irq(q->queue_lock);
- blk_start_queueing(q);
- spin_unlock_irq(q->queue_lock);
- }
+ if (start_queue)
+ blk_run_queue(q);
return;
}
spin_unlock_irq(&hwif->lock);
@@ -54,7 +52,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
rq->cmd[0] = REQ_UNPARK_HEADS;
rq->cmd_len = 1;
rq->cmd_type = REQ_TYPE_SPECIAL;
- elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 1);
+ elv_add_request(q, rq, ELEVATOR_INSERT_FRONT);
out:
return;
@@ -118,8 +116,10 @@ ssize_t ide_park_store(struct device *dev, struct device_attribute *attr,
long int input;
int rc;
- rc = strict_strtol(buf, 10, &input);
- if (rc || input < -2)
+ rc = kstrtol(buf, 10, &input);
+ if (rc)
+ return rc;
+ if (input < -2)
return -EINVAL;
if (input > MAX_PARK_TIMEOUT) {
input = MAX_PARK_TIMEOUT;
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index 61111fd2713..673420db953 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -28,11 +28,21 @@
#define DRV_NAME "ide_pci_generic"
-static int ide_generic_all; /* Set to claim all devices */
+static bool ide_generic_all; /* Set to claim all devices */
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
+static void netcell_quirkproc(ide_drive_t *drive)
+{
+ /* mark words 85-87 as valid */
+ drive->id[ATA_ID_CSF_DEFAULT] |= 0x4000;
+}
+
+static const struct ide_port_ops netcell_port_ops = {
+ .quirkproc = netcell_quirkproc,
+};
+
#define DECLARE_GENERIC_PCI_DEV(extra_flags) \
{ \
.name = DRV_NAME, \
@@ -43,7 +53,7 @@ MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE st
.udma_mask = ATA_UDMA6, \
}
-static const struct ide_port_info generic_chipsets[] __devinitdata = {
+static const struct ide_port_info generic_chipsets[] = {
/* 0: Unknown */
DECLARE_GENERIC_PCI_DEV(0),
@@ -74,6 +84,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
{ /* 6: Revolution */
.name = DRV_NAME,
+ .port_ops = &netcell_port_ops,
.host_flags = IDE_HFLAG_CLEAR_SIMPLEX |
IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD,
@@ -92,7 +103,7 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = {
* finds a device matching our IDE device tables.
*/
-static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct ide_port_info *d = &generic_chipsets[id->driver_data];
int ret = -ENODEV;
@@ -151,9 +162,10 @@ static const struct pci_device_id generic_pci_tbl[] = {
#ifdef CONFIG_BLK_DEV_IDE_SATA
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237_SATA), 5 },
#endif
- { PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO), 4 },
{ PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO_1), 4 },
{ PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO_2), 4 },
+ { PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO_3), 4 },
+ { PCI_VDEVICE(TOSHIBA, PCI_DEVICE_ID_TOSHIBA_PICCOLO_5), 4 },
{ PCI_VDEVICE(NETCELL, PCI_DEVICE_ID_REVOLUTION), 6 },
/*
* Must come last. If you add entries adjust
diff --git a/drivers/ide/ide-pio-blacklist.c b/drivers/ide/ide-pio-blacklist.c
index a8c2c8f8660..40e683a84ff 100644
--- a/drivers/ide/ide-pio-blacklist.c
+++ b/drivers/ide/ide-pio-blacklist.c
@@ -7,6 +7,7 @@
*/
#include <linux/string.h>
+#include <linux/ide.h>
static struct ide_pio_info {
const char *name;
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 0d8a151c0a0..8d1e32d7cd9 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -1,25 +1,26 @@
#include <linux/kernel.h>
+#include <linux/gfp.h>
#include <linux/ide.h>
int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
- ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive);
+ ide_drive_t *drive = to_ide_device(dev);
+ ide_drive_t *pair = ide_get_pair_dev(drive);
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- struct ide_cmd cmd;
int ret;
- /* call ACPI _GTM only once */
- if ((drive->dn & 1) == 0 || pair == NULL)
- ide_acpi_get_timing(hwif);
+ if (ide_port_acpi(hwif)) {
+ /* call ACPI _GTM only once */
+ if ((drive->dn & 1) == 0 || pair == NULL)
+ ide_acpi_get_timing(hwif);
+ }
memset(&rqpm, 0, sizeof(rqpm));
- memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_SUSPEND;
- rq->special = &cmd;
- rq->data = &rqpm;
+ rq->special = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND;
if (mesg.event == PM_EVENT_PRETHAW)
mesg.event = PM_EVENT_FREEZE;
@@ -28,37 +29,39 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ret = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
- /* call ACPI _PS3 only after both devices are suspended */
- if (ret == 0 && ((drive->dn & 1) || pair == NULL))
- ide_acpi_set_state(hwif, 0);
+ if (ret == 0 && ide_port_acpi(hwif)) {
+ /* call ACPI _PS3 only after both devices are suspended */
+ if ((drive->dn & 1) || pair == NULL)
+ ide_acpi_set_state(hwif, 0);
+ }
return ret;
}
int generic_ide_resume(struct device *dev)
{
- ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive);
+ ide_drive_t *drive = to_ide_device(dev);
+ ide_drive_t *pair = ide_get_pair_dev(drive);
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- struct ide_cmd cmd;
int err;
- /* call ACPI _PS0 / _STM only once */
- if ((drive->dn & 1) == 0 || pair == NULL) {
- ide_acpi_set_state(hwif, 1);
- ide_acpi_push_timing(hwif);
- }
+ if (ide_port_acpi(hwif)) {
+ /* call ACPI _PS0 / _STM only once */
+ if ((drive->dn & 1) == 0 || pair == NULL) {
+ ide_acpi_set_state(hwif, 1);
+ ide_acpi_push_timing(hwif);
+ }
- ide_acpi_exec_tfs(drive);
+ ide_acpi_exec_tfs(drive);
+ }
memset(&rqpm, 0, sizeof(rqpm));
- memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_RESUME;
rq->cmd_flags |= REQ_PREEMPT;
- rq->special = &cmd;
- rq->data = &rqpm;
+ rq->special = &rqpm;
rqpm.pm_step = IDE_PM_START_RESUME;
rqpm.pm_state = PM_EVENT_ON;
@@ -77,7 +80,7 @@ int generic_ide_resume(struct device *dev)
void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
#ifdef DEBUG_PM
printk(KERN_INFO "%s: complete_power_step(step: %d)\n",
@@ -107,10 +110,8 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->data;
- struct ide_cmd *cmd = rq->special;
-
- memset(cmd, 0, sizeof(*cmd));
+ struct request_pm_state *pm = rq->special;
+ struct ide_cmd cmd = { };
switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
@@ -123,12 +124,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
if (ata_id_flush_ext_enabled(drive->id))
- cmd->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd.tf.command = ATA_CMD_FLUSH_EXT;
else
- cmd->tf.command = ATA_CMD_FLUSH;
+ cmd.tf.command = ATA_CMD_FLUSH;
goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
- cmd->tf.command = ATA_CMD_STANDBYNOW1;
+ cmd.tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive);
@@ -141,7 +142,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
ide_complete_power_step(drive, rq);
return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */
- cmd->tf.command = ATA_CMD_IDLEIMMEDIATE;
+ cmd.tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/*
@@ -163,11 +164,11 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
out_do_tf:
- cmd->valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
- cmd->valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
- cmd->protocol = ATA_PROT_NODATA;
+ cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
+ cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
+ cmd.protocol = ATA_PROT_NODATA;
- return do_rw_taskfile(drive, cmd);
+ return do_rw_taskfile(drive, &cmd);
}
/**
@@ -181,7 +182,7 @@ out_do_tf:
void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
unsigned long flags;
ide_complete_power_step(drive, rq);
@@ -190,10 +191,10 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
#ifdef DEBUG_PM
printk("%s: completing PM request, %s\n", drive->name,
- blk_pm_suspend_request(rq) ? "suspend" : "resume");
+ (rq->cmd_type == REQ_TYPE_PM_SUSPEND) ? "suspend" : "resume");
#endif
spin_lock_irqsave(q->queue_lock, flags);
- if (blk_pm_suspend_request(rq))
+ if (rq->cmd_type == REQ_TYPE_PM_SUSPEND)
blk_stop_queue(q);
else
drive->dev_flags &= ~IDE_DFLAG_BLOCKED;
@@ -207,13 +208,13 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
{
- struct request_pm_state *pm = rq->data;
+ struct request_pm_state *pm = rq->special;
- if (blk_pm_suspend_request(rq) &&
+ if (rq->cmd_type == REQ_TYPE_PM_SUSPEND &&
pm->pm_step == IDE_PM_START_SUSPEND)
/* Mark drive blocked when starting the suspend sequence. */
drive->dev_flags |= IDE_DFLAG_BLOCKED;
- else if (blk_pm_resume_request(rq) &&
+ else if (rq->cmd_type == REQ_TYPE_PM_RESUME &&
pm->pm_step == IDE_PM_START_RESUME) {
/*
* The first thing we do on wakeup is to wait for BSY bit to
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 6e80b774e88..e5f3db83137 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/pnp.h>
#include <linux/ide.h>
+#include <linux/module.h>
#define DRV_NAME "ide-pnp"
@@ -29,6 +30,7 @@ static struct pnp_device_id idepnp_devices[] = {
static const struct ide_port_info ide_pnp_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
+ .chipset = ide_generic,
};
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
@@ -36,7 +38,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
struct ide_host *host;
unsigned long base, ctl;
int rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n");
@@ -62,9 +64,8 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base, ctl);
hw.irq = pnp_irq(dev, 0);
- hw.chipset = ide_generic;
- rc = ide_host_add(&ide_pnp_port_info, hws, &host);
+ rc = ide_host_add(&ide_pnp_port_info, hws, 1, &host);
if (rc)
goto out;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 7f264ed1141..a3d3b1733c4 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -97,7 +97,7 @@ static void ide_disk_init_mult_count(ide_drive_t *drive)
drive->mult_req = id[ATA_ID_MULTSECT] & 0xff;
if (drive->mult_req)
- drive->special.b.set_multmode = 1;
+ drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
}
}
@@ -238,6 +238,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
* @drive: drive to identify
* @cmd: command to use
* @id: buffer for IDENTIFY data
+ * @irq_ctx: flag set when called from the IRQ context
*
* Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
*
@@ -246,7 +247,7 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
* 2 device aborted the command (refused to identify itself)
*/
-int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
+int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
@@ -263,7 +264,10 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */
- msleep(50);
+ if (irq_ctx)
+ mdelay(50);
+ else
+ msleep(50);
if (io_ports->ctl_addr &&
(hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
@@ -295,12 +299,19 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
- if (ide_busy_sleep(hwif, timeout, use_altstatus))
- return 1;
-
/* wait for IRQ and ATA_DRQ */
- msleep(50);
- s = tp_ops->read_status(hwif);
+ if (irq_ctx) {
+ rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s);
+ if (rc)
+ return 1;
+ } else {
+ rc = ide_busy_sleep(drive, timeout, use_altstatus);
+ if (rc)
+ return 1;
+
+ msleep(50);
+ s = tp_ops->read_status(hwif);
+ }
if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
/* drive returned ID */
@@ -316,8 +327,9 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
return rc;
}
-int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
+int ide_busy_sleep(ide_drive_t *drive, unsigned long timeout, int altstatus)
{
+ ide_hwif_t *hwif = drive->hwif;
u8 stat;
timeout += jiffies;
@@ -330,6 +342,8 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
return 0;
} while (time_before(jiffies, timeout));
+ printk(KERN_ERR "%s: timeout in %s\n", drive->name, __func__);
+
return 1; /* drive timed-out */
}
@@ -403,10 +417,10 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
present || cmd == ATA_CMD_ID_ATAPI) {
- rc = ide_dev_read_id(drive, cmd, id);
+ rc = ide_dev_read_id(drive, cmd, id, 0);
if (rc)
/* failed: try again */
- rc = ide_dev_read_id(drive, cmd, id);
+ rc = ide_dev_read_id(drive, cmd, id, 0);
stat = tp_ops->read_status(hwif);
@@ -420,8 +434,8 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
tp_ops->dev_select(drive);
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
- (void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
- rc = ide_dev_read_id(drive, cmd, id);
+ (void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
+ rc = ide_dev_read_id(drive, cmd, id, 0);
}
/* ensure drive IRQ is clear */
@@ -462,23 +476,8 @@ static u8 probe_for_drive(ide_drive_t *drive)
int rc;
u8 cmd;
- /*
- * In order to keep things simple we have an id
- * block for all drives at all times. If the device
- * is pre ATA or refuses ATA/ATAPI identify we
- * will add faked data to this.
- *
- * Also note that 0 everywhere means "can't do X"
- */
-
drive->dev_flags &= ~IDE_DFLAG_ID_READ;
- drive->id = kzalloc(SECTOR_SIZE, GFP_KERNEL);
- if (drive->id == NULL) {
- printk(KERN_ERR "ide: out of memory for id data.\n");
- return 0;
- }
-
m = (char *)&drive->id[ATA_ID_PROD];
strcpy(m, "UNKNOWN");
@@ -494,7 +493,7 @@ static u8 probe_for_drive(ide_drive_t *drive)
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- goto out_free;
+ return 0;
/* identification failed? */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -518,7 +517,7 @@ static u8 probe_for_drive(ide_drive_t *drive)
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- goto out_free;
+ return 0;
/* The drive wasn't being helpful. Add generic info only */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -532,9 +531,6 @@ static u8 probe_for_drive(ide_drive_t *drive)
}
return 1;
-out_free:
- kfree(drive->id);
- return 0;
}
static void hwif_release_dev(struct device *dev)
@@ -549,8 +545,8 @@ static int ide_register_port(ide_hwif_t *hwif)
int ret;
/* register with global device tree */
- dev_set_name(&hwif->gendev, hwif->name);
- hwif->gendev.driver_data = hwif;
+ dev_set_name(&hwif->gendev, "%s", hwif->name);
+ dev_set_drvdata(&hwif->gendev, hwif);
if (hwif->gendev.parent == NULL)
hwif->gendev.parent = hwif->dev;
hwif->gendev.release = hwif_release_dev;
@@ -563,7 +559,7 @@ static int ide_register_port(ide_hwif_t *hwif)
}
hwif->portdev = device_create(ide_port_class, &hwif->gendev,
- MKDEV(0, 0), hwif, hwif->name);
+ MKDEV(0, 0), hwif, "%s", hwif->name);
if (IS_ERR(hwif->portdev)) {
ret = PTR_ERR(hwif->portdev);
device_unregister(&hwif->gendev);
@@ -729,6 +725,8 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
int i;
ide_port_for_each_present_dev(i, drive, hwif) {
+ ide_check_nien_quirk_list(drive);
+
if (port_ops && port_ops->quirkproc)
port_ops->quirkproc(drive);
}
@@ -770,7 +768,7 @@ static int ide_init_queue(ide_drive_t *drive)
if (hwif->rqsize < max_sectors)
max_sectors = hwif->rqsize;
- blk_queue_max_sectors(q, max_sectors);
+ blk_queue_max_hw_sectors(q, max_sectors);
#ifdef CONFIG_PCI
/* When we have an IOMMU, we may have a problem where pci_map_sg()
@@ -786,8 +784,7 @@ static int ide_init_queue(ide_drive_t *drive)
max_sg_entries >>= 1;
#endif /* CONFIG_PCI */
- blk_queue_max_hw_segments(q, max_sg_entries);
- blk_queue_max_phys_segments(q, max_sg_entries);
+ blk_queue_max_segments(q, max_sg_entries);
/* assign drive queue */
drive->queue = q;
@@ -814,8 +811,6 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
if (ide_init_queue(drive)) {
printk(KERN_ERR "ide: failed to init %s\n",
drive->name);
- kfree(drive->id);
- drive->id = NULL;
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
continue;
}
@@ -827,6 +822,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
return j;
}
+static void ide_host_enable_irqs(struct ide_host *host)
+{
+ ide_hwif_t *hwif;
+ int i;
+
+ ide_host_for_each_port(i, hwif, host) {
+ if (hwif == NULL)
+ continue;
+
+ /* clear any pending IRQs */
+ hwif->tp_ops->read_status(hwif);
+
+ /* unmask IRQs */
+ if (hwif->io_ports.ctl_addr)
+ hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
+ }
+}
+
/*
* This routine sets up the IRQ for an IDE interface.
*/
@@ -840,11 +853,9 @@ static int init_irq (ide_hwif_t *hwif)
if (irq_handler == NULL)
irq_handler = ide_intr;
- if (io_ports->ctl_addr)
- hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
-
- if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
- goto out_up;
+ if (!host->get_lock)
+ if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
+ goto out_up;
#if !defined(__mc68000__)
printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
@@ -944,9 +955,6 @@ static void drive_release_dev (struct device *dev)
blk_cleanup_queue(drive->queue);
drive->queue = NULL;
- kfree(drive->id);
- drive->id = NULL;
-
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
complete(&drive->gendev_rel_comp);
@@ -999,9 +1007,9 @@ static void hwif_register_devices(ide_hwif_t *hwif)
int ret;
dev_set_name(dev, "%u.%u", hwif->index, i);
+ dev_set_drvdata(dev, drive);
dev->parent = &hwif->gendev;
dev->bus = &ide_bus_type;
- dev->driver_data = drive;
dev->release = drive_release_dev;
ret = device_register(dev);
@@ -1029,6 +1037,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
+ drive->pio_mode = XFER_PIO_0;
+
if (port_ops && port_ops->init_dev)
port_ops->init_dev(drive);
}
@@ -1039,8 +1049,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
{
hwif->channel = port;
- if (d->chipset)
- hwif->chipset = d->chipset;
+ hwif->chipset = d->chipset ? d->chipset : ide_pci;
if (d->init_iops)
d->init_iops(hwif);
@@ -1121,16 +1130,19 @@ static void ide_port_init_devices_data(ide_hwif_t *hwif)
ide_port_for_each_dev(i, drive, hwif) {
u8 j = (hwif->index * MAX_DRIVES) + i;
+ u16 *saved_id = drive->id;
memset(drive, 0, sizeof(*drive));
+ memset(saved_id, 0, SECTOR_SIZE);
+ drive->id = saved_id;
drive->media = ide_disk;
drive->select = (i << 4) | ATA_DEVICE_OBS;
drive->hwif = hwif;
drive->ready_stat = ATA_DRDY;
drive->bad_wstat = BAD_W_STAT;
- drive->special.b.recalibrate = 1;
- drive->special.b.set_geometry = 1;
+ drive->special_flags = IDE_SFLAG_RECALIBRATE |
+ IDE_SFLAG_SET_GEOMETRY;
drive->name[0] = 'h';
drive->name[1] = 'd';
drive->name[2] = 'a' + j;
@@ -1165,14 +1177,12 @@ static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
ide_port_init_devices_data(hwif);
}
-static void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
+static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw)
{
memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
hwif->irq = hw->irq;
- hwif->chipset = hw->chipset;
hwif->dev = hw->dev;
hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
- hwif->ack_intr = hw->ack_intr;
hwif->config_data = hw->config;
}
@@ -1189,7 +1199,7 @@ static int ide_find_port_slot(const struct ide_port_info *d)
{
int idx = -ENOENT;
u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
- u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;;
+ u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
/*
* Claim an unassigned slot.
@@ -1230,8 +1240,10 @@ static void ide_port_free_devices(ide_hwif_t *hwif)
ide_drive_t *drive;
int i;
- ide_port_for_each_dev(i, drive, hwif)
+ ide_port_for_each_dev(i, drive, hwif) {
+ kfree(drive->id);
kfree(drive);
+ }
}
static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
@@ -1245,6 +1257,18 @@ static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
if (drive == NULL)
goto out_nomem;
+ /*
+ * In order to keep things simple we have an id
+ * block for all drives at all times. If the device
+ * is pre ATA or refuses ATA/ATAPI identify we
+ * will add faked data to this.
+ *
+ * Also note that 0 everywhere means "can't do X"
+ */
+ drive->id = kzalloc_node(SECTOR_SIZE, GFP_KERNEL, node);
+ if (drive->id == NULL)
+ goto out_nomem;
+
hwif->devices[i] = drive;
}
return 0;
@@ -1254,7 +1278,8 @@ out_nomem:
return -ENOMEM;
}
-struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
+struct ide_host *ide_host_alloc(const struct ide_port_info *d,
+ struct ide_hw **hws, unsigned int n_ports)
{
struct ide_host *host;
struct device *dev = hws[0] ? hws[0]->dev : NULL;
@@ -1265,7 +1290,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
if (host == NULL)
return NULL;
- for (i = 0; i < MAX_HOST_PORTS; i++) {
+ for (i = 0; i < n_ports; i++) {
ide_hwif_t *hwif;
int idx;
@@ -1285,6 +1310,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
if (idx < 0) {
printk(KERN_ERR "%s: no free slot for interface\n",
d ? d->name : "ide");
+ ide_port_free_devices(hwif);
kfree(hwif);
continue;
}
@@ -1341,7 +1367,7 @@ static void ide_disable_port(ide_hwif_t *hwif)
}
int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
- hw_regs_t **hws)
+ struct ide_hw **hws)
{
ide_hwif_t *hwif, *mate = NULL;
int i, j = 0;
@@ -1364,6 +1390,9 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_init_port(hwif, i & 1, d);
ide_port_cable_detect(hwif);
+
+ hwif->port_flags |= IDE_PFLAG_PROBING;
+
ide_port_init_devices(hwif);
}
@@ -1374,6 +1403,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (ide_probe_port(hwif) == 0)
hwif->present = 1;
+ hwif->port_flags &= ~IDE_PFLAG_PROBING;
+
if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
hwif->mate == NULL || hwif->mate->present == 0) {
if (ide_register_port(hwif)) {
@@ -1386,6 +1417,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_port_tune_devices(hwif);
}
+ ide_host_enable_irqs(host);
+
ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
@@ -1416,32 +1449,26 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (hwif == NULL)
continue;
- if (hwif->present)
- hwif_register_devices(hwif);
- }
-
- ide_host_for_each_port(i, hwif, host) {
- if (hwif == NULL)
- continue;
-
ide_sysfs_register_port(hwif);
ide_proc_register_port(hwif);
- if (hwif->present)
+ if (hwif->present) {
ide_proc_port_register_devices(hwif);
+ hwif_register_devices(hwif);
+ }
}
return j ? 0 : -1;
}
EXPORT_SYMBOL_GPL(ide_host_register);
-int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws,
- struct ide_host **hostp)
+int ide_host_add(const struct ide_port_info *d, struct ide_hw **hws,
+ unsigned int n_ports, struct ide_host **hostp)
{
struct ide_host *host;
int rc;
- host = ide_host_alloc(d, hws);
+ host = ide_host_alloc(d, hws, n_ports);
if (host == NULL)
return -ENOMEM;
@@ -1507,7 +1534,8 @@ static void ide_unregister(ide_hwif_t *hwif)
ide_proc_unregister_port(hwif);
- free_irq(hwif->irq, hwif);
+ if (!hwif->host->get_lock)
+ free_irq(hwif->irq, hwif);
device_unregister(hwif->portdev);
device_unregister(&hwif->gendev);
@@ -1555,11 +1583,20 @@ EXPORT_SYMBOL_GPL(ide_host_remove);
void ide_port_scan(ide_hwif_t *hwif)
{
+ int rc;
+
ide_port_apply_params(hwif);
ide_port_cable_detect(hwif);
+
+ hwif->port_flags |= IDE_PFLAG_PROBING;
+
ide_port_init_devices(hwif);
- if (ide_probe_port(hwif) < 0)
+ rc = ide_probe_port(hwif);
+
+ hwif->port_flags &= ~IDE_PFLAG_PROBING;
+
+ if (rc < 0)
return;
hwif->present = 1;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 3242698832a..97c07007777 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -25,16 +25,15 @@
#include <linux/ctype.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
+#include <linux/slab.h>
#include <asm/io.h>
static struct proc_dir_entry *proc_ide_root;
-static int proc_ide_read_imodel
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_imodel_proc_show(struct seq_file *m, void *v)
{
- ide_hwif_t *hwif = (ide_hwif_t *) data;
- int len;
+ ide_hwif_t *hwif = (ide_hwif_t *) m->private;
const char *name;
switch (hwif->chipset) {
@@ -53,63 +52,108 @@ static int proc_ide_read_imodel
case ide_acorn: name = "acorn"; break;
default: name = "(unknown)"; break;
}
- len = sprintf(page, "%s\n", name);
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "%s\n", name);
+ return 0;
+}
+
+static int ide_imodel_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_imodel_proc_show, PDE_DATA(inode));
}
-static int proc_ide_read_mate
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_imodel_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_imodel_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int ide_mate_proc_show(struct seq_file *m, void *v)
{
- ide_hwif_t *hwif = (ide_hwif_t *) data;
- int len;
+ ide_hwif_t *hwif = (ide_hwif_t *) m->private;
if (hwif && hwif->mate)
- len = sprintf(page, "%s\n", hwif->mate->name);
+ seq_printf(m, "%s\n", hwif->mate->name);
else
- len = sprintf(page, "(none)\n");
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "(none)\n");
+ return 0;
}
-static int proc_ide_read_channel
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_mate_proc_open(struct inode *inode, struct file *file)
{
- ide_hwif_t *hwif = (ide_hwif_t *) data;
- int len;
+ return single_open(file, ide_mate_proc_show, PDE_DATA(inode));
+}
- page[0] = hwif->channel ? '1' : '0';
- page[1] = '\n';
- len = 2;
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static const struct file_operations ide_mate_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_mate_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int ide_channel_proc_show(struct seq_file *m, void *v)
+{
+ ide_hwif_t *hwif = (ide_hwif_t *) m->private;
+
+ seq_printf(m, "%c\n", hwif->channel ? '1' : '0');
+ return 0;
}
-static int proc_ide_read_identify
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_channel_proc_open(struct inode *inode, struct file *file)
{
- ide_drive_t *drive = (ide_drive_t *)data;
- int len = 0, i = 0;
- int err = 0;
+ return single_open(file, ide_channel_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations ide_channel_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_channel_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
- len = sprintf(page, "\n");
+static int ide_identify_proc_show(struct seq_file *m, void *v)
+{
+ ide_drive_t *drive = (ide_drive_t *)m->private;
+ u8 *buf;
- if (drive) {
- __le16 *val = (__le16 *)page;
+ if (!drive) {
+ seq_putc(m, '\n');
+ return 0;
+ }
- err = taskfile_lib_get_identify(drive, page);
- if (!err) {
- char *out = (char *)page + SECTOR_SIZE;
+ buf = kmalloc(SECTOR_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ if (taskfile_lib_get_identify(drive, buf) == 0) {
+ __le16 *val = (__le16 *)buf;
+ int i;
- page = out;
- do {
- out += sprintf(out, "%04x%c",
- le16_to_cpup(val), (++i & 7) ? ' ' : '\n');
- val += 1;
- } while (i < SECTOR_SIZE / 2);
- len = out - page;
+ for (i = 0; i < SECTOR_SIZE / 2; i++) {
+ seq_printf(m, "%04x%c", le16_to_cpu(val[i]),
+ (i % 8) == 7 ? '\n' : ' ');
}
- }
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ } else
+ seq_putc(m, buf[0]);
+ kfree(buf);
+ return 0;
+}
+
+static int ide_identify_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_identify_proc_show, PDE_DATA(inode));
}
+static const struct file_operations ide_identify_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_identify_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/**
* ide_find_setting - find a specific setting
* @st: setting table pointer
@@ -195,7 +239,6 @@ ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
struct ide_cmd cmd;
- int err;
if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
return -EINVAL;
@@ -206,14 +249,9 @@ static int set_xfer_rate (ide_drive_t *drive, int arg)
cmd.tf.nsect = (u8)arg;
cmd.valid.out.tf = IDE_VALID_FEATURE | IDE_VALID_NSECT;
cmd.valid.in.tf = IDE_VALID_NSECT;
+ cmd.tf_flags = IDE_TFLAG_SET_XFER;
- err = ide_no_data_taskfile(drive, &cmd);
-
- if (!err) {
- ide_set_xfer_rate(drive, (u8) arg);
- ide_driveid_update(drive);
- }
- return err;
+ return ide_no_data_taskfile(drive, &cmd);
}
ide_devset_rw(current_speed, xfer_rate);
@@ -236,32 +274,24 @@ static const struct ide_proc_devset ide_generic_settings[] = {
static void proc_ide_settings_warn(void)
{
- static int warned;
-
- if (warned)
- return;
-
- printk(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
+ printk_once(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
"obsolete, and will be removed soon!\n");
- warned = 1;
}
-static int proc_ide_read_settings
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_settings_proc_show(struct seq_file *m, void *v)
{
const struct ide_proc_devset *setting, *g, *d;
const struct ide_devset *ds;
- ide_drive_t *drive = (ide_drive_t *) data;
- char *out = page;
- int len, rc, mul_factor, div_factor;
+ ide_drive_t *drive = (ide_drive_t *) m->private;
+ int rc, mul_factor, div_factor;
proc_ide_settings_warn();
mutex_lock(&ide_setting_mtx);
g = ide_generic_settings;
d = drive->settings;
- out += sprintf(out, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
- out += sprintf(out, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
+ seq_printf(m, "name\t\t\tvalue\t\tmin\t\tmax\t\tmode\n");
+ seq_printf(m, "----\t\t\t-----\t\t---\t\t---\t\t----\n");
while (g->name || (d && d->name)) {
/* read settings in the alphabetical order */
if (g->name && d && d->name) {
@@ -275,31 +305,35 @@ static int proc_ide_read_settings
setting = g++;
mul_factor = setting->mulf ? setting->mulf(drive) : 1;
div_factor = setting->divf ? setting->divf(drive) : 1;
- out += sprintf(out, "%-24s", setting->name);
+ seq_printf(m, "%-24s", setting->name);
rc = ide_read_setting(drive, setting);
if (rc >= 0)
- out += sprintf(out, "%-16d", rc * mul_factor / div_factor);
+ seq_printf(m, "%-16d", rc * mul_factor / div_factor);
else
- out += sprintf(out, "%-16s", "write-only");
- out += sprintf(out, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
+ seq_printf(m, "%-16s", "write-only");
+ seq_printf(m, "%-16d%-16d", (setting->min * mul_factor + div_factor - 1) / div_factor, setting->max * mul_factor / div_factor);
ds = setting->setting;
if (ds->get)
- out += sprintf(out, "r");
+ seq_printf(m, "r");
if (ds->set)
- out += sprintf(out, "w");
- out += sprintf(out, "\n");
+ seq_printf(m, "w");
+ seq_printf(m, "\n");
}
- len = out - page;
mutex_unlock(&ide_setting_mtx);
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ return 0;
+}
+
+static int ide_settings_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_settings_proc_show, PDE_DATA(inode));
}
#define MAX_LEN 30
-static int proc_ide_write_settings(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+static ssize_t ide_settings_proc_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *pos)
{
- ide_drive_t *drive = (ide_drive_t *) data;
+ ide_drive_t *drive = PDE_DATA(file_inode(file));
char name[MAX_LEN + 1];
int for_real = 0, mul_factor, div_factor;
unsigned long n;
@@ -394,63 +428,104 @@ static int proc_ide_write_settings(struct file *file, const char __user *buffer,
return count;
parse_error:
free_page((unsigned long)buf);
- printk("proc_ide_write_settings(): parse error\n");
+ printk("%s(): parse error\n", __func__);
return -EINVAL;
}
-int proc_ide_read_capacity
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_settings_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_settings_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = ide_settings_proc_write,
+};
+
+static int ide_capacity_proc_show(struct seq_file *m, void *v)
{
- int len = sprintf(page, "%llu\n", (long long)0x7fffffff);
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "%llu\n", (long long)0x7fffffff);
+ return 0;
}
-EXPORT_SYMBOL_GPL(proc_ide_read_capacity);
+static int ide_capacity_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_capacity_proc_show, NULL);
+}
-int proc_ide_read_geometry
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+const struct file_operations ide_capacity_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_capacity_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+EXPORT_SYMBOL_GPL(ide_capacity_proc_fops);
+
+static int ide_geometry_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t *drive = (ide_drive_t *) data;
- char *out = page;
- int len;
+ ide_drive_t *drive = (ide_drive_t *) m->private;
- out += sprintf(out, "physical %d/%d/%d\n",
+ seq_printf(m, "physical %d/%d/%d\n",
drive->cyl, drive->head, drive->sect);
- out += sprintf(out, "logical %d/%d/%d\n",
+ seq_printf(m, "logical %d/%d/%d\n",
drive->bios_cyl, drive->bios_head, drive->bios_sect);
+ return 0;
+}
- len = out - page;
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+static int ide_geometry_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_geometry_proc_show, PDE_DATA(inode));
}
-EXPORT_SYMBOL(proc_ide_read_geometry);
+const struct file_operations ide_geometry_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_geometry_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+EXPORT_SYMBOL(ide_geometry_proc_fops);
-static int proc_ide_read_dmodel
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_dmodel_proc_show(struct seq_file *seq, void *v)
{
- ide_drive_t *drive = (ide_drive_t *) data;
+ ide_drive_t *drive = (ide_drive_t *) seq->private;
char *m = (char *)&drive->id[ATA_ID_PROD];
- int len;
- len = sprintf(page, "%.40s\n", m[0] ? m : "(none)");
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(seq, "%.40s\n", m[0] ? m : "(none)");
+ return 0;
}
-static int proc_ide_read_driver
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int ide_dmodel_proc_open(struct inode *inode, struct file *file)
{
- ide_drive_t *drive = (ide_drive_t *)data;
+ return single_open(file, ide_dmodel_proc_show, PDE_DATA(inode));
+}
+
+static const struct file_operations ide_dmodel_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_dmodel_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int ide_driver_proc_show(struct seq_file *m, void *v)
+{
+ ide_drive_t *drive = (ide_drive_t *)m->private;
struct device *dev = &drive->gendev;
struct ide_driver *ide_drv;
- int len;
if (dev->driver) {
ide_drv = to_ide_driver(dev->driver);
- len = sprintf(page, "%s version %s\n",
+ seq_printf(m, "%s version %s\n",
dev->driver->name, ide_drv->version);
} else
- len = sprintf(page, "ide-default version 0.9.newide\n");
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "ide-default version 0.9.newide\n");
+ return 0;
+}
+
+static int ide_driver_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_driver_proc_show, PDE_DATA(inode));
}
static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
@@ -480,10 +555,10 @@ static int ide_replace_subdriver(ide_drive_t *drive, const char *driver)
return ret;
}
-static int proc_ide_write_driver
- (struct file *file, const char __user *buffer, unsigned long count, void *data)
+static ssize_t ide_driver_proc_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *pos)
{
- ide_drive_t *drive = (ide_drive_t *) data;
+ ide_drive_t *drive = PDE_DATA(file_inode(file));
char name[32];
if (!capable(CAP_SYS_ADMIN))
@@ -498,12 +573,19 @@ static int proc_ide_write_driver
return count;
}
-static int proc_ide_read_media
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static const struct file_operations ide_driver_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_driver_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .write = ide_driver_proc_write,
+};
+
+static int ide_media_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t *drive = (ide_drive_t *) data;
+ ide_drive_t *drive = (ide_drive_t *) m->private;
const char *media;
- int len;
switch (drive->media) {
case ide_disk: media = "disk\n"; break;
@@ -513,20 +595,30 @@ static int proc_ide_read_media
case ide_optical: media = "optical\n"; break;
default: media = "UNKNOWN\n"; break;
}
- strcpy(page, media);
- len = strlen(media);
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_puts(m, media);
+ return 0;
+}
+
+static int ide_media_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ide_media_proc_show, PDE_DATA(inode));
}
+static const struct file_operations ide_media_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ide_media_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static ide_proc_entry_t generic_drive_entries[] = {
- { "driver", S_IFREG|S_IRUGO, proc_ide_read_driver,
- proc_ide_write_driver },
- { "identify", S_IFREG|S_IRUSR, proc_ide_read_identify, NULL },
- { "media", S_IFREG|S_IRUGO, proc_ide_read_media, NULL },
- { "model", S_IFREG|S_IRUGO, proc_ide_read_dmodel, NULL },
- { "settings", S_IFREG|S_IRUSR|S_IWUSR, proc_ide_read_settings,
- proc_ide_write_settings },
- { NULL, 0, NULL, NULL }
+ { "driver", S_IFREG|S_IRUGO, &ide_driver_proc_fops },
+ { "identify", S_IFREG|S_IRUSR, &ide_identify_proc_fops},
+ { "media", S_IFREG|S_IRUGO, &ide_media_proc_fops },
+ { "model", S_IFREG|S_IRUGO, &ide_dmodel_proc_fops },
+ { "settings", S_IFREG|S_IRUSR|S_IWUSR, &ide_settings_proc_fops},
+ {}
};
static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p, void *data)
@@ -536,11 +628,8 @@ static void ide_add_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p
if (!dir || !p)
return;
while (p->name != NULL) {
- ent = create_proc_entry(p->name, p->mode, dir);
+ ent = proc_create_data(p->name, p->mode, dir, p->proc_fops, data);
if (!ent) return;
- ent->data = data;
- ent->read_proc = p->read_proc;
- ent->write_proc = p->write_proc;
p++;
}
}
@@ -623,10 +712,10 @@ void ide_proc_unregister_device(ide_drive_t *drive)
}
static ide_proc_entry_t hwif_entries[] = {
- { "channel", S_IFREG|S_IRUGO, proc_ide_read_channel, NULL },
- { "mate", S_IFREG|S_IRUGO, proc_ide_read_mate, NULL },
- { "model", S_IFREG|S_IRUGO, proc_ide_read_imodel, NULL },
- { NULL, 0, NULL, NULL }
+ { "channel", S_IFREG|S_IRUGO, &ide_channel_proc_fops },
+ { "mate", S_IFREG|S_IRUGO, &ide_mate_proc_fops },
+ { "model", S_IFREG|S_IRUGO, &ide_imodel_proc_fops },
+ {}
};
void ide_proc_register_port(ide_hwif_t *hwif)
diff --git a/drivers/ide/ide-scan-pci.c b/drivers/ide/ide-scan-pci.c
index 0e79efff1de..c3da53e7bb2 100644
--- a/drivers/ide/ide-scan-pci.c
+++ b/drivers/ide/ide-scan-pci.c
@@ -88,7 +88,7 @@ static int __init ide_scan_pcibus(void)
struct list_head *l, *n;
pre_init = 0;
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
+ for_each_pci_dev(dev)
ide_scan_pcidev(dev);
/*
diff --git a/drivers/ide/ide-sysfs.c b/drivers/ide/ide-sysfs.c
index 883ffacaf45..84a6a9e08d6 100644
--- a/drivers/ide/ide-sysfs.c
+++ b/drivers/ide/ide-sysfs.c
@@ -25,6 +25,7 @@ static ssize_t media_show(struct device *dev, struct device_attribute *attr,
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", ide_media_string(drive));
}
+static DEVICE_ATTR_RO(media);
static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -32,6 +33,7 @@ static ssize_t drivename_show(struct device *dev, struct device_attribute *attr,
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", drive->name);
}
+static DEVICE_ATTR_RO(drivename);
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -39,6 +41,7 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "ide:m-%s\n", ide_media_string(drive));
}
+static DEVICE_ATTR_RO(modalias);
static ssize_t model_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -46,6 +49,7 @@ static ssize_t model_show(struct device *dev, struct device_attribute *attr,
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_PROD]);
}
+static DEVICE_ATTR_RO(model);
static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -53,6 +57,7 @@ static ssize_t firmware_show(struct device *dev, struct device_attribute *attr,
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_FW_REV]);
}
+static DEVICE_ATTR_RO(firmware);
static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -60,16 +65,28 @@ static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", (char *)&drive->id[ATA_ID_SERNO]);
}
+static DEVICE_ATTR(serial, 0400, serial_show, NULL);
+
+static DEVICE_ATTR(unload_heads, 0644, ide_park_show, ide_park_store);
+
+static struct attribute *ide_attrs[] = {
+ &dev_attr_media.attr,
+ &dev_attr_drivename.attr,
+ &dev_attr_modalias.attr,
+ &dev_attr_model.attr,
+ &dev_attr_firmware.attr,
+ &dev_attr_serial.attr,
+ &dev_attr_unload_heads.attr,
+ NULL,
+};
+
+static const struct attribute_group ide_attr_group = {
+ .attrs = ide_attrs,
+};
-struct device_attribute ide_dev_attrs[] = {
- __ATTR_RO(media),
- __ATTR_RO(drivename),
- __ATTR_RO(modalias),
- __ATTR_RO(model),
- __ATTR_RO(firmware),
- __ATTR(serial, 0400, serial_show, NULL),
- __ATTR(unload_heads, 0644, ide_park_show, ide_park_store),
- __ATTR_NULL
+const struct attribute_group *ide_dev_groups[] = {
+ &ide_attr_group,
+ NULL,
};
static ssize_t store_delete_devices(struct device *portdev,
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index cb942a9b580..1793aea4a7d 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -31,44 +31,28 @@
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/ide.h>
-#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/bitops.h>
#include <linux/mutex.h>
#include <scsi/scsi.h>
#include <asm/byteorder.h>
-#include <linux/irq.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <asm/unaligned.h>
#include <linux/mtio.h>
-enum {
- /* output errors only */
- DBG_ERR = (1 << 0),
- /* output all sense key/asc */
- DBG_SENSE = (1 << 1),
- /* info regarding all chrdev-related procedures */
- DBG_CHRDEV = (1 << 2),
- /* all remaining procedures */
- DBG_PROCS = (1 << 3),
-};
-
/* define to see debug info */
-#define IDETAPE_DEBUG_LOG 0
+#undef IDETAPE_DEBUG_LOG
-#if IDETAPE_DEBUG_LOG
-#define debug_log(lvl, fmt, args...) \
-{ \
- if (tape->debug_mask & lvl) \
- printk(KERN_INFO "ide-tape: " fmt, ## args); \
-}
+#ifdef IDETAPE_DEBUG_LOG
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
-#define debug_log(lvl, fmt, args...) do {} while (0)
+#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
/**************************** Tunable parameters *****************************/
@@ -131,13 +115,6 @@ enum {
IDETAPE_DIR_WRITE = (1 << 2),
};
-struct idetape_bh {
- u32 b_size;
- atomic_t b_count;
- struct idetape_bh *b_reqnext;
- char *b_data;
-};
-
/* Tape door status */
#define DOOR_UNLOCKED 0
#define DOOR_LOCKED 1
@@ -177,7 +154,8 @@ typedef struct ide_tape_obj {
* other device. Note that at most we will have only one DSC (usually
* data transfer) request in the device request queue.
*/
- struct request *postponed_rq;
+ bool postponed_rq;
+
/* The time in which we started polling for DSC */
unsigned long dsc_polling_start;
/* Timer used to poll for dsc */
@@ -219,18 +197,12 @@ typedef struct ide_tape_obj {
/* Data buffer size chosen based on the tape's recommendation */
int buffer_size;
- /* merge buffer */
- struct idetape_bh *merge_bh;
- /* size of the merge buffer */
- int merge_bh_size;
- /* pointer to current buffer head within the merge buffer */
- struct idetape_bh *bh;
- char *b_data;
- int b_count;
-
- int pages_per_buffer;
- /* Wasted space in each stage */
- int excess_bh_size;
+ /* Staging buffer of buffer_size bytes */
+ void *buf;
+ /* The read/write cursor */
+ void *cur;
+ /* The number of valid bytes in buf */
+ size_t valid;
/* Measures average tape speed */
unsigned long avg_time;
@@ -243,28 +215,38 @@ typedef struct ide_tape_obj {
char drv_write_prot;
/* the tape is write protected (hardware or opened as read-only) */
char write_prot;
-
- u32 debug_mask;
} idetape_tape_t;
+static DEFINE_MUTEX(ide_tape_mutex);
static DEFINE_MUTEX(idetape_ref_mutex);
+static DEFINE_MUTEX(idetape_chrdev_mutex);
+
static struct class *idetape_sysfs_class;
static void ide_tape_release(struct device *);
-static struct ide_tape_obj *ide_tape_get(struct gendisk *disk)
+static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES];
+
+static struct ide_tape_obj *ide_tape_get(struct gendisk *disk, bool cdev,
+ unsigned int i)
{
struct ide_tape_obj *tape = NULL;
mutex_lock(&idetape_ref_mutex);
- tape = ide_drv_g(disk, ide_tape_obj);
+
+ if (cdev)
+ tape = idetape_devs[i];
+ else
+ tape = ide_drv_g(disk, ide_tape_obj);
+
if (tape) {
if (ide_device_get(tape->drive))
tape = NULL;
else
get_device(&tape->dev);
}
+
mutex_unlock(&idetape_ref_mutex);
return tape;
}
@@ -280,124 +262,27 @@ static void ide_tape_put(struct ide_tape_obj *tape)
}
/*
- * The variables below are used for the character device interface. Additional
- * state variables are defined in our ide_drive_t structure.
- */
-static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES];
-
-static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
-{
- struct ide_tape_obj *tape = NULL;
-
- mutex_lock(&idetape_ref_mutex);
- tape = idetape_devs[i];
- if (tape)
- get_device(&tape->dev);
- mutex_unlock(&idetape_ref_mutex);
- return tape;
-}
-
-static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount)
-{
- struct idetape_bh *bh = pc->bh;
- int count;
-
- while (bcount) {
- if (bh == NULL)
- break;
- count = min(
- (unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
- bcount);
- drive->hwif->tp_ops->input_data(drive, NULL, bh->b_data +
- atomic_read(&bh->b_count), count);
- bcount -= count;
- atomic_add(count, &bh->b_count);
- if (atomic_read(&bh->b_count) == bh->b_size) {
- bh = bh->b_reqnext;
- if (bh)
- atomic_set(&bh->b_count, 0);
- }
- }
-
- pc->bh = bh;
-
- return bcount;
-}
-
-static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount)
-{
- struct idetape_bh *bh = pc->bh;
- int count;
-
- while (bcount) {
- if (bh == NULL)
- break;
- count = min((unsigned int)pc->b_count, (unsigned int)bcount);
- drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
- bcount -= count;
- pc->b_data += count;
- pc->b_count -= count;
- if (!pc->b_count) {
- bh = bh->b_reqnext;
- pc->bh = bh;
- if (bh) {
- pc->b_data = bh->b_data;
- pc->b_count = atomic_read(&bh->b_count);
- }
- }
- }
-
- return bcount;
-}
-
-static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
-{
- struct idetape_bh *bh = pc->bh;
- int count;
- unsigned int bcount = pc->xferred;
-
- if (pc->flags & PC_FLAG_WRITING)
- return;
- while (bcount) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return;
- }
- count = min((unsigned int)bh->b_size, (unsigned int)bcount);
- atomic_set(&bh->b_count, count);
- if (atomic_read(&bh->b_count) == bh->b_size)
- bh = bh->b_reqnext;
- bcount -= count;
- }
- pc->bh = bh;
-}
-
-/*
* called on each failed packet command retry to analyze the request sense. We
* currently do not utilize this information.
*/
-static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
+static void idetape_analyze_error(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = drive->failed_pc;
+ struct request *rq = drive->hwif->rq;
+ u8 *sense = bio_data(rq->bio);
tape->sense_key = sense[2] & 0xF;
tape->asc = sense[12];
tape->ascq = sense[13];
- debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n",
- pc->c[0], tape->sense_key, tape->asc, tape->ascq);
+ ide_debug_log(IDE_DBG_FUNC,
+ "cmd: 0x%x, sense key = %x, asc = %x, ascq = %x",
+ rq->cmd[0], tape->sense_key, tape->asc, tape->ascq);
- /* Correct pc->xferred by asking the tape. */
- if (pc->flags & PC_FLAG_DMA_ERROR) {
- pc->xferred = pc->req_xfer -
- tape->blk_size *
- get_unaligned_be32(&sense[3]);
- idetape_update_buffers(drive, pc);
- }
+ /* correct remaining bytes to transfer */
+ if (pc->flags & PC_FLAG_DMA_ERROR)
+ rq->resid_len = tape->blk_size * get_unaligned_be32(&sense[3]);
/*
* If error was the result of a zero-length read or write command,
@@ -431,34 +316,11 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
pc->flags |= PC_FLAG_ABORT;
}
if (!(pc->flags & PC_FLAG_ABORT) &&
- pc->xferred)
+ (blk_rq_bytes(rq) - rq->resid_len))
pc->retries = IDETAPE_MAX_PC_RETRIES + 1;
}
}
-/* Free data buffers completely. */
-static void ide_tape_kfree_buffer(idetape_tape_t *tape)
-{
- struct idetape_bh *prev_bh, *bh = tape->merge_bh;
-
- while (bh) {
- u32 size = bh->b_size;
-
- while (size) {
- unsigned int order = fls(size >> PAGE_SHIFT)-1;
-
- if (bh->b_data)
- free_pages((unsigned long)bh->b_data, order);
-
- size &= (order-1);
- bh->b_data += (1 << order) * PAGE_SIZE;
- }
- prev_bh = bh;
- bh = bh->b_reqnext;
- kfree(prev_bh);
- }
-}
-
static void ide_tape_handle_dsc(ide_drive_t *);
static int ide_tape_callback(ide_drive_t *drive, int dsc)
@@ -469,7 +331,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
int uptodate = pc->error ? 0 : 1;
int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc: %d, err: %d", rq->cmd[0],
+ dsc, err);
if (dsc)
ide_tape_handle_dsc(drive);
@@ -479,12 +342,13 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
if (pc->c[0] == REQUEST_SENSE) {
if (uptodate)
- idetape_analyze_error(drive, pc->buf);
+ idetape_analyze_error(drive);
else
printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
"itself - Aborting request!\n");
} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
- int blocks = pc->xferred / tape->blk_size;
+ unsigned int blocks =
+ (blk_rq_bytes(rq) - rq->resid_len) / tape->blk_size;
tape->avg_size += blocks * tape->blk_size;
@@ -496,36 +360,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
}
tape->first_frame += blocks;
- rq->current_nr_sectors -= blocks;
if (pc->error) {
uptodate = 0;
err = pc->error;
}
- } else if (pc->c[0] == READ_POSITION && uptodate) {
- u8 *readpos = pc->buf;
-
- debug_log(DBG_SENSE, "BOP - %s\n",
- (readpos[0] & 0x80) ? "Yes" : "No");
- debug_log(DBG_SENSE, "EOP - %s\n",
- (readpos[0] & 0x40) ? "Yes" : "No");
-
- if (readpos[0] & 0x4) {
- printk(KERN_INFO "ide-tape: Block location is unknown"
- "to the tape\n");
- clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
- uptodate = 0;
- err = IDE_DRV_ERROR_GENERAL;
- } else {
- debug_log(DBG_SENSE, "Block Location - %u\n",
- be32_to_cpup((__be32 *)&readpos[4]));
-
- tape->partition = readpos[1];
- tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]);
- set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
- }
}
-
rq->errors = err;
return uptodate;
@@ -535,13 +375,14 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
* Postpone the current request so that ide.c will be able to service requests
* from another device on the same port while we are polling for DSC.
*/
-static void idetape_postpone_request(ide_drive_t *drive)
+static void ide_tape_stall_queue(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, dsc_poll_freq: %lu",
+ drive->hwif->rq->cmd[0], tape->dsc_poll_freq);
- tape->postponed_rq = drive->hwif->rq;
+ tape->postponed_rq = true;
ide_stall_queue(drive, tape->dsc_poll_freq);
}
@@ -555,20 +396,7 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST;
tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT;
/* Allow ide.c to handle other requests */
- idetape_postpone_request(drive);
-}
-
-static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int write)
-{
- unsigned int bleft;
-
- if (write)
- bleft = idetape_output_buffers(drive, pc, bcount);
- else
- bleft = idetape_input_buffers(drive, pc, bcount);
-
- return bcount - bleft;
+ ide_tape_stall_queue(drive);
}
/*
@@ -613,12 +441,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
idetape_tape_t *tape = drive->driver_data;
-
- if (drive->pc->c[0] == REQUEST_SENSE &&
- pc->c[0] == REQUEST_SENSE) {
- printk(KERN_ERR "ide-tape: possible ide-tape.c bug - "
- "Two request sense in serial were issued\n");
- }
+ struct request *rq = drive->hwif->rq;
if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
drive->failed_pc = pc;
@@ -628,6 +451,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
(pc->flags & PC_FLAG_ABORT)) {
+
/*
* We will "abort" retrying a packet command in case legitimate
* error code was received (crossing a filemark, or end of the
@@ -647,11 +471,14 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
/* Giving up */
pc->error = IDE_DRV_ERROR_GENERAL;
}
+
drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
+ ide_complete_rq(drive, -EIO, blk_rq_bytes(rq));
return ide_stopped;
}
- debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]);
+ ide_debug_log(IDE_DBG_SENSE, "retry #%d, cmd: 0x%02x", pc->retries,
+ pc->c[0]);
pc->retries++;
@@ -701,7 +528,7 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
printk(KERN_ERR "ide-tape: %s: I/O error, ",
tape->name);
/* Retry operation */
- ide_retry_pc(drive, tape->disk);
+ ide_retry_pc(drive);
return ide_stopped;
}
pc->error = 0;
@@ -717,27 +544,20 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
struct ide_atapi_pc *pc, struct request *rq,
u8 opcode)
{
- struct idetape_bh *bh = (struct idetape_bh *)rq->special;
- unsigned int length = rq->current_nr_sectors;
+ unsigned int length = blk_rq_sectors(rq) / (tape->blk_size >> 9);
ide_init_pc(pc);
put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]);
pc->c[1] = 1;
- pc->bh = bh;
- pc->buf = NULL;
- pc->buf_size = length * tape->blk_size;
- pc->req_xfer = pc->buf_size;
- if (pc->req_xfer == tape->buffer_size)
+
+ if (blk_rq_bytes(rq) == tape->buffer_size)
pc->flags |= PC_FLAG_DMA_OK;
- if (opcode == READ_6) {
+ if (opcode == READ_6)
pc->c[0] = READ_6;
- atomic_set(&bh->b_count, 0);
- } else if (opcode == WRITE_6) {
+ else if (opcode == WRITE_6) {
pc->c[0] = WRITE_6;
pc->flags |= PC_FLAG_WRITING;
- pc->b_data = bh->b_data;
- pc->b_count = atomic_read(&bh->b_count);
}
memcpy(rq->cmd, pc->c, 12);
@@ -749,24 +569,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
ide_hwif_t *hwif = drive->hwif;
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = NULL;
- struct request *postponed_rq = tape->postponed_rq;
struct ide_cmd cmd;
u8 stat;
- debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
- " current_nr_sectors: %u\n",
- (unsigned long long)rq->sector, rq->nr_sectors,
- rq->current_nr_sectors);
-
- if (!blk_special_request(rq)) {
- /* We do not support buffer cache originated requests. */
- printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
- "request queue (%d)\n", drive->name, rq->cmd_type);
- if (blk_fs_request(rq) == 0 && rq->errors == 0)
- rq->errors = -EIO;
- ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
- return ide_stopped;
- }
+ ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, sector: %llu, nr_sectors: %u",
+ rq->cmd[0], (unsigned long long)blk_rq_pos(rq),
+ blk_rq_sectors(rq));
+
+ BUG_ON(!(rq->cmd_type == REQ_TYPE_SPECIAL ||
+ rq->cmd_type == REQ_TYPE_SENSE));
/* Retry a failed packet command */
if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
@@ -774,18 +585,6 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
goto out;
}
- if (postponed_rq != NULL)
- if (rq != postponed_rq) {
- printk(KERN_ERR "ide-tape: ide-tape.c bug - "
- "Two DSC requests were queued\n");
- drive->failed_pc = NULL;
- rq->errors = 0;
- ide_complete_rq(drive, 0, blk_rq_bytes(rq));
- return ide_stopped;
- }
-
- tape->postponed_rq = NULL;
-
/*
* If the tape is still busy, postpone our request and service
* the other device meanwhile.
@@ -794,16 +593,16 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 &&
(rq->cmd[13] & REQ_IDETAPE_PC2) == 0)
- set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
+ drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
if (drive->dev_flags & IDE_DFLAG_POST_RESET) {
- set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags);
+ drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
drive->dev_flags &= ~IDE_DFLAG_POST_RESET;
}
- if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) &&
- (stat & ATA_DSC) == 0) {
- if (postponed_rq == NULL) {
+ if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) &&
+ !(stat & ATA_DSC)) {
+ if (!tape->postponed_rq) {
tape->dsc_polling_start = jiffies;
tape->dsc_poll_freq = tape->best_dsc_rw_freq;
tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT;
@@ -820,9 +619,13 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
tape->dsc_polling_start +
IDETAPE_DSC_MA_THRESHOLD))
tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW;
- idetape_postpone_request(drive);
+ ide_tape_stall_queue(drive);
return ide_stopped;
+ } else {
+ drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC;
+ tape->postponed_rq = false;
}
+
if (rq->cmd[13] & REQ_IDETAPE_READ) {
pc = &tape->queued_pc;
ide_tape_create_rw_cmd(tape, pc, rq, READ_6);
@@ -834,7 +637,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
goto out;
}
if (rq->cmd[13] & REQ_IDETAPE_PC1) {
- pc = (struct ide_atapi_pc *) rq->buffer;
+ pc = (struct ide_atapi_pc *)rq->special;
rq->cmd[13] &= ~(REQ_IDETAPE_PC1);
rq->cmd[13] |= REQ_IDETAPE_PC2;
goto out;
@@ -846,6 +649,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
BUG();
out:
+ /* prepare sense request for this command */
+ ide_prep_sense(drive, rq);
+
memset(&cmd, 0, sizeof(cmd));
if (rq_data_dir(rq))
@@ -853,167 +659,10 @@ out:
cmd.rq = rq;
- return ide_tape_issue_pc(drive, &cmd, pc);
-}
-
-/*
- * The function below uses __get_free_pages to allocate a data buffer of size
- * tape->buffer_size (or a bit more). We attempt to combine sequential pages as
- * much as possible.
- *
- * It returns a pointer to the newly allocated buffer, or NULL in case of
- * failure.
- */
-static struct idetape_bh *ide_tape_kmalloc_buffer(idetape_tape_t *tape,
- int full, int clear)
-{
- struct idetape_bh *prev_bh, *bh, *merge_bh;
- int pages = tape->pages_per_buffer;
- unsigned int order, b_allocd;
- char *b_data = NULL;
-
- merge_bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
- bh = merge_bh;
- if (bh == NULL)
- goto abort;
-
- order = fls(pages) - 1;
- bh->b_data = (char *) __get_free_pages(GFP_KERNEL, order);
- if (!bh->b_data)
- goto abort;
- b_allocd = (1 << order) * PAGE_SIZE;
- pages &= (order-1);
-
- if (clear)
- memset(bh->b_data, 0, b_allocd);
- bh->b_reqnext = NULL;
- bh->b_size = b_allocd;
- atomic_set(&bh->b_count, full ? bh->b_size : 0);
-
- while (pages) {
- order = fls(pages) - 1;
- b_data = (char *) __get_free_pages(GFP_KERNEL, order);
- if (!b_data)
- goto abort;
- b_allocd = (1 << order) * PAGE_SIZE;
-
- if (clear)
- memset(b_data, 0, b_allocd);
-
- /* newly allocated page frames below buffer header or ...*/
- if (bh->b_data == b_data + b_allocd) {
- bh->b_size += b_allocd;
- bh->b_data -= b_allocd;
- if (full)
- atomic_add(b_allocd, &bh->b_count);
- continue;
- }
- /* they are above the header */
- if (b_data == bh->b_data + bh->b_size) {
- bh->b_size += b_allocd;
- if (full)
- atomic_add(b_allocd, &bh->b_count);
- continue;
- }
- prev_bh = bh;
- bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL);
- if (!bh) {
- free_pages((unsigned long) b_data, order);
- goto abort;
- }
- bh->b_reqnext = NULL;
- bh->b_data = b_data;
- bh->b_size = b_allocd;
- atomic_set(&bh->b_count, full ? bh->b_size : 0);
- prev_bh->b_reqnext = bh;
-
- pages &= (order-1);
- }
-
- bh->b_size -= tape->excess_bh_size;
- if (full)
- atomic_sub(tape->excess_bh_size, &bh->b_count);
- return merge_bh;
-abort:
- ide_tape_kfree_buffer(tape);
- return NULL;
-}
-
-static int idetape_copy_stage_from_user(idetape_tape_t *tape,
- const char __user *buf, int n)
-{
- struct idetape_bh *bh = tape->bh;
- int count;
- int ret = 0;
-
- while (n) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return 1;
- }
- count = min((unsigned int)
- (bh->b_size - atomic_read(&bh->b_count)),
- (unsigned int)n);
- if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf,
- count))
- ret = 1;
- n -= count;
- atomic_add(count, &bh->b_count);
- buf += count;
- if (atomic_read(&bh->b_count) == bh->b_size) {
- bh = bh->b_reqnext;
- if (bh)
- atomic_set(&bh->b_count, 0);
- }
- }
- tape->bh = bh;
- return ret;
-}
-
-static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf,
- int n)
-{
- struct idetape_bh *bh = tape->bh;
- int count;
- int ret = 0;
-
- while (n) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return 1;
- }
- count = min(tape->b_count, n);
- if (copy_to_user(buf, tape->b_data, count))
- ret = 1;
- n -= count;
- tape->b_data += count;
- tape->b_count -= count;
- buf += count;
- if (!tape->b_count) {
- bh = bh->b_reqnext;
- tape->bh = bh;
- if (bh) {
- tape->b_data = bh->b_data;
- tape->b_count = atomic_read(&bh->b_count);
- }
- }
- }
- return ret;
-}
+ ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
+ ide_map_sg(drive, &cmd);
-static void idetape_init_merge_buffer(idetape_tape_t *tape)
-{
- struct idetape_bh *bh = tape->merge_bh;
- tape->bh = tape->merge_bh;
-
- if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
- atomic_set(&bh->b_count, 0);
- else {
- tape->b_data = bh->b_data;
- tape->b_count = atomic_read(&bh->b_count);
- }
+ return ide_tape_issue_pc(drive, &cmd, pc);
}
/*
@@ -1036,7 +685,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout)
int load_attempted = 0;
/* Wait for the tape to become ready */
- set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
+ set_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), &drive->atapi_flags);
timeout += jiffies;
while (time_before(jiffies, timeout)) {
if (ide_do_test_unit_ready(drive, disk) == 0)
@@ -1064,33 +713,53 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive)
int rc;
idetape_create_write_filemark_cmd(drive, &pc, 0);
- rc = ide_queue_pc_tail(drive, tape->disk, &pc);
+ rc = ide_queue_pc_tail(drive, tape->disk, &pc, NULL, 0);
if (rc)
return rc;
idetape_wait_ready(drive, 60 * 5 * HZ);
return 0;
}
-static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc)
-{
- ide_init_pc(pc);
- pc->c[0] = READ_POSITION;
- pc->req_xfer = 20;
-}
-
-static int idetape_read_position(ide_drive_t *drive)
+static int ide_tape_read_position(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
- int position;
+ u8 buf[20];
+
+ ide_debug_log(IDE_DBG_FUNC, "enter");
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
+ /* prep cmd */
+ ide_init_pc(&pc);
+ pc.c[0] = READ_POSITION;
+ pc.req_xfer = 20;
- idetape_create_read_position_cmd(&pc);
- if (ide_queue_pc_tail(drive, tape->disk, &pc))
+ if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer))
return -1;
- position = tape->first_frame;
- return position;
+
+ if (!pc.error) {
+ ide_debug_log(IDE_DBG_FUNC, "BOP - %s",
+ (buf[0] & 0x80) ? "Yes" : "No");
+ ide_debug_log(IDE_DBG_FUNC, "EOP - %s",
+ (buf[0] & 0x40) ? "Yes" : "No");
+
+ if (buf[0] & 0x4) {
+ printk(KERN_INFO "ide-tape: Block location is unknown"
+ "to the tape\n");
+ clear_bit(ilog2(IDE_AFLAG_ADDRESS_VALID),
+ &drive->atapi_flags);
+ return -1;
+ } else {
+ ide_debug_log(IDE_DBG_FUNC, "Block Location: %u",
+ be32_to_cpup((__be32 *)&buf[4]));
+
+ tape->partition = buf[1];
+ tape->first_frame = be32_to_cpup((__be32 *)&buf[4]);
+ set_bit(ilog2(IDE_AFLAG_ADDRESS_VALID),
+ &drive->atapi_flags);
+ }
+ }
+
+ return tape->first_frame;
}
static void idetape_create_locate_cmd(ide_drive_t *drive,
@@ -1112,11 +781,11 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
if (tape->chrdev_dir != IDETAPE_DIR_READ)
return;
- clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags);
- tape->merge_bh_size = 0;
- if (tape->merge_bh != NULL) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
+ clear_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags);
+ tape->valid = 0;
+ if (tape->buf != NULL) {
+ kfree(tape->buf);
+ tape->buf = NULL;
}
tape->chrdev_dir = IDETAPE_DIR_NONE;
@@ -1133,19 +802,21 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block,
{
idetape_tape_t *tape = drive->driver_data;
struct gendisk *disk = tape->disk;
- int retval;
+ int ret;
struct ide_atapi_pc pc;
if (tape->chrdev_dir == IDETAPE_DIR_READ)
__ide_tape_discard_merge_buffer(drive);
idetape_wait_ready(drive, 60 * 5 * HZ);
idetape_create_locate_cmd(drive, &pc, block, partition, skip);
- retval = ide_queue_pc_tail(drive, disk, &pc);
- if (retval)
- return (retval);
+ ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
+ if (ret)
+ return ret;
- idetape_create_read_position_cmd(&pc);
- return ide_queue_pc_tail(drive, disk, &pc);
+ ret = ide_tape_read_position(drive);
+ if (ret < 0)
+ return ret;
+ return 0;
}
static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
@@ -1156,7 +827,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
__ide_tape_discard_merge_buffer(drive);
if (restore_position) {
- position = idetape_read_position(drive);
+ position = ide_tape_read_position(drive);
seek = position > 0 ? position : 0;
if (idetape_position_tape(drive, seek, 0, 0)) {
printk(KERN_INFO "ide-tape: %s: position_tape failed in"
@@ -1170,36 +841,45 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive,
* Generate a read/write request for the block device interface and wait for it
* to be serviced.
*/
-static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
- struct idetape_bh *bh)
+static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
{
idetape_tape_t *tape = drive->driver_data;
struct request *rq;
- int ret, errors;
+ int ret;
- debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd);
+ ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, size: %d", cmd, size);
+
+ BUG_ON(cmd != REQ_IDETAPE_READ && cmd != REQ_IDETAPE_WRITE);
+ BUG_ON(size < 0 || size % tape->blk_size);
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->cmd[13] = cmd;
rq->rq_disk = tape->disk;
- rq->special = (void *)bh;
- rq->sector = tape->first_frame;
- rq->nr_sectors = blocks;
- rq->current_nr_sectors = blocks;
- blk_execute_rq(drive->queue, tape->disk, rq, 0);
+ rq->__sector = tape->first_frame;
- errors = rq->errors;
- ret = tape->blk_size * (blocks - rq->current_nr_sectors);
- blk_put_request(rq);
+ if (size) {
+ ret = blk_rq_map_kern(drive->queue, rq, tape->buf, size,
+ __GFP_WAIT);
+ if (ret)
+ goto out_put;
+ }
- if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0)
- return 0;
+ blk_execute_rq(drive->queue, tape->disk, rq, 0);
- if (tape->merge_bh)
- idetape_init_merge_buffer(tape);
- if (errors == IDE_DRV_ERROR_GENERAL)
- return -EIO;
+ /* calculate the number of transferred bytes and update buffer state */
+ size -= rq->resid_len;
+ tape->cur = tape->buf;
+ if (cmd == REQ_IDETAPE_READ)
+ tape->valid = size;
+ else
+ tape->valid = 0;
+
+ ret = size;
+ if (rq->errors == IDE_DRV_ERROR_GENERAL)
+ ret = -EIO;
+out_put:
+ blk_put_request(rq);
return ret;
}
@@ -1236,153 +916,87 @@ static void idetape_create_space_cmd(struct ide_atapi_pc *pc, int count, u8 cmd)
pc->flags |= PC_FLAG_WAIT_FOR_DSC;
}
-/* Queue up a character device originated write request. */
-static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks)
-{
- idetape_tape_t *tape = drive->driver_data;
-
- debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
-
- return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
- blocks, tape->merge_bh);
-}
-
static void ide_tape_flush_merge_buffer(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
- int blocks, min;
- struct idetape_bh *bh;
if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
printk(KERN_ERR "ide-tape: bug: Trying to empty merge buffer"
" but we are not writing.\n");
return;
}
- if (tape->merge_bh_size > tape->buffer_size) {
- printk(KERN_ERR "ide-tape: bug: merge_buffer too big\n");
- tape->merge_bh_size = tape->buffer_size;
- }
- if (tape->merge_bh_size) {
- blocks = tape->merge_bh_size / tape->blk_size;
- if (tape->merge_bh_size % tape->blk_size) {
- unsigned int i;
-
- blocks++;
- i = tape->blk_size - tape->merge_bh_size %
- tape->blk_size;
- bh = tape->bh->b_reqnext;
- while (bh) {
- atomic_set(&bh->b_count, 0);
- bh = bh->b_reqnext;
- }
- bh = tape->bh;
- while (i) {
- if (bh == NULL) {
- printk(KERN_INFO "ide-tape: bug,"
- " bh NULL\n");
- break;
- }
- min = min(i, (unsigned int)(bh->b_size -
- atomic_read(&bh->b_count)));
- memset(bh->b_data + atomic_read(&bh->b_count),
- 0, min);
- atomic_add(min, &bh->b_count);
- i -= min;
- bh = bh->b_reqnext;
- }
- }
- (void) idetape_add_chrdev_write_request(drive, blocks);
- tape->merge_bh_size = 0;
- }
- if (tape->merge_bh != NULL) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
+ if (tape->buf) {
+ size_t aligned = roundup(tape->valid, tape->blk_size);
+
+ memset(tape->cur, 0, aligned - tape->valid);
+ idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, aligned);
+ kfree(tape->buf);
+ tape->buf = NULL;
}
tape->chrdev_dir = IDETAPE_DIR_NONE;
}
-static int idetape_init_read(ide_drive_t *drive)
+static int idetape_init_rw(ide_drive_t *drive, int dir)
{
idetape_tape_t *tape = drive->driver_data;
- int bytes_read;
+ int rc;
- /* Initialize read operation */
- if (tape->chrdev_dir != IDETAPE_DIR_READ) {
- if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
- ide_tape_flush_merge_buffer(drive);
- idetape_flush_tape_buffers(drive);
- }
- if (tape->merge_bh || tape->merge_bh_size) {
- printk(KERN_ERR "ide-tape: merge_bh_size should be"
- " 0 now\n");
- tape->merge_bh_size = 0;
- }
- tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
- if (!tape->merge_bh)
- return -ENOMEM;
- tape->chrdev_dir = IDETAPE_DIR_READ;
+ BUG_ON(dir != IDETAPE_DIR_READ && dir != IDETAPE_DIR_WRITE);
- /*
- * Issue a read 0 command to ensure that DSC handshake is
- * switched from completion mode to buffer available mode.
- * No point in issuing this if DSC overlap isn't supported, some
- * drives (Seagate STT3401A) will return an error.
- */
- if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
- bytes_read = idetape_queue_rw_tail(drive,
- REQ_IDETAPE_READ, 0,
- tape->merge_bh);
- if (bytes_read < 0) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
- tape->chrdev_dir = IDETAPE_DIR_NONE;
- return bytes_read;
- }
- }
- }
-
- return 0;
-}
+ if (tape->chrdev_dir == dir)
+ return 0;
-/* called from idetape_chrdev_read() to service a chrdev read request. */
-static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks)
-{
- idetape_tape_t *tape = drive->driver_data;
+ if (tape->chrdev_dir == IDETAPE_DIR_READ)
+ ide_tape_discard_merge_buffer(drive, 1);
+ else if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
+ ide_tape_flush_merge_buffer(drive);
+ idetape_flush_tape_buffers(drive);
+ }
- debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks);
+ if (tape->buf || tape->valid) {
+ printk(KERN_ERR "ide-tape: valid should be 0 now\n");
+ tape->valid = 0;
+ }
- /* If we are at a filemark, return a read length of 0 */
- if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
- return 0;
+ tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL);
+ if (!tape->buf)
+ return -ENOMEM;
+ tape->chrdev_dir = dir;
+ tape->cur = tape->buf;
- idetape_init_read(drive);
+ /*
+ * Issue a 0 rw command to ensure that DSC handshake is
+ * switched from completion mode to buffer available mode. No
+ * point in issuing this if DSC overlap isn't supported, some
+ * drives (Seagate STT3401A) will return an error.
+ */
+ if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
+ int cmd = dir == IDETAPE_DIR_READ ? REQ_IDETAPE_READ
+ : REQ_IDETAPE_WRITE;
+
+ rc = idetape_queue_rw_tail(drive, cmd, 0);
+ if (rc < 0) {
+ kfree(tape->buf);
+ tape->buf = NULL;
+ tape->chrdev_dir = IDETAPE_DIR_NONE;
+ return rc;
+ }
+ }
- return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks,
- tape->merge_bh);
+ return 0;
}
static void idetape_pad_zeros(ide_drive_t *drive, int bcount)
{
idetape_tape_t *tape = drive->driver_data;
- struct idetape_bh *bh;
- int blocks;
+
+ memset(tape->buf, 0, tape->buffer_size);
while (bcount) {
- unsigned int count;
+ unsigned int count = min(tape->buffer_size, bcount);
- bh = tape->merge_bh;
- count = min(tape->buffer_size, bcount);
+ idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, count);
bcount -= count;
- blocks = count / tape->blk_size;
- while (count) {
- atomic_set(&bh->b_count,
- min(count, (unsigned int)bh->b_size));
- memset(bh->b_data, 0, atomic_read(&bh->b_count));
- count -= atomic_read(&bh->b_count);
- bh = bh->b_reqnext;
- }
- idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks,
- tape->merge_bh);
}
}
@@ -1394,20 +1008,19 @@ static int idetape_rewind_tape(ide_drive_t *drive)
{
struct ide_tape_obj *tape = drive->driver_data;
struct gendisk *disk = tape->disk;
- int retval;
struct ide_atapi_pc pc;
+ int ret;
- debug_log(DBG_SENSE, "Enter %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
idetape_create_rewind_cmd(drive, &pc);
- retval = ide_queue_pc_tail(drive, disk, &pc);
- if (retval)
- return retval;
+ ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
+ if (ret)
+ return ret;
- idetape_create_read_position_cmd(&pc);
- retval = ide_queue_pc_tail(drive, disk, &pc);
- if (retval)
- return retval;
+ ret = ide_tape_read_position(drive);
+ if (ret < 0)
+ return ret;
return 0;
}
@@ -1424,7 +1037,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
int nr_stages;
} config;
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%04x", cmd);
switch (cmd) {
case 0x0340:
@@ -1433,6 +1046,7 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd,
tape->best_dsc_rw_freq = config.dsc_rw_frequency;
break;
case 0x0350:
+ memset(&config, 0, sizeof(config));
config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq;
config.nr_stages = 1;
if (copy_to_user(argp, &config, sizeof(config)))
@@ -1453,6 +1067,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
int retval, count = 0;
int sprev = !!(tape->caps[4] & 0x20);
+
+ ide_debug_log(IDE_DBG_FUNC, "mt_op: %d, mt_count: %d", mt_op, mt_count);
+
if (mt_count == 0)
return 0;
if (MTBSF == mt_op || MTBSFM == mt_op) {
@@ -1462,8 +1079,9 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
}
if (tape->chrdev_dir == IDETAPE_DIR_READ) {
- tape->merge_bh_size = 0;
- if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags))
+ tape->valid = 0;
+ if (test_and_clear_bit(ilog2(IDE_AFLAG_FILEMARK),
+ &drive->atapi_flags))
++count;
ide_tape_discard_merge_buffer(drive, 0);
}
@@ -1473,7 +1091,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op,
case MTBSF:
idetape_create_space_cmd(&pc, mt_count - count,
IDETAPE_SPACE_OVER_FILEMARK);
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
case MTFSFM:
case MTBSFM:
if (!sprev)
@@ -1511,61 +1129,54 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf,
{
struct ide_tape_obj *tape = file->private_data;
ide_drive_t *drive = tape->drive;
- ssize_t bytes_read, temp, actually_read = 0, rc;
+ size_t done = 0;
ssize_t ret = 0;
- u16 ctl = *(u16 *)&tape->caps[12];
+ int rc;
- debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
+ ide_debug_log(IDE_DBG_FUNC, "count %Zd", count);
if (tape->chrdev_dir != IDETAPE_DIR_READ) {
- if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags))
+ if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags))
if (count > tape->blk_size &&
(count % tape->blk_size) == 0)
tape->user_bs_factor = count / tape->blk_size;
}
- rc = idetape_init_read(drive);
+
+ rc = idetape_init_rw(drive, IDETAPE_DIR_READ);
if (rc < 0)
return rc;
- if (count == 0)
- return (0);
- if (tape->merge_bh_size) {
- actually_read = min((unsigned int)(tape->merge_bh_size),
- (unsigned int)count);
- if (idetape_copy_stage_to_user(tape, buf, actually_read))
- ret = -EFAULT;
- buf += actually_read;
- tape->merge_bh_size -= actually_read;
- count -= actually_read;
- }
- while (count >= tape->buffer_size) {
- bytes_read = idetape_add_chrdev_read_request(drive, ctl);
- if (bytes_read <= 0)
- goto finish;
- if (idetape_copy_stage_to_user(tape, buf, bytes_read))
- ret = -EFAULT;
- buf += bytes_read;
- count -= bytes_read;
- actually_read += bytes_read;
- }
- if (count) {
- bytes_read = idetape_add_chrdev_read_request(drive, ctl);
- if (bytes_read <= 0)
- goto finish;
- temp = min((unsigned long)count, (unsigned long)bytes_read);
- if (idetape_copy_stage_to_user(tape, buf, temp))
+
+ while (done < count) {
+ size_t todo;
+
+ /* refill if staging buffer is empty */
+ if (!tape->valid) {
+ /* If we are at a filemark, nothing more to read */
+ if (test_bit(ilog2(IDE_AFLAG_FILEMARK),
+ &drive->atapi_flags))
+ break;
+ /* read */
+ if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ,
+ tape->buffer_size) <= 0)
+ break;
+ }
+
+ /* copy out */
+ todo = min_t(size_t, count - done, tape->valid);
+ if (copy_to_user(buf + done, tape->cur, todo))
ret = -EFAULT;
- actually_read += temp;
- tape->merge_bh_size = bytes_read-temp;
+
+ tape->cur += todo;
+ tape->valid -= todo;
+ done += todo;
}
-finish:
- if (!actually_read && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) {
- debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name);
+ if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) {
idetape_space_over_filemarks(drive, MTFSF, 1);
return 0;
}
- return ret ? ret : actually_read;
+ return ret ? ret : done;
}
static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
@@ -1573,91 +1184,42 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf,
{
struct ide_tape_obj *tape = file->private_data;
ide_drive_t *drive = tape->drive;
- ssize_t actually_written = 0;
+ size_t done = 0;
ssize_t ret = 0;
- u16 ctl = *(u16 *)&tape->caps[12];
+ int rc;
/* The drive is write protected. */
if (tape->write_prot)
return -EACCES;
- debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count);
+ ide_debug_log(IDE_DBG_FUNC, "count %Zd", count);
/* Initialize write operation */
- if (tape->chrdev_dir != IDETAPE_DIR_WRITE) {
- if (tape->chrdev_dir == IDETAPE_DIR_READ)
- ide_tape_discard_merge_buffer(drive, 1);
- if (tape->merge_bh || tape->merge_bh_size) {
- printk(KERN_ERR "ide-tape: merge_bh_size "
- "should be 0 now\n");
- tape->merge_bh_size = 0;
- }
- tape->merge_bh = ide_tape_kmalloc_buffer(tape, 0, 0);
- if (!tape->merge_bh)
- return -ENOMEM;
- tape->chrdev_dir = IDETAPE_DIR_WRITE;
- idetape_init_merge_buffer(tape);
+ rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE);
+ if (rc < 0)
+ return rc;
- /*
- * Issue a write 0 command to ensure that DSC handshake is
- * switched from completion mode to buffer available mode. No
- * point in issuing this if DSC overlap isn't supported, some
- * drives (Seagate STT3401A) will return an error.
- */
- if (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) {
- ssize_t retval = idetape_queue_rw_tail(drive,
- REQ_IDETAPE_WRITE, 0,
- tape->merge_bh);
- if (retval < 0) {
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
- tape->chrdev_dir = IDETAPE_DIR_NONE;
- return retval;
- }
- }
- }
- if (count == 0)
- return (0);
- if (tape->merge_bh_size) {
- if (tape->merge_bh_size >= tape->buffer_size) {
- printk(KERN_ERR "ide-tape: bug: merge buf too big\n");
- tape->merge_bh_size = 0;
- }
- actually_written = min((unsigned int)
- (tape->buffer_size - tape->merge_bh_size),
- (unsigned int)count);
- if (idetape_copy_stage_from_user(tape, buf, actually_written))
- ret = -EFAULT;
- buf += actually_written;
- tape->merge_bh_size += actually_written;
- count -= actually_written;
-
- if (tape->merge_bh_size == tape->buffer_size) {
- ssize_t retval;
- tape->merge_bh_size = 0;
- retval = idetape_add_chrdev_write_request(drive, ctl);
- if (retval <= 0)
- return (retval);
- }
- }
- while (count >= tape->buffer_size) {
- ssize_t retval;
- if (idetape_copy_stage_from_user(tape, buf, tape->buffer_size))
- ret = -EFAULT;
- buf += tape->buffer_size;
- count -= tape->buffer_size;
- retval = idetape_add_chrdev_write_request(drive, ctl);
- actually_written += tape->buffer_size;
- if (retval <= 0)
- return (retval);
- }
- if (count) {
- actually_written += count;
- if (idetape_copy_stage_from_user(tape, buf, count))
+ while (done < count) {
+ size_t todo;
+
+ /* flush if staging buffer is full */
+ if (tape->valid == tape->buffer_size &&
+ idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE,
+ tape->buffer_size) <= 0)
+ return rc;
+
+ /* copy in */
+ todo = min_t(size_t, count - done,
+ tape->buffer_size - tape->valid);
+ if (copy_from_user(tape->cur, buf + done, todo))
ret = -EFAULT;
- tape->merge_bh_size += count;
+
+ tape->cur += todo;
+ tape->valid += todo;
+ done += todo;
}
- return ret ? ret : actually_written;
+
+ return ret ? ret : done;
}
static int idetape_write_filemark(ide_drive_t *drive)
@@ -1667,7 +1229,7 @@ static int idetape_write_filemark(ide_drive_t *drive)
/* Write a filemark */
idetape_create_write_filemark_cmd(drive, &pc, 1);
- if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc, NULL, 0)) {
printk(KERN_ERR "ide-tape: Couldn't write a filemark\n");
return -EIO;
}
@@ -1694,8 +1256,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
struct ide_atapi_pc pc;
int i, retval;
- debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n",
- mt_op, mt_count);
+ ide_debug_log(IDE_DBG_FUNC, "MTIOCTOP ioctl: mt_op: %d, mt_count: %d",
+ mt_op, mt_count);
switch (mt_op) {
case MTFSF:
@@ -1741,7 +1303,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
ide_tape_discard_merge_buffer(drive, 0);
retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK);
if (!retval)
- clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags);
+ clear_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT),
+ &drive->atapi_flags);
return retval;
case MTNOP:
ide_tape_discard_merge_buffer(drive, 0);
@@ -1752,20 +1315,22 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK);
case MTEOM:
idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD);
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
case MTERASE:
(void)idetape_rewind_tape(drive);
idetape_create_erase_cmd(&pc);
- return ide_queue_pc_tail(drive, disk, &pc);
+ return ide_queue_pc_tail(drive, disk, &pc, NULL, 0);
case MTSETBLK:
if (mt_count) {
if (mt_count < tape->blk_size ||
mt_count % tape->blk_size)
return -EIO;
tape->user_bs_factor = mt_count / tape->blk_size;
- clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
+ clear_bit(ilog2(IDE_AFLAG_DETECT_BS),
+ &drive->atapi_flags);
} else
- set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags);
+ set_bit(ilog2(IDE_AFLAG_DETECT_BS),
+ &drive->atapi_flags);
return 0;
case MTSEEK:
ide_tape_discard_merge_buffer(drive, 0);
@@ -1800,7 +1365,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
* supported here, and not in the corresponding block interface. Our own
* ide-tape ioctls are supported on both interfaces.
*/
-static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
+static long do_idetape_chrdev_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
struct ide_tape_obj *tape = file->private_data;
@@ -1811,16 +1376,16 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
int block_offset = 0, position = tape->first_frame;
void __user *argp = (void __user *)arg;
- debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd);
+ ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x", cmd);
if (tape->chrdev_dir == IDETAPE_DIR_WRITE) {
ide_tape_flush_merge_buffer(drive);
idetape_flush_tape_buffers(drive);
}
if (cmd == MTIOCGET || cmd == MTIOCPOS) {
- block_offset = tape->merge_bh_size /
+ block_offset = tape->valid /
(tape->blk_size * tape->user_bs_factor);
- position = idetape_read_position(drive);
+ position = ide_tape_read_position(drive);
if (position < 0)
return -EIO;
}
@@ -1855,6 +1420,16 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
}
}
+static long idetape_chrdev_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ long ret;
+ mutex_lock(&ide_tape_mutex);
+ ret = do_idetape_chrdev_ioctl(file, cmd, arg);
+ mutex_unlock(&ide_tape_mutex);
+ return ret;
+}
+
/*
* Do a mode sense page 0 with block descriptor and if it succeeds set the tape
* block size with the reported value.
@@ -1863,9 +1438,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
+ u8 buf[12];
idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR);
- if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) {
printk(KERN_ERR "ide-tape: Can't get block descriptor\n");
if (tape->blk_size == 0) {
printk(KERN_WARNING "ide-tape: Cannot deal with zero "
@@ -1874,10 +1450,13 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive)
}
return;
}
- tape->blk_size = (pc.buf[4 + 5] << 16) +
- (pc.buf[4 + 6] << 8) +
- pc.buf[4 + 7];
- tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7;
+ tape->blk_size = (buf[4 + 5] << 16) +
+ (buf[4 + 6] << 8) +
+ buf[4 + 7];
+ tape->drv_write_prot = (buf[2] & 0x80) >> 7;
+
+ ide_debug_log(IDE_DBG_FUNC, "blk_size: %d, write_prot: %d",
+ tape->blk_size, tape->drv_write_prot);
}
static int idetape_chrdev_open(struct inode *inode, struct file *filp)
@@ -1890,14 +1469,18 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
if (i >= MAX_HWIFS * MAX_DRIVES)
return -ENXIO;
- lock_kernel();
- tape = ide_tape_chrdev_get(i);
+ mutex_lock(&idetape_chrdev_mutex);
+
+ tape = ide_tape_get(NULL, true, i);
if (!tape) {
- unlock_kernel();
+ mutex_unlock(&idetape_chrdev_mutex);
return -ENXIO;
}
- debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
+ drive = tape->drive;
+ filp->private_data = tape;
+
+ ide_debug_log(IDE_DBG_FUNC, "enter");
/*
* We really want to do nonseekable_open(inode, filp); here, but some
@@ -1906,24 +1489,21 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
*/
filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
- drive = tape->drive;
-
- filp->private_data = tape;
- if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) {
+ if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) {
retval = -EBUSY;
goto out_put_tape;
}
retval = idetape_wait_ready(drive, 60 * HZ);
if (retval) {
- clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
+ clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags);
printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
goto out_put_tape;
}
- idetape_read_position(drive);
- if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags))
+ ide_tape_read_position(drive);
+ if (!test_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), &drive->atapi_flags))
(void)idetape_rewind_tape(drive);
/* Read block size and write protect status from drive. */
@@ -1939,7 +1519,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
if (tape->write_prot) {
if ((filp->f_flags & O_ACCMODE) == O_WRONLY ||
(filp->f_flags & O_ACCMODE) == O_RDWR) {
- clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
+ clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags);
retval = -EROFS;
goto out_put_tape;
}
@@ -1952,12 +1532,15 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
tape->door_locked = DOOR_LOCKED;
}
}
- unlock_kernel();
+ mutex_unlock(&idetape_chrdev_mutex);
+
return 0;
out_put_tape:
ide_tape_put(tape);
- unlock_kernel();
+
+ mutex_unlock(&idetape_chrdev_mutex);
+
return retval;
}
@@ -1966,12 +1549,12 @@ static void idetape_write_release(ide_drive_t *drive, unsigned int minor)
idetape_tape_t *tape = drive->driver_data;
ide_tape_flush_merge_buffer(drive);
- tape->merge_bh = ide_tape_kmalloc_buffer(tape, 1, 0);
- if (tape->merge_bh != NULL) {
+ tape->buf = kmalloc(tape->buffer_size, GFP_KERNEL);
+ if (tape->buf != NULL) {
idetape_pad_zeros(drive, tape->blk_size *
(tape->user_bs_factor - 1));
- ide_tape_kfree_buffer(tape);
- tape->merge_bh = NULL;
+ kfree(tape->buf);
+ tape->buf = NULL;
}
idetape_write_filemark(drive);
idetape_flush_tape_buffers(drive);
@@ -1984,10 +1567,11 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
ide_drive_t *drive = tape->drive;
unsigned int minor = iminor(inode);
- lock_kernel();
+ mutex_lock(&idetape_chrdev_mutex);
+
tape = drive->driver_data;
- debug_log(DBG_CHRDEV, "Enter %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (tape->chrdev_dir == IDETAPE_DIR_WRITE)
idetape_write_release(drive, minor);
@@ -1996,17 +1580,21 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
ide_tape_discard_merge_buffer(drive, 1);
}
- if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags))
+ if (minor < 128 && test_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT),
+ &drive->atapi_flags))
(void) idetape_rewind_tape(drive);
+
if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
if (tape->door_locked == DOOR_LOCKED) {
if (!ide_set_media_lock(drive, tape->disk, 0))
tape->door_locked = DOOR_UNLOCKED;
}
}
- clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags);
+ clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags);
ide_tape_put(tape);
- unlock_kernel();
+
+ mutex_unlock(&idetape_chrdev_mutex);
+
return 0;
}
@@ -2018,17 +1606,14 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
char fw_rev[4], vendor_id[8], product_id[16];
idetape_create_inquiry_cmd(&pc);
- pc.buf = &pc_buf[0];
- pc.buf_size = sizeof(pc_buf);
-
- if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc, pc_buf, pc.req_xfer)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
return;
}
- memcpy(vendor_id, &pc.buf[8], 8);
- memcpy(product_id, &pc.buf[16], 16);
- memcpy(fw_rev, &pc.buf[32], 4);
+ memcpy(vendor_id, &pc_buf[8], 8);
+ memcpy(product_id, &pc_buf[16], 16);
+ memcpy(fw_rev, &pc_buf[32], 4);
ide_fixstring(vendor_id, 8, 0);
ide_fixstring(product_id, 16, 0);
@@ -2046,11 +1631,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
- u8 *caps;
+ u8 buf[24], *caps;
u8 speed, max_speed;
idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE);
- if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
+ if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) {
printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming"
" some default values\n");
tape->blk_size = 512;
@@ -2059,7 +1644,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
put_unaligned(6*52, (u16 *)&tape->caps[16]);
return;
}
- caps = pc.buf + 4 + pc.buf[3];
+ caps = buf + 4 + buf[3];
/* convert to host order and save for later use */
speed = be16_to_cpup((__be16 *)&caps[14]);
@@ -2125,7 +1710,6 @@ static int divf_buffer_size(ide_drive_t *drive) { return 1024; }
ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP);
-ide_tape_devset_rw_field(debug_mask, debug_mask);
ide_tape_devset_rw_field(tdsc, best_dsc_rw_freq);
ide_tape_devset_r_field(avg_speed, avg_speed);
@@ -2137,7 +1721,6 @@ static const struct ide_proc_devset idetape_settings[] = {
__IDE_PROC_DEVSET(avg_speed, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(buffer, 0, 0xffff, NULL, divf_buffer),
__IDE_PROC_DEVSET(buffer_size, 0, 0xffff, NULL, divf_buffer_size),
- __IDE_PROC_DEVSET(debug_mask, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(dsc_overlap, 0, 1, NULL, NULL),
__IDE_PROC_DEVSET(speed, 0, 0xffff, NULL, NULL),
__IDE_PROC_DEVSET(tdsc, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX,
@@ -2164,9 +1747,9 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
int buffer_size;
u16 *ctl = (u16 *)&tape->caps[12];
- drive->pc_callback = ide_tape_callback;
- drive->pc_update_buffers = idetape_update_buffers;
- drive->pc_io_buffers = ide_tape_io_buffers;
+ ide_debug_log(IDE_DBG_FUNC, "minor: %d", minor);
+
+ drive->pc_callback = ide_tape_callback;
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
@@ -2197,11 +1780,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
tape->buffer_size = *ctl * tape->blk_size;
}
buffer_size = tape->buffer_size;
- tape->pages_per_buffer = buffer_size / PAGE_SIZE;
- if (buffer_size % PAGE_SIZE) {
- tape->pages_per_buffer++;
- tape->excess_bh_size = PAGE_SIZE - buffer_size % PAGE_SIZE;
- }
/* select the "best" DSC read/write polling freq */
speed = max(*(u16 *)&tape->caps[14], *(u16 *)&tape->caps[8]);
@@ -2244,7 +1822,7 @@ static void ide_tape_release(struct device *dev)
ide_drive_t *drive = tape->drive;
struct gendisk *g = tape->disk;
- BUG_ON(tape->merge_bh_size);
+ BUG_ON(tape->valid);
drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP;
drive->driver_data = NULL;
@@ -2258,22 +1836,32 @@ static void ide_tape_release(struct device *dev)
}
#ifdef CONFIG_IDE_PROC_FS
-static int proc_idetape_read_name
- (char *page, char **start, off_t off, int count, int *eof, void *data)
+static int idetape_name_proc_show(struct seq_file *m, void *v)
{
- ide_drive_t *drive = (ide_drive_t *) data;
+ ide_drive_t *drive = (ide_drive_t *) m->private;
idetape_tape_t *tape = drive->driver_data;
- char *out = page;
- int len;
- len = sprintf(out, "%s\n", tape->name);
- PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
+ seq_printf(m, "%s\n", tape->name);
+ return 0;
+}
+
+static int idetape_name_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, idetape_name_proc_show, PDE_DATA(inode));
}
+static const struct file_operations idetape_name_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = idetape_name_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static ide_proc_entry_t idetape_proc[] = {
- { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
- { "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL },
- { NULL, 0, NULL, NULL }
+ { "capacity", S_IFREG|S_IRUGO, &ide_capacity_proc_fops },
+ { "name", S_IFREG|S_IRUGO, &idetape_name_proc_fops },
+ {}
};
static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive)
@@ -2310,14 +1898,19 @@ static const struct file_operations idetape_fops = {
.owner = THIS_MODULE,
.read = idetape_chrdev_read,
.write = idetape_chrdev_write,
- .ioctl = idetape_chrdev_ioctl,
+ .unlocked_ioctl = idetape_chrdev_ioctl,
.open = idetape_chrdev_open,
.release = idetape_chrdev_release,
+ .llseek = noop_llseek,
};
static int idetape_open(struct block_device *bdev, fmode_t mode)
{
- struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk);
+ struct ide_tape_obj *tape;
+
+ mutex_lock(&ide_tape_mutex);
+ tape = ide_tape_get(bdev->bd_disk, false, 0);
+ mutex_unlock(&ide_tape_mutex);
if (!tape)
return -ENXIO;
@@ -2325,12 +1918,13 @@ static int idetape_open(struct block_device *bdev, fmode_t mode)
return 0;
}
-static int idetape_release(struct gendisk *disk, fmode_t mode)
+static void idetape_release(struct gendisk *disk, fmode_t mode)
{
struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj);
+ mutex_lock(&ide_tape_mutex);
ide_tape_put(tape);
- return 0;
+ mutex_unlock(&ide_tape_mutex);
}
static int idetape_ioctl(struct block_device *bdev, fmode_t mode,
@@ -2338,17 +1932,22 @@ static int idetape_ioctl(struct block_device *bdev, fmode_t mode,
{
struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj);
ide_drive_t *drive = tape->drive;
- int err = generic_ide_ioctl(drive, bdev, cmd, arg);
+ int err;
+
+ mutex_lock(&ide_tape_mutex);
+ err = generic_ide_ioctl(drive, bdev, cmd, arg);
if (err == -EINVAL)
err = idetape_blkdev_ioctl(drive, cmd, arg);
+ mutex_unlock(&ide_tape_mutex);
+
return err;
}
-static struct block_device_operations idetape_block_ops = {
+static const struct block_device_operations idetape_block_ops = {
.owner = THIS_MODULE,
.open = idetape_open,
.release = idetape_release,
- .locked_ioctl = idetape_ioctl,
+ .ioctl = idetape_ioctl,
};
static int ide_tape_probe(ide_drive_t *drive)
@@ -2357,7 +1956,9 @@ static int ide_tape_probe(ide_drive_t *drive)
struct gendisk *g;
int minor;
- if (!strstr("ide-tape", drive->driver_req))
+ ide_debug_log(IDE_DBG_FUNC, "enter");
+
+ if (!strstr(DRV_NAME, drive->driver_req))
goto failed;
if (drive->media != ide_tape)
@@ -2384,7 +1985,7 @@ static int ide_tape_probe(ide_drive_t *drive)
tape->dev.parent = &drive->gendev;
tape->dev.release = ide_tape_release;
- dev_set_name(&tape->dev, dev_name(&drive->gendev));
+ dev_set_name(&tape->dev, "%s", dev_name(&drive->gendev));
if (device_register(&tape->dev))
goto out_free_disk;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 4aa6223c11b..dabb88b1cbe 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -11,6 +11,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
@@ -19,8 +20,8 @@
#include <linux/hdreg.h>
#include <linux/ide.h>
#include <linux/scatterlist.h>
+#include <linux/uaccess.h>
-#include <asm/uaccess.h>
#include <asm/io.h>
void ide_tf_readback(ide_drive_t *drive, struct ide_cmd *cmd)
@@ -53,7 +54,7 @@ void ide_tf_dump(const char *s, struct ide_cmd *cmd)
#endif
}
-int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
+int taskfile_lib_get_identify(ide_drive_t *drive, u8 *buf)
{
struct ide_cmd cmd;
@@ -86,7 +87,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
if (orig_cmd->protocol == ATA_PROT_PIO &&
(orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
drive->mult_count == 0) {
- printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+ pr_err("%s: multimode not set!\n", drive->name);
return ide_stopped;
}
@@ -98,7 +99,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, cmd);
tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
- SELECT_MASK(drive, 0);
if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
u8 data[2] = { cmd->tf.data, cmd->hob.data };
@@ -166,7 +166,7 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
if (custom && tf->command == ATA_CMD_SET_MULTI) {
drive->mult_req = drive->mult_count = 0;
- drive->special.b.recalibrate = 1;
+ drive->special_flags |= IDE_SFLAG_RECALIBRATE;
(void)ide_dump_status(drive, __func__, stat);
return ide_stopped;
} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
@@ -202,7 +202,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
u8 stat;
/*
- * Last sector was transfered, wait until device is ready. This can
+ * Last sector was transferred, wait until device is ready. This can
* take up to 6 ms on some ATAPI devices, so we will wait max 10 ms.
*/
for (retries = 0; retries < 1000; retries++) {
@@ -215,7 +215,7 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
}
if (stat & ATA_BUSY)
- printk(KERN_ERR "%s: drive still BUSY!\n", drive->name);
+ pr_err("%s: drive still BUSY!\n", drive->name);
return stat;
}
@@ -226,8 +226,8 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
struct scatterlist *cursg = cmd->cursg;
+ unsigned long uninitialized_var(flags);
struct page *page;
- unsigned long flags;
unsigned int offset;
u8 *buf;
@@ -237,9 +237,7 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
while (len) {
unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
-
- if (nr_bytes > PAGE_SIZE)
- nr_bytes = PAGE_SIZE;
+ int page_is_high;
page = sg_page(cursg);
offset = cursg->offset + cmd->cursg_ofs;
@@ -248,10 +246,13 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
page = nth_page(page, (offset >> PAGE_SHIFT));
offset %= PAGE_SIZE;
- if (PageHighMem(page))
+ nr_bytes = min_t(unsigned, nr_bytes, (PAGE_SIZE - offset));
+
+ page_is_high = PageHighMem(page);
+ if (page_is_high)
local_irq_save(flags);
- buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+ buf = kmap_atomic(page) + offset;
cmd->nleft -= nr_bytes;
cmd->cursg_ofs += nr_bytes;
@@ -267,9 +268,9 @@ void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
else
hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
- kunmap_atomic(buf, KM_BIO_SRC_IRQ);
+ kunmap_atomic(buf);
- if (PageHighMem(page))
+ if (page_is_high)
local_irq_restore(flags);
len -= nr_bytes;
@@ -323,10 +324,17 @@ static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
{
struct request *rq = drive->hwif->rq;
- u8 err = ide_read_error(drive);
+ u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
+ u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
ide_complete_cmd(drive, cmd, stat, err);
rq->errors = err;
+
+ if (err == 0 && set_xfer) {
+ ide_set_xfer_rate(drive, nsect);
+ ide_driveid_update(drive);
+ }
+
ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
}
@@ -385,7 +393,7 @@ out_end:
if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
ide_finish_cmd(drive, cmd, stat);
else
- ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9);
+ ide_complete_rq(drive, 0, blk_rq_sectors(cmd->rq) << 9);
return ide_stopped;
out_err:
ide_error_cmd(drive, cmd);
@@ -399,8 +407,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
if (ide_wait_stat(&startstop, drive, ATA_DRQ,
drive->bad_wstat, WAIT_DRQ)) {
- printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
- drive->name,
+ pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name,
(cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
return startstop;
@@ -421,10 +428,10 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
{
struct request *rq;
int error;
+ int rw = !(cmd->tf_flags & IDE_TFLAG_WRITE) ? READ : WRITE;
- rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
+ rq = blk_get_request(drive->queue, rw, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
- rq->buffer = buf;
/*
* (ks) We transfer currently only whole sectors.
@@ -432,21 +439,22 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
* if we would find a solution to transfer any size.
* To support special commands like READ LONG.
*/
- rq->hard_nr_sectors = rq->nr_sectors = nsect;
- rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
-
- if (cmd->tf_flags & IDE_TFLAG_WRITE)
- rq->cmd_flags |= REQ_RW;
+ if (nsect) {
+ error = blk_rq_map_kern(drive->queue, rq, buf,
+ nsect * SECTOR_SIZE, __GFP_WAIT);
+ if (error)
+ goto put_req;
+ }
rq->special = cmd;
cmd->rq = rq;
error = blk_execute_rq(drive->queue, NULL, rq, 0);
- blk_put_request(rq);
+put_req:
+ blk_put_request(rq);
return error;
}
-
EXPORT_SYMBOL(ide_raw_taskfile);
int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
@@ -472,18 +480,13 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
u16 nsect = 0;
char __user *buf = (char __user *)arg;
-// printk("IDE Taskfile ...\n");
-
- req_task = kzalloc(tasksize, GFP_KERNEL);
- if (req_task == NULL) return -ENOMEM;
- if (copy_from_user(req_task, buf, tasksize)) {
- kfree(req_task);
- return -EFAULT;
- }
+ req_task = memdup_user(buf, tasksize);
+ if (IS_ERR(req_task))
+ return PTR_ERR(req_task);
taskout = req_task->out_size;
taskin = req_task->in_size;
-
+
if (taskin > 65536 || taskout > 65536) {
err = -EINVAL;
goto abort;
@@ -573,51 +576,49 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
cmd.protocol = ATA_PROT_DMA;
switch (req_task->data_phase) {
- case TASKFILE_MULTI_OUT:
- if (!drive->mult_count) {
- /* (hs): give up if multcount is not set */
- printk(KERN_ERR "%s: %s Multimode Write " \
- "multcount is not set\n",
- drive->name, __func__);
- err = -EPERM;
- goto abort;
- }
- cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
- /* fall through */
- case TASKFILE_OUT:
- cmd.protocol = ATA_PROT_PIO;
- /* fall through */
- case TASKFILE_OUT_DMAQ:
- case TASKFILE_OUT_DMA:
- cmd.tf_flags |= IDE_TFLAG_WRITE;
- nsect = taskout / SECTOR_SIZE;
- data_buf = outbuf;
- break;
- case TASKFILE_MULTI_IN:
- if (!drive->mult_count) {
- /* (hs): give up if multcount is not set */
- printk(KERN_ERR "%s: %s Multimode Read failure " \
- "multcount is not set\n",
- drive->name, __func__);
- err = -EPERM;
- goto abort;
- }
- cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
- /* fall through */
- case TASKFILE_IN:
- cmd.protocol = ATA_PROT_PIO;
- /* fall through */
- case TASKFILE_IN_DMAQ:
- case TASKFILE_IN_DMA:
- nsect = taskin / SECTOR_SIZE;
- data_buf = inbuf;
- break;
- case TASKFILE_NO_DATA:
- cmd.protocol = ATA_PROT_NODATA;
- break;
- default:
- err = -EFAULT;
+ case TASKFILE_MULTI_OUT:
+ if (!drive->mult_count) {
+ /* (hs): give up if multcount is not set */
+ pr_err("%s: %s Multimode Write multcount is not set\n",
+ drive->name, __func__);
+ err = -EPERM;
goto abort;
+ }
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
+ /* fall through */
+ case TASKFILE_OUT:
+ cmd.protocol = ATA_PROT_PIO;
+ /* fall through */
+ case TASKFILE_OUT_DMAQ:
+ case TASKFILE_OUT_DMA:
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+ nsect = taskout / SECTOR_SIZE;
+ data_buf = outbuf;
+ break;
+ case TASKFILE_MULTI_IN:
+ if (!drive->mult_count) {
+ /* (hs): give up if multcount is not set */
+ pr_err("%s: %s Multimode Read multcount is not set\n",
+ drive->name, __func__);
+ err = -EPERM;
+ goto abort;
+ }
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
+ /* fall through */
+ case TASKFILE_IN:
+ cmd.protocol = ATA_PROT_PIO;
+ /* fall through */
+ case TASKFILE_IN_DMAQ:
+ case TASKFILE_IN_DMA:
+ nsect = taskin / SECTOR_SIZE;
+ data_buf = inbuf;
+ break;
+ case TASKFILE_NO_DATA:
+ cmd.protocol = ATA_PROT_NODATA;
+ break;
+ default:
+ err = -EFAULT;
+ goto abort;
}
if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
@@ -626,7 +627,7 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
nsect = (cmd.hob.nsect << 8) | cmd.tf.nsect;
if (!nsect) {
- printk(KERN_ERR "%s: in/out command without data\n",
+ pr_err("%s: in/out command without data\n",
drive->name);
err = -EFAULT;
goto abort;
@@ -668,8 +669,6 @@ abort:
kfree(outbuf);
kfree(inbuf);
-// printk("IDE Taskfile ioctl ended. rc = %i\n", err);
-
return err;
}
#endif
diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c
index 001a56365be..0e05f75934c 100644
--- a/drivers/ide/ide-timings.c
+++ b/drivers/ide/ide-timings.c
@@ -166,12 +166,13 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
if (id[ATA_ID_FIELD_VALID] & 2) { /* EIDE drive */
memset(&p, 0, sizeof(p));
- if (speed <= XFER_PIO_2)
- p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
- else if ((speed <= XFER_PIO_4) ||
- (speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
- p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
- else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
+ if (speed >= XFER_PIO_0 && speed < XFER_SW_DMA_0) {
+ if (speed <= XFER_PIO_2)
+ p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
+ else if ((speed <= XFER_PIO_4) ||
+ (speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
+ p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
+ } else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
p.cycle = id[ATA_ID_EIDE_DMA_MIN];
ide_timing_merge(&p, t, t, IDE_TIMING_CYCLE | IDE_TIMING_CYC8B);
@@ -185,11 +186,10 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
/*
* Even in DMA/UDMA modes we still use PIO access for IDENTIFY,
* S.M.A.R.T and some other commands. We have to ensure that the
- * DMA cycle timing is slower/equal than the fastest PIO timing.
+ * DMA cycle timing is slower/equal than the current PIO timing.
*/
if (speed >= XFER_SW_DMA_0) {
- u8 pio = ide_get_best_pio_mode(drive, 255, 5);
- ide_timing_compute(drive, XFER_PIO_0 + pio, &p, T, UT);
+ ide_timing_compute(drive, drive->pio_mode, &p, T, UT);
ide_timing_merge(&p, t, t, IDE_TIMING_ALL);
}
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
index af44be9d546..eb421883c16 100644
--- a/drivers/ide/ide-xfer-mode.c
+++ b/drivers/ide/ide-xfer-mode.c
@@ -1,6 +1,7 @@
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/interrupt.h>
#include <linux/ide.h>
#include <linux/bitops.h>
@@ -58,7 +59,7 @@ EXPORT_SYMBOL(ide_xfer_verbose);
* This is used by most chipset support modules when "auto-tuning".
*/
-u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
+static u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
{
u16 *id = drive->id;
int pio_mode = -1, overridden = 0;
@@ -105,7 +106,18 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
return pio_mode;
}
-EXPORT_SYMBOL_GPL(ide_get_best_pio_mode);
+
+int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio)
+{
+ /*
+ * IORDY may lead to controller lock up on certain controllers
+ * if the port is not occupied.
+ */
+ if (pio == 0 && (drive->hwif->port_flags & IDE_PFLAG_PROBING))
+ return 0;
+ return ata_id_pio_need_iordy(drive->id, pio);
+}
+EXPORT_SYMBOL_GPL(ide_pio_need_iordy);
int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
{
@@ -123,17 +135,20 @@ int ide_set_pio_mode(ide_drive_t *drive, const u8 mode)
* set transfer mode on the device in ->set_pio_mode method...
*/
if (port_ops->set_dma_mode == NULL) {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ drive->pio_mode = mode;
+ port_ops->set_pio_mode(hwif, drive);
return 0;
}
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ drive->pio_mode = mode;
+ port_ops->set_pio_mode(hwif, drive);
return 0;
} else {
- port_ops->set_pio_mode(drive, mode - XFER_PIO_0);
+ drive->pio_mode = mode;
+ port_ops->set_pio_mode(hwif, drive);
return ide_config_drive_speed(drive, mode);
}
}
@@ -152,10 +167,12 @@ int ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) {
if (ide_config_drive_speed(drive, mode))
return -1;
- port_ops->set_dma_mode(drive, mode);
+ drive->dma_mode = mode;
+ port_ops->set_dma_mode(hwif, drive);
return 0;
} else {
- port_ops->set_dma_mode(drive, mode);
+ drive->dma_mode = mode;
+ port_ops->set_dma_mode(hwif, drive);
return ide_config_drive_speed(drive, mode);
}
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 92c9b90931e..2ce6268a273 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -52,7 +52,6 @@
#include <linux/major.h>
#include <linux/errno.h>
#include <linux/genhd.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ide.h>
@@ -159,7 +158,7 @@ struct bus_type ide_bus_type = {
.probe = generic_ide_probe,
.remove = generic_ide_remove,
.shutdown = generic_ide_shutdown,
- .dev_attrs = ide_dev_attrs,
+ .dev_groups = ide_dev_groups,
.suspend = generic_ide_suspend,
.resume = generic_ide_resume,
};
@@ -178,7 +177,7 @@ EXPORT_SYMBOL_GPL(ide_pci_clk);
module_param_named(pci_clock, ide_pci_clk, int, 0);
MODULE_PARM_DESC(pci_clock, "PCI bus clock frequency (in MHz)");
-static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
+static int ide_set_dev_param_mask(const char *s, const struct kernel_param *kp)
{
int a, b, i, j = 1;
unsigned int *dev_param_mask = (unsigned int *)kp->arg;
@@ -201,29 +200,40 @@ static int ide_set_dev_param_mask(const char *s, struct kernel_param *kp)
return 0;
}
+static struct kernel_param_ops param_ops_ide_dev_mask = {
+ .set = ide_set_dev_param_mask
+};
+
+#define param_check_ide_dev_mask(name, p) param_check_uint(name, p)
+
static unsigned int ide_nodma;
-module_param_call(nodma, ide_set_dev_param_mask, NULL, &ide_nodma, 0);
+module_param_named(nodma, ide_nodma, ide_dev_mask, 0);
MODULE_PARM_DESC(nodma, "disallow DMA for a device");
static unsigned int ide_noflush;
-module_param_call(noflush, ide_set_dev_param_mask, NULL, &ide_noflush, 0);
+module_param_named(noflush, ide_noflush, ide_dev_mask, 0);
MODULE_PARM_DESC(noflush, "disable flush requests for a device");
+static unsigned int ide_nohpa;
+
+module_param_named(nohpa, ide_nohpa, ide_dev_mask, 0);
+MODULE_PARM_DESC(nohpa, "disable Host Protected Area for a device");
+
static unsigned int ide_noprobe;
-module_param_call(noprobe, ide_set_dev_param_mask, NULL, &ide_noprobe, 0);
+module_param_named(noprobe, ide_noprobe, ide_dev_mask, 0);
MODULE_PARM_DESC(noprobe, "skip probing for a device");
static unsigned int ide_nowerr;
-module_param_call(nowerr, ide_set_dev_param_mask, NULL, &ide_nowerr, 0);
+module_param_named(nowerr, ide_nowerr, ide_dev_mask, 0);
MODULE_PARM_DESC(nowerr, "ignore the ATA_DF bit for a device");
static unsigned int ide_cdroms;
-module_param_call(cdrom, ide_set_dev_param_mask, NULL, &ide_cdroms, 0);
+module_param_named(cdrom, ide_cdroms, ide_dev_mask, 0);
MODULE_PARM_DESC(cdrom, "force device as a CD-ROM");
struct chs_geom {
@@ -281,6 +291,11 @@ static void ide_dev_apply_params(ide_drive_t *drive, u8 unit)
drive->name);
drive->dev_flags |= IDE_DFLAG_NOFLUSH;
}
+ if (ide_nohpa & (1 << i)) {
+ printk(KERN_INFO "ide: disabling Host Protected Area for %s\n",
+ drive->name);
+ drive->dev_flags |= IDE_DFLAG_NOHPA;
+ }
if (ide_noprobe & (1 << i)) {
printk(KERN_INFO "ide: skipping probe for %s\n", drive->name);
drive->dev_flags |= IDE_DFLAG_NOPROBE;
diff --git a/drivers/ide/ide_platform.c b/drivers/ide/ide_platform.c
index 051b4ab0f35..a8b4b6af80e 100644
--- a/drivers/ide/ide_platform.c
+++ b/drivers/ide/ide_platform.c
@@ -19,13 +19,12 @@
#include <linux/module.h>
#include <linux/ata_platform.h>
#include <linux/platform_device.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
-static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
- void __iomem *base,
- void __iomem *ctrl,
- struct pata_platform_info *pdata,
- int irq)
+static void plat_ide_setup_ports(struct ide_hw *hw, void __iomem *base,
+ void __iomem *ctrl,
+ struct pata_platform_info *pdata, int irq)
{
unsigned long port = (unsigned long)base;
int i;
@@ -40,25 +39,24 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw,
hw->io_ports.ctl_addr = (unsigned long)ctrl;
hw->irq = irq;
-
- hw->chipset = ide_generic;
}
static const struct ide_port_info platform_ide_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
+ .chipset = ide_generic,
};
-static int __devinit plat_ide_probe(struct platform_device *pdev)
+static int plat_ide_probe(struct platform_device *pdev)
{
struct resource *res_base, *res_alt, *res_irq;
void __iomem *base, *alt_base;
struct pata_platform_info *pdata;
struct ide_host *host;
int ret = 0, mmio = 0;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
struct ide_port_info d = platform_ide_port_info;
- pdata = pdev->dev.platform_data;
+ pdata = dev_get_platdata(&pdev->dev);
/* get a pointer to the register memory */
res_base = platform_get_resource(pdev, IORESOURCE_IO, 0);
@@ -82,24 +80,28 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
if (mmio) {
base = devm_ioremap(&pdev->dev,
- res_base->start, res_base->end - res_base->start + 1);
+ res_base->start, resource_size(res_base));
alt_base = devm_ioremap(&pdev->dev,
- res_alt->start, res_alt->end - res_alt->start + 1);
+ res_alt->start, resource_size(res_alt));
} else {
base = devm_ioport_map(&pdev->dev,
- res_base->start, res_base->end - res_base->start + 1);
+ res_base->start, resource_size(res_base));
alt_base = devm_ioport_map(&pdev->dev,
- res_alt->start, res_alt->end - res_alt->start + 1);
+ res_alt->start, resource_size(res_alt));
}
memset(&hw, 0, sizeof(hw));
plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start);
hw.dev = &pdev->dev;
+ d.irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
+ if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE)
+ d.irq_flags |= IRQF_SHARED;
+
if (mmio)
d.host_flags |= IDE_HFLAG_MMIO;
- ret = ide_host_add(&d, hws, &host);
+ ret = ide_host_add(&d, hws, 1, &host);
if (ret)
goto out;
@@ -111,9 +113,9 @@ out:
return ret;
}
-static int __devexit plat_ide_remove(struct platform_device *pdev)
+static int plat_ide_remove(struct platform_device *pdev)
{
- struct ide_host *host = pdev->dev.driver_data;
+ struct ide_host *host = dev_get_drvdata(&pdev->dev);
ide_host_remove(host);
@@ -126,7 +128,7 @@ static struct platform_driver platform_ide_driver = {
.owner = THIS_MODULE,
},
.probe = plat_ide_probe,
- .remove = __devexit_p(plat_ide_remove),
+ .remove = plat_ide_remove,
};
static int __init platform_ide_init(void)
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
index e021078cd06..b6f674ab4fb 100644
--- a/drivers/ide/it8172.c
+++ b/drivers/ide/it8172.c
@@ -37,12 +37,12 @@
#define DRV_NAME "IT8172"
-static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void it8172_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u16 drive_enables;
u32 drive_timing;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* The highest value of DIOR/DIOW pulse width and recovery time
@@ -66,7 +66,7 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
if (drive->media == ide_disk)
/* enable prefetch */
drive_enables |= 0x0004 << (drive->dn * 4);
- if (ata_id_has_iordy(drive->id))
+ if (ide_pio_need_iordy(drive, pio))
/* enable IORDY sample-point */
drive_enables |= 0x0002 << (drive->dn * 4);
@@ -77,14 +77,14 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_dword(dev, 0x44, drive_timing);
}
-static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void it8172_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int a_speed = 3 << (drive->dn * 4);
int u_flag = 1 << drive->dn;
int u_speed = 0;
u8 reg48, reg4a;
+ const u8 speed = drive->dma_mode;
pci_read_config_byte(dev, 0x48, &reg48);
pci_read_config_byte(dev, 0x4a, &reg4a);
@@ -98,14 +98,14 @@ static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
- u8 pio;
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
- pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ drive->pio_mode =
+ mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
- it8172_set_pio_mode(drive, pio);
+ it8172_set_pio_mode(hwif, drive);
}
}
@@ -115,7 +115,7 @@ static const struct ide_port_ops it8172_port_ops = {
.set_dma_mode = it8172_set_dma_mode,
};
-static const struct ide_port_info it8172_port_info __devinitdata = {
+static const struct ide_port_info it8172_port_info = {
.name = DRV_NAME,
.port_ops = &it8172_port_ops,
.enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} },
@@ -125,8 +125,7 @@ static const struct ide_port_info it8172_port_info __devinitdata = {
.udma_mask = ATA_UDMA2,
};
-static int __devinit it8172_init_one(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int it8172_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
return -ENODEV; /* IT8172 is more than an IDE controller */
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c
index d7969b6d139..6b92846682f 100644
--- a/drivers/ide/it8213.c
+++ b/drivers/ide/it8213.c
@@ -17,15 +17,14 @@
/**
* it8213_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Set the interface PIO mode.
*/
-static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void it8213_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = 0x40;
@@ -35,6 +34,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
static const u8 timings[][2] = {
{ 0, 0 },
@@ -50,7 +50,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
control |= 1; /* Programmable timing on */
if (drive->media != ide_disk)
control |= 4; /* ATAPI */
- if (pio > 2)
+ if (ide_pio_need_iordy(drive, pio))
control |= 2; /* IORDY */
if (is_slave) {
master_data |= 0x4000;
@@ -74,15 +74,14 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* it8213_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Tune the ITE chipset for the DMA mode.
*/
-static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void it8213_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 maslave = 0x40;
int a_speed = 3 << (drive->dn * 4);
@@ -92,6 +91,7 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
int u_speed = 0;
u16 reg4042, reg4a;
u8 reg48, reg54, reg55;
+ const u8 speed = drive->dma_mode;
pci_read_config_word(dev, maslave, &reg4042);
pci_read_config_byte(dev, 0x48, &reg48);
@@ -120,7 +120,6 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
- u8 pio;
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
@@ -132,11 +131,12 @@ static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
if (speed >= XFER_MW_DMA_0)
- pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ drive->pio_mode =
+ mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
else
- pio = 2; /* only SWDMA2 is allowed */
+ drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
- it8213_set_pio_mode(drive, pio);
+ it8213_set_pio_mode(hwif, drive);
}
}
@@ -156,7 +156,7 @@ static const struct ide_port_ops it8213_port_ops = {
.cable_detect = it8213_cable_detect,
};
-static const struct ide_port_info it8213_chipset __devinitdata = {
+static const struct ide_port_info it8213_chipset = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80} },
.port_ops = &it8213_port_ops,
@@ -177,7 +177,7 @@ static const struct ide_port_info it8213_chipset __devinitdata = {
* standard helper functions to do almost all the work for us.
*/
-static int __devinit it8213_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int it8213_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &it8213_chipset, NULL);
}
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index 51aa745246d..f01ba4606be 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -61,6 +61,7 @@
#include <linux/types.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
@@ -228,18 +229,18 @@ static void it821x_clock_strategy(ide_drive_t *drive)
/**
* it821x_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Tune the host to the desired PIO mode taking into the consideration
* the maximum PIO mode supported by the other device on the cable.
*/
-static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void it821x_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct it821x_dev *itdev = ide_get_hwifdata(hwif);
ide_drive_t *pair = ide_get_pair_dev(drive);
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 unit = drive->dn & 1, set_pio = pio;
/* Spec says 89 ref driver uses 88 */
@@ -252,7 +253,7 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
* on the cable.
*/
if (pair) {
- u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
+ u8 pair_pio = pair->pio_mode - XFER_PIO_0;
/* trim PIO to the slowest of the master/slave */
if (pair_pio < set_pio)
set_pio = pair_pio;
@@ -393,14 +394,16 @@ static int it821x_dma_end(ide_drive_t *drive)
/**
* it821x_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Tune the ITE chipset for the desired DMA mode.
*/
-static void it821x_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void it821x_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
+ const u8 speed = drive->dma_mode;
+
/*
* MWDMA tuning is really hard because our MWDMA and PIO
* timings are kept in the same place. We can switch in the
@@ -525,7 +528,7 @@ static struct ide_dma_ops it821x_pass_through_dma_ops = {
* ide DMA handlers appropriately
*/
-static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
+static void init_hwif_it821x(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
@@ -627,7 +630,7 @@ static const struct ide_port_ops it821x_port_ops = {
.cable_detect = it821x_cable_detect,
};
-static const struct ide_port_info it821x_chipset __devinitdata = {
+static const struct ide_port_info it821x_chipset = {
.name = DRV_NAME,
.init_chipset = init_chipset_it821x,
.init_hwif = init_hwif_it821x,
@@ -644,7 +647,7 @@ static const struct ide_port_info it821x_chipset __devinitdata = {
* We then use the IDE PCI generic helper to do most of the work.
*/
-static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int it821x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct it821x_dev *itdevs;
int rc;
@@ -664,7 +667,7 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic
return rc;
}
-static void __devexit it821x_remove(struct pci_dev *dev)
+static void it821x_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct it821x_dev *itdevs = host->host_priv;
@@ -686,7 +689,7 @@ static struct pci_driver it821x_pci_driver = {
.name = "ITE821x IDE",
.id_table = it821x_pci_tbl,
.probe = it821x_init_one,
- .remove = __devexit_p(it821x_remove),
+ .remove = it821x_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
diff --git a/drivers/ide/jmicron.c b/drivers/ide/jmicron.c
index bf2be6431b2..ae6480dcbad 100644
--- a/drivers/ide/jmicron.c
+++ b/drivers/ide/jmicron.c
@@ -80,19 +80,19 @@ static u8 jmicron_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static void jmicron_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void jmicron_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
}
/**
* jmicron_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @mode: DMA mode
*
* As the JMicron snoops for timings we don't need to do anything here.
*/
-static void jmicron_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void jmicron_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
}
@@ -102,7 +102,7 @@ static const struct ide_port_ops jmicron_port_ops = {
.cable_detect = jmicron_cable_detect,
};
-static const struct ide_port_info jmicron_chipset __devinitdata = {
+static const struct ide_port_info jmicron_chipset = {
.name = DRV_NAME,
.enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } },
.port_ops = &jmicron_port_ops,
@@ -120,7 +120,7 @@ static const struct ide_port_info jmicron_chipset __devinitdata = {
* We then use the IDE PCI generic helper to do most of the work.
*/
-static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int jmicron_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &jmicron_chipset, NULL);
}
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c
index 4b1718e8328..adc5fe9daaf 100644
--- a/drivers/ide/macide.c
+++ b/drivers/ide/macide.c
@@ -17,6 +17,7 @@
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/module.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
@@ -53,17 +54,20 @@
volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR);
-int macide_ack_intr(ide_hwif_t* hwif)
+int macide_test_irq(ide_hwif_t *hwif)
{
- if (*ide_ifr & 0x20) {
- *ide_ifr &= ~0x20;
+ if (*ide_ifr & 0x20)
return 1;
- }
return 0;
}
-static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
- int irq, ide_ack_intr_t *ack_intr)
+static void macide_clear_irq(ide_drive_t *drive)
+{
+ *ide_ifr &= ~0x20;
+}
+
+static void __init macide_setup_ports(struct ide_hw *hw, unsigned long base,
+ int irq)
{
int i;
@@ -75,14 +79,18 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->io_ports.ctl_addr = base + IDE_CONTROL;
hw->irq = irq;
- hw->ack_intr = ack_intr;
-
- hw->chipset = ide_generic;
}
+static const struct ide_port_ops macide_port_ops = {
+ .clear_irq = macide_clear_irq,
+ .test_irq = macide_test_irq,
+};
+
static const struct ide_port_info macide_port_info = {
+ .port_ops = &macide_port_ops,
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
+ .chipset = ide_generic,
};
static const char *mac_ide_name[] =
@@ -94,10 +102,10 @@ static const char *mac_ide_name[] =
static int __init macide_init(void)
{
- ide_ack_intr_t *ack_intr;
unsigned long base;
int irq;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
+ struct ide_port_info d = macide_port_info;
if (!MACH_IS_MAC)
return -ENODEV;
@@ -105,17 +113,15 @@ static int __init macide_init(void)
switch (macintosh_config->ide_type) {
case MAC_IDE_QUADRA:
base = IDE_BASE;
- ack_intr = macide_ack_intr;
irq = IRQ_NUBUS_F;
break;
case MAC_IDE_PB:
base = IDE_BASE;
- ack_intr = macide_ack_intr;
irq = IRQ_NUBUS_C;
break;
case MAC_IDE_BABOON:
base = BABOON_BASE;
- ack_intr = NULL;
+ d.port_ops = NULL;
irq = IRQ_BABOON_1;
break;
default:
@@ -125,9 +131,9 @@ static int __init macide_init(void)
printk(KERN_INFO "ide: Macintosh %s IDE controller\n",
mac_ide_name[macintosh_config->ide_type - 1]);
- macide_setup_ports(&hw, base, irq, ack_intr);
+ macide_setup_ports(&hw, base, irq);
- return ide_host_add(&macide_port_info, hws, NULL);
+ return ide_host_add(&d, hws, 1, NULL);
}
module_init(macide_init);
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 95327a2c242..392fd106edf 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -96,7 +96,7 @@ static const struct ide_tp_ops superio_tp_ops = {
.output_data = ide_output_data,
};
-static void __devinit superio_init_iops(struct hwif_s *hwif)
+static void superio_init_iops(struct hwif_s *hwif)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
u32 dma_stat;
@@ -201,7 +201,7 @@ static int ns87415_dma_end(ide_drive_t *drive)
return (dma_stat & 7) != 4;
}
-static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
+static void init_hwif_ns87415 (ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned int ctrl, using_inta;
@@ -293,7 +293,7 @@ static const struct ide_dma_ops ns87415_dma_ops = {
.dma_sff_read_status = superio_dma_sff_read_status,
};
-static const struct ide_port_info ns87415_chipset __devinitdata = {
+static const struct ide_port_info ns87415_chipset = {
.name = DRV_NAME,
.init_hwif = init_hwif_ns87415,
.tp_ops = &ns87415_tp_ops,
@@ -302,7 +302,7 @@ static const struct ide_port_info ns87415_chipset __devinitdata = {
IDE_HFLAG_NO_ATAPI_DMA,
};
-static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d = ns87415_chipset;
diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c
index 6048eda3cd6..26a45007e53 100644
--- a/drivers/ide/opti621.c
+++ b/drivers/ide/opti621.c
@@ -8,77 +8,6 @@
* Jan Harkes <jaharkes@cwi.nl>,
* Mark Lord <mlord@pobox.com>
* Some parts of code are from ali14xx.c and from rz1000.c.
- *
- * OPTi is trademark of OPTi, Octek is trademark of Octek.
- *
- * I used docs from OPTi databook, from ftp.opti.com, file 9123-0002.ps
- * and disassembled/traced setupvic.exe (DOS program).
- * It increases kernel code about 2 kB.
- * I don't have this card no more, but I hope I can get some in case
- * of needed development.
- * My card is Octek PIDE 1.01 (on card) or OPTiViC (program).
- * It has a place for a secondary connector in circuit, but nothing
- * is there. Also BIOS says no address for
- * secondary controller (see bellow in ide_init_opti621).
- * I've only tested this on my system, which only has one disk.
- * It's Western Digital WDAC2850, with PIO mode 3. The PCI bus
- * is at 20 MHz (I have DX2/80, I tried PCI at 40, but I got random
- * lockups). I tried the OCTEK double speed CD-ROM and
- * it does not work! But I can't boot DOS also, so it's probably
- * hardware fault. I have connected Conner 80MB, the Seagate 850MB (no
- * problems) and Seagate 1GB (as slave, WD as master). My experiences
- * with the third, 1GB drive: I got 3MB/s (hdparm), but sometimes
- * it slows to about 100kB/s! I don't know why and I have
- * not this drive now, so I can't try it again.
- * I write this driver because I lost the paper ("manual") with
- * settings of jumpers on the card and I have to boot Linux with
- * Loadlin except LILO, cause I have to run the setupvic.exe program
- * already or I get disk errors (my test: rpm -Vf
- * /usr/X11R6/bin/XF86_SVGA - or any big file).
- * Some numbers from hdparm -t /dev/hda:
- * Timing buffer-cache reads: 32 MB in 3.02 seconds =10.60 MB/sec
- * Timing buffered disk reads: 16 MB in 5.52 seconds = 2.90 MB/sec
- * I have 4 Megs/s before, but I don't know why (maybe changes
- * in hdparm test).
- * After release of 0.1, I got some successful reports, so it might work.
- *
- * The main problem with OPTi is that some timings for master
- * and slave must be the same. For example, if you have master
- * PIO 3 and slave PIO 0, driver have to set some timings of
- * master for PIO 0. Second problem is that opti621_set_pio_mode
- * got only one drive to set, but have to set both drives.
- * This is solved in compute_pios. If you don't set
- * the second drive, compute_pios use ide_get_best_pio_mode
- * for autoselect mode (you can change it to PIO 0, if you want).
- * If you then set the second drive to another PIO, the old value
- * (automatically selected) will be overrided by yours.
- * There is a 25/33MHz switch in configuration
- * register, but driver is written for use at any frequency.
- *
- * Version 0.1, Nov 8, 1996
- * by Jaromir Koutek, for 2.1.8.
- * Initial version of driver.
- *
- * Version 0.2
- * Number 0.2 skipped.
- *
- * Version 0.3, Nov 29, 1997
- * by Mark Lord (probably), for 2.1.68
- * Updates for use with new IDE block driver.
- *
- * Version 0.4, Dec 14, 1997
- * by Jan Harkes
- * Fixed some errors and cleaned the code.
- *
- * Version 0.5, Jan 2, 1998
- * by Jaromir Koutek
- * Updates for use with (again) new IDE block driver.
- * Update of documentation.
- *
- * Version 0.6, Jan 2, 1999
- * by Jaromir Koutek
- * Reversed to version 0.3 of the driver, because
- * 0.5 doesn't work.
*/
#include <linux/types.h>
@@ -133,11 +62,12 @@ static u8 read_reg(int reg)
return ret;
}
-static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void opti621_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
ide_drive_t *pair = ide_get_pair_dev(drive);
unsigned long flags;
+ unsigned long mode = drive->pio_mode, pair_mode;
+ const u8 pio = mode - XFER_PIO_0;
u8 tim, misc, addr_pio = pio, clk;
/* DRDY is default 2 (by OPTi Databook) */
@@ -150,11 +80,12 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
{ 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */
};
- drive->drive_data = XFER_PIO_0 + pio;
+ ide_set_drivedata(drive, (void *)mode);
if (pair) {
- if (pair->drive_data && pair->drive_data < drive->drive_data)
- addr_pio = pair->drive_data - XFER_PIO_0;
+ pair_mode = (unsigned long)ide_get_drivedata(pair);
+ if (pair_mode && pair_mode < mode)
+ addr_pio = pair_mode - XFER_PIO_0;
}
spin_lock_irqsave(&opti621_lock, flags);
@@ -200,7 +131,7 @@ static const struct ide_port_ops opti621_port_ops = {
.set_pio_mode = opti621_set_pio_mode,
};
-static const struct ide_port_info opti621_chipset __devinitdata = {
+static const struct ide_port_info opti621_chipset = {
.name = DRV_NAME,
.enablebits = { {0x45, 0x80, 0x00}, {0x40, 0x08, 0x00} },
.port_ops = &opti621_port_ops,
@@ -208,7 +139,7 @@ static const struct ide_port_info opti621_chipset __devinitdata = {
.pio_mask = ATA_PIO4,
};
-static int __devinit opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int opti621_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &opti621_chipset, NULL);
}
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index 09d813d313f..ba20d18c037 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -166,7 +166,7 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
writel(val32, base + BK3710_DATRCVR);
if (mate) {
- u8 mode2 = ide_get_best_pio_mode(mate, 255, 4);
+ u8 mode2 = mate->pio_mode - XFER_PIO_0;
if (mode2 < mode)
mode = mode2;
@@ -188,10 +188,11 @@ static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate,
writel(val32, base + BK3710_REGRCVR);
}
-static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
+static void palm_bk3710_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int is_slave = drive->dn & 1;
- void __iomem *base = (void *)drive->hwif->dma_base;
+ void __iomem *base = (void __iomem *)hwif->dma_base;
+ const u8 xferspeed = drive->dma_mode;
if (xferspeed >= XFER_UDMA_0) {
palm_bk3710_setudmamode(base, is_slave,
@@ -203,12 +204,13 @@ static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed)
}
}
-static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
+static void palm_bk3710_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
unsigned int cycle_time;
int is_slave = drive->dn & 1;
ide_drive_t *mate;
- void __iomem *base = (void *)drive->hwif->dma_base;
+ void __iomem *base = (void __iomem *)hwif->dma_base;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* Obtain the drive PIO data for tuning the Palm Chip registers
@@ -218,7 +220,7 @@ static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio)
palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio);
}
-static void __devinit palm_bk3710_chipinit(void __iomem *base)
+static void palm_bk3710_chipinit(void __iomem *base)
{
/*
* REVISIT: the ATA reset signal needs to be managed through a
@@ -280,8 +282,7 @@ static u8 palm_bk3710_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static int __devinit palm_bk3710_init_dma(ide_hwif_t *hwif,
- const struct ide_port_info *d)
+static int palm_bk3710_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
{
printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
@@ -299,13 +300,14 @@ static const struct ide_port_ops palm_bk3710_ports_ops = {
.cable_detect = palm_bk3710_cable_detect,
};
-static struct ide_port_info __devinitdata palm_bk3710_port_info = {
+static struct ide_port_info palm_bk3710_port_info = {
.init_dma = palm_bk3710_init_dma,
.port_ops = &palm_bk3710_ports_ops,
.dma_ops = &sff_dma_ops,
.host_flags = IDE_HFLAG_MMIO,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
+ .chipset = ide_palm3710,
};
static int __init palm_bk3710_probe(struct platform_device *pdev)
@@ -315,9 +317,9 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
void __iomem *base;
unsigned long rate, mem_size;
int i, rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
- clk = clk_get(&pdev->dev, "IDECLK");
+ clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(clk))
return -ENODEV;
@@ -339,7 +341,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
return -ENODEV;
}
- mem_size = mem->end - mem->start + 1;
+ mem_size = resource_size(mem);
if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
printk(KERN_ERR "failed to request memory region\n");
return -EBUSY;
@@ -363,13 +365,12 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
(base + IDE_PALM_ATA_PRI_CTL_OFFSET);
hw.irq = irq->start;
hw.dev = &pdev->dev;
- hw.chipset = ide_palm3710;
palm_bk3710_port_info.udma_mask = rate < 100000000 ? ATA_UDMA4 :
ATA_UDMA5;
/* Register the IDE interface with Linux */
- rc = ide_host_add(&palm_bk3710_port_info, hws, NULL);
+ rc = ide_host_add(&palm_bk3710_port_info, hws, 1, NULL);
if (rc)
goto out;
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c
index b68906c3c17..df73cbd9387 100644
--- a/drivers/ide/pdc202xx_new.c
+++ b/drivers/ide/pdc202xx_new.c
@@ -40,18 +40,6 @@
#define DBG(fmt, args...)
#endif
-static const char *pdc_quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP KA9.1",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP KX13.6",
- "QUANTUM FIREBALLP KX20.5",
- "QUANTUM FIREBALLP KX27.3",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
static u8 max_dma_rate(struct pci_dev *pdev)
{
u8 mode;
@@ -141,11 +129,11 @@ static struct udma_timing {
{ 0x1a, 0x01, 0xcb }, /* UDMA mode 6 */
};
-static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void pdcnew_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
+ const u8 speed = drive->dma_mode;
/*
* IDE core issues SETFEATURES_XFER to the drive first (thanks to
@@ -179,11 +167,11 @@ static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
}
-static void pdcnew_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void pdcnew_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
if (max_dma_rate(dev) == 4) {
set_indexed_reg(hwif, 0x0c + adj, pio_timings[pio].reg0c);
@@ -200,19 +188,6 @@ static u8 pdcnew_cable_detect(ide_hwif_t *hwif)
return ATA_CBL_PATA80;
}
-static void pdcnew_quirkproc(ide_drive_t *drive)
-{
- const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
-
- for (list = pdc_quirk_drives; *list != NULL; list++)
- if (strstr(m, *list) != NULL) {
- drive->quirk_list = 2;
- return;
- }
-
- drive->quirk_list = 0;
-}
-
static void pdcnew_reset(ide_drive_t *drive)
{
/*
@@ -447,7 +422,7 @@ static int init_chipset_pdcnew(struct pci_dev *dev)
return 0;
}
-static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
+static struct pci_dev *pdc20270_get_dev2(struct pci_dev *dev)
{
struct pci_dev *dev2;
@@ -473,7 +448,6 @@ static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
static const struct ide_port_ops pdcnew_port_ops = {
.set_pio_mode = pdcnew_set_pio_mode,
.set_dma_mode = pdcnew_set_dma_mode,
- .quirkproc = pdcnew_quirkproc,
.resetproc = pdcnew_reset,
.cable_detect = pdcnew_cable_detect,
};
@@ -491,7 +465,7 @@ static const struct ide_port_ops pdcnew_port_ops = {
.udma_mask = udma, \
}
-static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
+static const struct ide_port_info pdcnew_chipsets[] = {
/* 0: PDC202{68,70} */ DECLARE_PDCNEW_DEV(ATA_UDMA5),
/* 1: PDC202{69,71,75,76,77} */ DECLARE_PDCNEW_DEV(ATA_UDMA6),
};
@@ -505,7 +479,7 @@ static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
* finds a device matching our IDE device tables.
*/
-static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct ide_port_info *d = &pdcnew_chipsets[id->driver_data];
struct pci_dev *bridge = dev->bus->self;
@@ -540,7 +514,7 @@ static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_de
return ide_pci_init_one(dev, d, NULL);
}
-static void __devexit pdc202new_remove(struct pci_dev *dev)
+static void pdc202new_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL;
@@ -565,7 +539,7 @@ static struct pci_driver pdc202new_pci_driver = {
.name = "Promise_IDE",
.id_table = pdc202new_pci_tbl,
.probe = pdc202new_init_one,
- .remove = __devexit_p(pdc202new_remove),
+ .remove = pdc202new_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 248a54bd238..224ad46d6cb 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
- * Copyright (C) 2006-2007 MontaVista Software, Inc.
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2006-2007, 2009 MontaVista Software, Inc.
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
*
* Portions Copyright (C) 1999 Promise Technology, Inc.
* Author: Frank Tiernan (frankt@promise.com)
@@ -21,42 +21,15 @@
#define DRV_NAME "pdc202xx_old"
-#define PDC202XX_DEBUG_DRIVE_INFO 0
-
-static const char *pdc_quirk_drives[] = {
- "QUANTUM FIREBALLlct08 08",
- "QUANTUM FIREBALLP KA6.4",
- "QUANTUM FIREBALLP KA9.1",
- "QUANTUM FIREBALLP LM20.4",
- "QUANTUM FIREBALLP KX13.6",
- "QUANTUM FIREBALLP KX20.5",
- "QUANTUM FIREBALLP KX27.3",
- "QUANTUM FIREBALLP LM20.5",
- NULL
-};
-
-static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
-
-static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
+static void pdc202xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 drive_pci = 0x60 + (drive->dn << 2);
+ const u8 speed = drive->dma_mode;
u8 AP = 0, BP = 0, CP = 0;
u8 TA = 0, TB = 0, TC = 0;
-#if PDC202XX_DEBUG_DRIVE_INFO
- u32 drive_conf = 0;
- pci_read_config_dword(dev, drive_pci, &drive_conf);
-#endif
-
- /*
- * TODO: do this once per channel
- */
- if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
- pdc_old_disable_66MHz_clock(hwif);
-
pci_read_config_byte(dev, drive_pci, &AP);
pci_read_config_byte(dev, drive_pci + 1, &BP);
pci_read_config_byte(dev, drive_pci + 2, &CP);
@@ -85,7 +58,7 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
* Prefetch_EN / IORDY_EN / PA[3:0] bits of register A
*/
AP &= ~0x3f;
- if (ata_id_iordy_disable(drive->id))
+ if (ide_pio_need_iordy(drive, speed - XFER_PIO_0))
AP |= 0x20; /* set IORDY_EN bit */
if (drive->media == ide_disk)
AP |= 0x10; /* set Prefetch_EN bit */
@@ -101,19 +74,33 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, drive_pci + 1, BP | TB);
pci_write_config_byte(dev, drive_pci + 2, CP | TC);
}
+}
-#if PDC202XX_DEBUG_DRIVE_INFO
- printk(KERN_DEBUG "%s: %s drive%d 0x%08x ",
- drive->name, ide_xfer_verbose(speed),
- drive->dn, drive_conf);
- pci_read_config_dword(dev, drive_pci, &drive_conf);
- printk("0x%08x\n", drive_conf);
-#endif
+static void pdc202xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
+{
+ drive->dma_mode = drive->pio_mode;
+ pdc202xx_set_mode(hwif, drive);
}
-static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static int pdc202xx_test_irq(ide_hwif_t *hwif)
{
- pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long high_16 = pci_resource_start(dev, 4);
+ u8 sc1d = inb(high_16 + 0x1d);
+
+ if (hwif->channel) {
+ /*
+ * bit 7: error, bit 6: interrupting,
+ * bit 5: FIFO full, bit 4: FIFO empty
+ */
+ return (sc1d & 0x40) ? 1 : 0;
+ } else {
+ /*
+ * bit 3: error, bit 2: interrupting,
+ * bit 1: FIFO full, bit 0: FIFO empty
+ */
+ return (sc1d & 0x04) ? 1 : 0;
+ }
}
static u8 pdc2026x_cable_detect(ide_hwif_t *hwif)
@@ -151,17 +138,9 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
}
-static void pdc202xx_quirkproc(ide_drive_t *drive)
+static void pdc2026x_init_hwif(ide_hwif_t *hwif)
{
- const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
-
- for (list = pdc_quirk_drives; *list != NULL; list++)
- if (strstr(m, *list) != NULL) {
- drive->quirk_list = 2;
- return;
- }
-
- drive->quirk_list = 0;
+ pdc_old_disable_66MHz_clock(hwif);
}
static void pdc202xx_dma_start(ide_drive_t *drive)
@@ -177,7 +156,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive)
u8 clock = inb(high_16 + 0x11);
outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
- word_count = (rq->nr_sectors << 8);
+ word_count = (blk_rq_sectors(rq) << 8);
word_count = (rq_data_dir(rq) == READ) ?
word_count | 0x05000000 :
word_count | 0x06000000;
@@ -203,61 +182,6 @@ static int pdc202xx_dma_end(ide_drive_t *drive)
return ide_dma_end(drive);
}
-static int pdc202xx_dma_test_irq(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- unsigned long high_16 = hwif->extra_base - 16;
- u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
- u8 sc1d = inb(high_16 + 0x001d);
-
- if (hwif->channel) {
- /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */
- if ((sc1d & 0x50) == 0x50)
- goto somebody_else;
- else if ((sc1d & 0x40) == 0x40)
- return (dma_stat & 4) == 4;
- } else {
- /* bit3: Error, bit2: Interrupting, bit1: FIFO Full, bit0: FIFO Empty */
- if ((sc1d & 0x05) == 0x05)
- goto somebody_else;
- else if ((sc1d & 0x04) == 0x04)
- return (dma_stat & 4) == 4;
- }
-somebody_else:
- return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
-}
-
-static void pdc202xx_reset_host (ide_hwif_t *hwif)
-{
- unsigned long high_16 = hwif->extra_base - 16;
- u8 udma_speed_flag = inb(high_16 | 0x001f);
-
- outb(udma_speed_flag | 0x10, high_16 | 0x001f);
- mdelay(100);
- outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
- mdelay(2000); /* 2 seconds ?! */
-
- printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
- hwif->channel ? "Secondary" : "Primary");
-}
-
-static void pdc202xx_reset (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- ide_hwif_t *mate = hwif->mate;
-
- pdc202xx_reset_host(hwif);
- pdc202xx_reset_host(mate);
-
- ide_set_max_pio(drive);
-}
-
-static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
-{
- pdc202xx_reset(drive);
- ide_dma_lost_irq(drive);
-}
-
static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
@@ -287,8 +211,7 @@ out:
return 0;
}
-static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
- const char *name)
+static void pdc202ata4_fixup_irq(struct pci_dev *dev, const char *name)
{
if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {
u8 irq = 0, irq2 = 0;
@@ -311,38 +234,24 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
static const struct ide_port_ops pdc20246_port_ops = {
.set_pio_mode = pdc202xx_set_pio_mode,
.set_dma_mode = pdc202xx_set_mode,
- .quirkproc = pdc202xx_quirkproc,
+ .test_irq = pdc202xx_test_irq,
};
static const struct ide_port_ops pdc2026x_port_ops = {
.set_pio_mode = pdc202xx_set_pio_mode,
.set_dma_mode = pdc202xx_set_mode,
- .quirkproc = pdc202xx_quirkproc,
- .resetproc = pdc202xx_reset,
+ .test_irq = pdc202xx_test_irq,
.cable_detect = pdc2026x_cable_detect,
};
-static const struct ide_dma_ops pdc20246_dma_ops = {
- .dma_host_set = ide_dma_host_set,
- .dma_setup = ide_dma_setup,
- .dma_start = ide_dma_start,
- .dma_end = ide_dma_end,
- .dma_test_irq = pdc202xx_dma_test_irq,
- .dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_clear = pdc202xx_reset,
- .dma_sff_read_status = ide_dma_sff_read_status,
-};
-
static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
.dma_start = pdc202xx_dma_start,
.dma_end = pdc202xx_dma_end,
- .dma_test_irq = pdc202xx_dma_test_irq,
- .dma_lost_irq = pdc202xx_dma_lost_irq,
+ .dma_test_irq = ide_dma_test_irq,
+ .dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -350,6 +259,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_pdc202xx, \
+ .init_hwif = pdc2026x_init_hwif, \
.port_ops = &pdc2026x_port_ops, \
.dma_ops = &pdc2026x_dma_ops, \
.host_flags = IDE_HFLAGS_PDC202XX, \
@@ -359,12 +269,12 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
.max_sectors = sectors, \
}
-static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
+static const struct ide_port_info pdc202xx_chipsets[] = {
{ /* 0: PDC20246 */
.name = DRV_NAME,
.init_chipset = init_chipset_pdc202xx,
.port_ops = &pdc20246_port_ops,
- .dma_ops = &pdc20246_dma_ops,
+ .dma_ops = &sff_dma_ops,
.host_flags = IDE_HFLAGS_PDC202XX,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
@@ -386,7 +296,8 @@ static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
* finds a device matching our IDE device tables.
*/
-static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int pdc202xx_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
const struct ide_port_info *d;
u8 idx = id->driver_data;
@@ -445,6 +356,6 @@ static void __exit pdc202xx_ide_exit(void)
module_init(pdc202xx_ide_init);
module_exit(pdc202xx_ide_exit);
-MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
+MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index 2aa69993306..a671cead6ae 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -8,8 +8,8 @@
*
* Documentation:
*
- * Publically available from Intel web site. Errata documentation
- * is also publically available. As an aide to anyone hacking on this
+ * Publicly available from Intel web site. Errata documentation
+ * is also publicly available. As an aide to anyone hacking on this
* driver the list of errata that are relevant is below.going back to
* PIIX4. Older device documentation is now a bit tricky to find.
*
@@ -59,15 +59,14 @@ static int no_piix_dma;
/**
* piix_set_pio_mode - set host controller for PIO mode
+ * @port: port
* @drive: drive
- * @pio: PIO mode number
*
* Set the interface PIO mode based upon the settings done by AMI BIOS.
*/
-static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void piix_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
@@ -77,6 +76,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
u8 slave_data;
static DEFINE_SPINLOCK(tune_lock);
int control = 0;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
/* ISP RTC */
static const u8 timings[][2]= {
@@ -98,7 +98,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
control |= 1; /* Programmable timing on */
if (drive->media == ide_disk)
control |= 4; /* Prefetch, post write */
- if (pio > 2)
+ if (ide_pio_need_iordy(drive, pio))
control |= 2; /* IORDY */
if (is_slave) {
master_data |= 0x4000;
@@ -127,16 +127,15 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* piix_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Set a PIIX host controller to the desired DMA mode. This involves
* programming the right timing data into the PCI configuration space.
*/
-static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void piix_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 maslave = hwif->channel ? 0x42 : 0x40;
int a_speed = 3 << (drive->dn * 4);
@@ -147,6 +146,7 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
int sitre;
u16 reg4042, reg4a;
u8 reg48, reg54, reg55;
+ const u8 speed = drive->dma_mode;
pci_read_config_word(dev, maslave, &reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
@@ -176,7 +176,6 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x54, reg54 & ~v_flag);
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
- u8 pio;
if (reg48 & u_flag)
pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
@@ -188,11 +187,12 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_byte(dev, 0x55, (u8) reg55 & ~w_flag);
if (speed >= XFER_MW_DMA_0)
- pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ drive->pio_mode =
+ mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
else
- pio = 2; /* only SWDMA2 is allowed */
+ drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
- piix_set_pio_mode(drive, pio);
+ piix_set_pio_mode(hwif, drive);
}
}
@@ -263,6 +263,7 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */
{ 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
{ 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
+ { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
/* end marker */
{ 0, }
};
@@ -296,7 +297,7 @@ static u8 piix_cable_detect(ide_hwif_t *hwif)
* capabilities of the hardware.
*/
-static void __devinit init_hwif_piix(ide_hwif_t *hwif)
+static void init_hwif_piix(ide_hwif_t *hwif)
{
if (!hwif->dma_base)
return;
@@ -330,7 +331,7 @@ static const struct ide_port_ops ich_port_ops = {
.udma_mask = udma, \
}
-#define DECLARE_ICH_DEV(udma) \
+#define DECLARE_ICH_DEV(mwdma, udma) \
{ \
.name = DRV_NAME, \
.init_chipset = init_chipset_ich, \
@@ -339,11 +340,11 @@ static const struct ide_port_ops ich_port_ops = {
.port_ops = &ich_port_ops, \
.pio_mask = ATA_PIO4, \
.swdma_mask = ATA_SWDMA2_ONLY, \
- .mwdma_mask = ATA_MWDMA12_ONLY, \
+ .mwdma_mask = mwdma, \
.udma_mask = udma, \
}
-static const struct ide_port_info piix_pci_info[] __devinitdata = {
+static const struct ide_port_info piix_pci_info[] = {
/* 0: MPIIX */
{ /*
* MPIIX actually has only a single IDE channel mapped to
@@ -361,13 +362,15 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
/* 2: PIIX4 */
DECLARE_PIIX_DEV(ATA_UDMA2),
/* 3: ICH0 */
- DECLARE_ICH_DEV(ATA_UDMA2),
+ DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA2),
/* 4: ICH */
- DECLARE_ICH_DEV(ATA_UDMA4),
+ DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA4),
/* 5: PIIX4 */
DECLARE_PIIX_DEV(ATA_UDMA4),
- /* 6: ICH[2-7]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */
- DECLARE_ICH_DEV(ATA_UDMA5),
+ /* 6: ICH[2-6]/ICH[2-3]M/C-ICH/ICH5-SATA/ESB2/ICH8M */
+ DECLARE_ICH_DEV(ATA_MWDMA12_ONLY, ATA_UDMA5),
+ /* 7: ICH7/7-R, no MWDMA1 */
+ DECLARE_ICH_DEV(ATA_MWDMA2_ONLY, ATA_UDMA5),
};
/**
@@ -379,7 +382,7 @@ static const struct ide_port_info piix_pci_info[] __devinitdata = {
* finds a device matching our IDE device tables.
*/
-static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int piix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &piix_pci_info[id->driver_data], NULL);
}
@@ -391,7 +394,7 @@ static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_
* they are found, disable use of DMA IDE
*/
-static void __devinit piix_check_450nx(void)
+static void piix_check_450nx(void)
{
struct pci_dev *pdev = NULL;
u16 cfg;
@@ -437,9 +440,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
#endif
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB_2), 6 },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH6_19), 6 },
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 6 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH7_21), 7 },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_82801DB_1), 6 },
- { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 6 },
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ESB2_18), 7 },
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICH8_6), 6 },
{ 0, },
};
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index f76e4e6b408..2db803cd095 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -28,11 +28,13 @@
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/notifier.h>
+#include <linux/module.h>
#include <linux/reboot.h>
#include <linux/pci.h>
#include <linux/adb.h>
#include <linux/pmu.h>
#include <linux/scatterlist.h>
+#include <linux/slab.h>
#include <asm/prom.h>
#include <asm/io.h>
@@ -43,10 +45,7 @@
#include <asm/pmac_feature.h>
#include <asm/sections.h>
#include <asm/irq.h>
-
-#ifndef CONFIG_PPC64
#include <asm/mediabay.h>
-#endif
#define DRV_NAME "ide-pmac"
@@ -59,13 +58,14 @@ typedef struct pmac_ide_hwif {
int irq;
int kind;
int aapl_bus_id;
- unsigned mediabay : 1;
unsigned broken_dma : 1;
unsigned broken_dma_warn : 1;
struct device_node* node;
struct macio_dev *mdev;
u32 timings[4];
volatile u32 __iomem * *kauai_fcr;
+ ide_hwif_t *hwif;
+
/* Those fields are duplicating what is in hwif. We currently
* can't use the hwif ones because of some assumptions that are
* beeing done by the generic code about the kind of dma controller
@@ -416,8 +416,7 @@ static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
static void pmac_ide_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
if (drive->dn & 1)
writel(pmif->timings[1], PMAC_IDE_REG(IDE_TIMING_CONFIG));
@@ -434,8 +433,7 @@ static void pmac_ide_apply_timings(ide_drive_t *drive)
static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
if (drive->dn & 1) {
writel(pmif->timings[1], PMAC_IDE_REG(IDE_KAUAI_PIO_CONFIG));
@@ -454,8 +452,7 @@ static void
pmac_ide_do_update_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
if (pmif->kind == controller_sh_ata6 ||
pmif->kind == controller_un_ata6 ||
@@ -498,12 +495,10 @@ static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
/*
* Old tuning functions (called on hdparm -p), sets up drive PIO timings
*/
-static void
-pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
u32 *timings, t;
unsigned accessTicks, recTicks;
@@ -780,14 +775,13 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
#endif
}
-static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void pmac_ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
int ret = 0;
u32 *timings, *timings2, tl[2];
u8 unit = drive->dn & 1;
+ const u8 speed = drive->dma_mode;
timings = &pmif->timings[unit];
timings2 = &pmif->timings[unit+2];
@@ -854,6 +848,11 @@ sanitize_timings(pmac_ide_hwif_t *pmif)
pmif->timings[2] = pmif->timings[3] = value2;
}
+static int on_media_bay(pmac_ide_hwif_t *pmif)
+{
+ return pmif->mdev && pmif->mdev->media_bay != NULL;
+}
+
/* Suspend call back, should be called after the child devices
* have actually been suspended
*/
@@ -866,7 +865,7 @@ static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
disable_irq(pmif->irq);
/* The media bay will handle itself just fine */
- if (pmif->mediabay)
+ if (on_media_bay(pmif))
return 0;
/* Kauai has bus control FCRs directly here */
@@ -889,7 +888,7 @@ static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif)
static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
{
/* Hard reset & re-enable controller (do we really need to reset ? -BenH) */
- if (!pmif->mediabay) {
+ if (!on_media_bay(pmif)) {
ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1);
ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);
msleep(10);
@@ -915,8 +914,7 @@ static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif)
static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
{
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
struct device_node *np = pmif->node;
const char *cable = of_get_property(np, "cable-type", NULL);
struct device_node *root = of_find_node_by_path("/");
@@ -947,16 +945,13 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
static void pmac_ide_init_dev(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
- if (pmif->mediabay) {
-#ifdef CONFIG_PMAC_MEDIABAY
- if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) {
+ if (on_media_bay(pmif)) {
+ if (check_media_bay(pmif->mdev->media_bay) == MB_CD) {
drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
return;
}
-#endif
drive->dev_flags |= IDE_DFLAG_NOPROBE;
}
}
@@ -1023,13 +1018,13 @@ static const struct ide_port_info pmac_port_info = {
* Setup, register & probe an IDE channel driven by this driver, this is
* called by one of the 2 probe functions (macio or PCI).
*/
-static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
+static int pmac_ide_setup_device(pmac_ide_hwif_t *pmif, struct ide_hw *hw)
{
struct device_node *np = pmif->node;
const int *bidp;
struct ide_host *host;
ide_hwif_t *hwif;
- hw_regs_t *hws[] = { hw, NULL, NULL, NULL };
+ struct ide_hw *hws[] = { hw };
struct ide_port_info d = pmac_port_info;
int rc;
@@ -1071,26 +1066,23 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
writel(KAUAI_FCR_UATA_MAGIC |
KAUAI_FCR_UATA_RESET_N |
KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr);
-
- pmif->mediabay = 0;
/* Make sure we have sane timings */
sanitize_timings(pmif);
- host = ide_host_alloc(&d, hws);
- if (host == NULL)
- return -ENOMEM;
- hwif = host->ports[0];
+ /* If we are on a media bay, wait for it to settle and lock it */
+ if (pmif->mdev)
+ lock_media_bay(pmif->mdev->media_bay);
-#ifndef CONFIG_PPC64
- /* XXX FIXME: Media bay stuff need re-organizing */
- if (np->parent && np->parent->name
- && strcasecmp(np->parent->name, "media-bay") == 0) {
-#ifdef CONFIG_PMAC_MEDIABAY
- media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq,
- hwif);
-#endif /* CONFIG_PMAC_MEDIABAY */
- pmif->mediabay = 1;
+ host = ide_host_alloc(&d, hws, 1);
+ if (host == NULL) {
+ rc = -ENOMEM;
+ goto bail;
+ }
+ hwif = pmif->hwif = host->ports[0];
+
+ if (on_media_bay(pmif)) {
+ /* Fixup bus ID for media bay */
if (!bidp)
pmif->aapl_bus_id = 1;
} else if (pmif->kind == controller_ohare) {
@@ -1099,9 +1091,7 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
* units, I keep the old way
*/
ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1);
- } else
-#endif
- {
+ } else {
/* This is necessary to enable IDE when net-booting */
ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1);
ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);
@@ -1111,20 +1101,24 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
}
printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), "
- "bus ID %d%s, irq %d\n", model_name[pmif->kind],
- pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
- pmif->mediabay ? " (mediabay)" : "", hw->irq);
+ "bus ID %d%s, irq %d\n", model_name[pmif->kind],
+ pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id,
+ on_media_bay(pmif) ? " (mediabay)" : "", hw->irq);
rc = ide_host_register(host, &d, hws);
- if (rc) {
- ide_host_free(host);
- return rc;
- }
+ if (rc)
+ pmif->hwif = NULL;
- return 0;
+ if (pmif->mdev)
+ unlock_media_bay(pmif->mdev->media_bay);
+
+ bail:
+ if (rc && host)
+ ide_host_free(host);
+ return rc;
}
-static void __devinit pmac_ide_init_ports(hw_regs_t *hw, unsigned long base)
+static void pmac_ide_init_ports(struct ide_hw *hw, unsigned long base)
{
int i;
@@ -1137,14 +1131,14 @@ static void __devinit pmac_ide_init_ports(hw_regs_t *hw, unsigned long base)
/*
* Attach to a macio probed interface
*/
-static int __devinit
-pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
+static int pmac_ide_macio_attach(struct macio_dev *mdev,
+ const struct of_device_id *match)
{
void __iomem *base;
unsigned long regbase;
pmac_ide_hwif_t *pmif;
int irq, rc;
- hw_regs_t hw;
+ struct ide_hw hw;
pmif = kzalloc(sizeof(*pmif), GFP_KERNEL);
if (pmif == NULL)
@@ -1152,7 +1146,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
if (macio_resource_count(mdev) == 0) {
printk(KERN_WARNING "ide-pmac: no address for %s\n",
- mdev->ofdev.node->full_name);
+ mdev->ofdev.dev.of_node->full_name);
rc = -ENXIO;
goto out_free_pmif;
}
@@ -1160,7 +1154,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
/* Request memory resource for IO ports */
if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {
printk(KERN_ERR "ide-pmac: can't request MMIO resource for "
- "%s!\n", mdev->ofdev.node->full_name);
+ "%s!\n", mdev->ofdev.dev.of_node->full_name);
rc = -EBUSY;
goto out_free_pmif;
}
@@ -1172,7 +1166,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
*/
if (macio_irq_count(mdev) == 0) {
printk(KERN_WARNING "ide-pmac: no intrs for device %s, using "
- "13\n", mdev->ofdev.node->full_name);
+ "13\n", mdev->ofdev.dev.of_node->full_name);
irq = irq_create_mapping(NULL, 13);
} else
irq = macio_irq(mdev, 0);
@@ -1181,7 +1175,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
regbase = (unsigned long) base;
pmif->mdev = mdev;
- pmif->node = mdev->ofdev.node;
+ pmif->node = mdev->ofdev.dev.of_node;
pmif->regbase = regbase;
pmif->irq = irq;
pmif->kauai_fcr = NULL;
@@ -1190,7 +1184,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match)
if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))
printk(KERN_WARNING "ide-pmac: can't request DMA "
"resource for %s!\n",
- mdev->ofdev.node->full_name);
+ mdev->ofdev.dev.of_node->full_name);
else
pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);
} else
@@ -1227,8 +1221,7 @@ out_free_pmif:
static int
pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
{
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(&mdev->ofdev.dev);
int rc = 0;
if (mesg.event != mdev->ofdev.dev.power.power_state.event
@@ -1244,8 +1237,7 @@ pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t mesg)
static int
pmac_ide_macio_resume(struct macio_dev *mdev)
{
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(&mdev->ofdev.dev);
int rc = 0;
if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
@@ -1260,15 +1252,15 @@ pmac_ide_macio_resume(struct macio_dev *mdev)
/*
* Attach to a PCI probed interface
*/
-static int __devinit
-pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
+static int pmac_ide_pci_attach(struct pci_dev *pdev,
+ const struct pci_device_id *id)
{
struct device_node *np;
pmac_ide_hwif_t *pmif;
void __iomem *base;
unsigned long rbase, rlen;
int rc;
- hw_regs_t hw;
+ struct ide_hw hw;
np = pci_device_to_OF_node(pdev);
if (np == NULL) {
@@ -1317,7 +1309,6 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id)
rc = pmac_ide_setup_device(pmif, &hw);
if (rc != 0) {
/* The inteface is released to the common IDE layer */
- pci_set_drvdata(pdev, NULL);
iounmap(base);
pci_release_regions(pdev);
kfree(pmif);
@@ -1333,7 +1324,7 @@ out_free_pmif:
static int
pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
{
- pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
+ pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev);
int rc = 0;
if (mesg.event != pdev->dev.power.power_state.event
@@ -1349,7 +1340,7 @@ pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
static int
pmac_ide_pci_resume(struct pci_dev *pdev)
{
- pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
+ pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev);
int rc = 0;
if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
@@ -1361,6 +1352,24 @@ pmac_ide_pci_resume(struct pci_dev *pdev)
return rc;
}
+#ifdef CONFIG_PMAC_MEDIABAY
+static void pmac_ide_macio_mb_event(struct macio_dev* mdev, int mb_state)
+{
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(&mdev->ofdev.dev);
+
+ switch(mb_state) {
+ case MB_CD:
+ if (!pmif->hwif->present)
+ ide_port_scan(pmif->hwif);
+ break;
+ default:
+ if (pmif->hwif->present)
+ ide_port_unregister_devices(pmif->hwif);
+ }
+}
+#endif /* CONFIG_PMAC_MEDIABAY */
+
+
static struct of_device_id pmac_ide_macio_match[] =
{
{
@@ -1380,11 +1389,17 @@ static struct of_device_id pmac_ide_macio_match[] =
static struct macio_driver pmac_ide_macio_driver =
{
- .name = "ide-pmac",
- .match_table = pmac_ide_macio_match,
+ .driver = {
+ .name = "ide-pmac",
+ .owner = THIS_MODULE,
+ .of_match_table = pmac_ide_macio_match,
+ },
.probe = pmac_ide_macio_attach,
.suspend = pmac_ide_macio_suspend,
.resume = pmac_ide_macio_resume,
+#ifdef CONFIG_PMAC_MEDIABAY
+ .mediabay_event = pmac_ide_macio_mb_event,
+#endif
};
static const struct pci_device_id pmac_ide_pci_match[] = {
@@ -1442,8 +1457,7 @@ out:
static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
struct dbdma_cmd *table;
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
struct scatterlist *sg;
@@ -1520,8 +1534,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
@@ -1546,8 +1559,7 @@ static void
pmac_ide_dma_start(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
volatile struct dbdma_regs __iomem *dma;
dma = pmif->dma_regs;
@@ -1564,8 +1576,7 @@ static int
pmac_ide_dma_end (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
u32 dstat;
@@ -1589,8 +1600,7 @@ static int
pmac_ide_dma_test_irq (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
unsigned long status, timeout;
@@ -1628,8 +1638,8 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
if ((status & FLUSH) == 0)
break;
if (++timeout > 100) {
- printk(KERN_WARNING "ide%d, ide_dma_test_irq \
- timeout flushing channel\n", hwif->index);
+ printk(KERN_WARNING "ide%d, ide_dma_test_irq timeout flushing channel\n",
+ hwif->index);
break;
}
}
@@ -1644,8 +1654,7 @@ static void
pmac_ide_dma_lost_irq (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
unsigned long status = readl(&dma->status);
@@ -1665,11 +1674,9 @@ static const struct ide_dma_ops pmac_dma_ops = {
* Allocate the data structures needed for using DMA with an interface
* and fill the proper list of functions pointers
*/
-static int __devinit pmac_ide_init_dma(ide_hwif_t *hwif,
- const struct ide_port_info *d)
+static int pmac_ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
{
- pmac_ide_hwif_t *pmif =
- (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
+ pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
struct pci_dev *dev = to_pci_dev(hwif->dev);
/* We won't need pci_dev if we switch to generic consistent
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index c7934667924..ecd0a69245f 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -15,6 +15,7 @@
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/ide.h>
+#include <linux/module.h>
#include <asm/ide.h>
@@ -51,11 +52,9 @@ static int q40ide_default_irq(unsigned long base)
/*
* Addresses are pretranslated for Q40 ISA access.
*/
-static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
- ide_ack_intr_t *ack_intr,
- int irq)
+static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base, int irq)
{
- memset(hw, 0, sizeof(hw_regs_t));
+ memset(hw, 0, sizeof(*hw));
/* BIG FAT WARNING:
assumption: only DATA port is ever used in 16 bit mode */
hw->io_ports.data_addr = Q40_ISA_IO_W(base);
@@ -69,9 +68,6 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206);
hw->irq = irq;
- hw->ack_intr = ack_intr;
-
- hw->chipset = ide_generic;
}
static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
@@ -119,6 +115,7 @@ static const struct ide_port_info q40ide_port_info = {
.tp_ops = &q40ide_tp_ops,
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
+ .chipset = ide_generic,
};
/*
@@ -136,7 +133,7 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
static int __init q40ide_init(void)
{
int i;
- hw_regs_t hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL };
+ struct ide_hw hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL };
if (!MACH_IS_Q40)
return -ENODEV;
@@ -157,13 +154,13 @@ static int __init q40ide_init(void)
release_region(pcide_bases[i], 8);
continue;
}
- q40_ide_setup_ports(&hw[i], pcide_bases[i], NULL,
+ q40_ide_setup_ports(&hw[i], pcide_bases[i],
q40ide_default_irq(pcide_bases[i]));
hws[i] = &hw[i];
}
- return ide_host_add(&q40ide_port_info, hws, NULL);
+ return ide_host_add(&q40ide_port_info, hws, Q40IDE_NUM_HWIFS, NULL);
}
module_init(q40ide_init);
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index c9a13498689..a6fb6a894c7 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -29,7 +29,6 @@
#include <linux/blkdev.h>
#include <linux/ide.h>
#include <linux/init.h>
-#include <asm/system.h>
#include <asm/io.h>
#define DRV_NAME "qd65xx"
@@ -180,21 +179,22 @@ static int qd_find_disk_type (ide_drive_t *drive,
static void qd_set_timing (ide_drive_t *drive, u8 timing)
{
- drive->drive_data &= 0xff00;
- drive->drive_data |= timing;
+ unsigned long data = (unsigned long)ide_get_drivedata(drive);
+
+ data &= 0xff00;
+ data |= timing;
+ ide_set_drivedata(drive, (void *)data);
printk(KERN_DEBUG "%s: %#x\n", drive->name, timing);
}
-static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void qd6500_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
u16 *id = drive->id;
int active_time = 175;
int recovery_time = 415; /* worst case values from the dos driver */
- /*
- * FIXME: use "pio" value
- */
+ /* FIXME: use drive->pio_mode value */
if (!qd_find_disk_type(drive, &active_time, &recovery_time) &&
(id[ATA_ID_OLD_PIO_MODES] & 0xff) && (id[ATA_ID_FIELD_VALID] & 2) &&
id[ATA_ID_EIDE_PIO] >= 240) {
@@ -208,9 +208,9 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
active_time, recovery_time));
}
-static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void qd6580_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
unsigned int cycle_time;
int active_time = 175;
@@ -292,7 +292,7 @@ static void __init qd6500_init_dev(ide_drive_t *drive)
u8 base = (hwif->config_data & 0xff00) >> 8;
u8 config = QD_CONFIG(hwif);
- drive->drive_data = QD6500_DEF_DATA;
+ ide_set_drivedata(drive, (void *)QD6500_DEF_DATA);
}
static void __init qd6580_init_dev(ide_drive_t *drive)
@@ -308,7 +308,7 @@ static void __init qd6580_init_dev(ide_drive_t *drive)
} else
t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA;
- drive->drive_data = (drive->dn & 1) ? t2 : t1;
+ ide_set_drivedata(drive, (void *)((drive->dn & 1) ? t2 : t1));
}
static const struct ide_tp_ops qd65xx_tp_ops = {
@@ -335,7 +335,7 @@ static const struct ide_port_ops qd6580_port_ops = {
.set_pio_mode = qd6580_set_pio_mode,
};
-static const struct ide_port_info qd65xx_port_info __initdata = {
+static const struct ide_port_info qd65xx_port_info __initconst = {
.name = DRV_NAME,
.tp_ops = &qd65xx_tp_ops,
.chipset = ide_qd65xx,
@@ -416,7 +416,7 @@ static int __init qd_probe(int base)
return rc;
}
-static int probe_qd65xx;
+static bool probe_qd65xx;
module_param_named(probe, probe_qd65xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
index d7e67a1a1dc..1fba2a5f281 100644
--- a/drivers/ide/qd65xx.h
+++ b/drivers/ide/qd65xx.h
@@ -31,8 +31,15 @@
#define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff)
-#define QD_TIMING(drive) (u8)(((drive)->drive_data) & 0x00ff)
-#define QD_TIMREG(drive) (u8)((((drive)->drive_data) & 0xff00) >> 8)
+static inline u8 QD_TIMING(ide_drive_t *drive)
+{
+ return (unsigned long)ide_get_drivedata(drive) & 0x00ff;
+}
+
+static inline u8 QD_TIMREG(ide_drive_t *drive)
+{
+ return ((unsigned long)ide_get_drivedata(drive) & 0xff00) >> 8;
+}
#define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08))
#define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
diff --git a/drivers/ide/rapide.c b/drivers/ide/rapide.c
index d5003ca6980..d73c3d10087 100644
--- a/drivers/ide/rapide.c
+++ b/drivers/ide/rapide.c
@@ -3,7 +3,6 @@
*/
#include <linux/module.h>
-#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/errno.h>
#include <linux/ide.h>
@@ -13,9 +12,10 @@
static const struct ide_port_info rapide_port_info = {
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .chipset = ide_generic,
};
-static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
+static void rapide_setup_ports(struct ide_hw *hw, void __iomem *base,
void __iomem *ctrl, unsigned int sz, int irq)
{
unsigned long port = (unsigned long)base;
@@ -29,13 +29,12 @@ static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base,
hw->irq = irq;
}
-static int __devinit
-rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
+static int rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
{
void __iomem *base;
struct ide_host *host;
int ret;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
ret = ecard_request_resources(ec);
if (ret)
@@ -49,10 +48,9 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
memset(&hw, 0, sizeof(hw));
rapide_setup_ports(&hw, base, base + 0x818, 1 << 6, ec->irq);
- hw.chipset = ide_generic;
hw.dev = &ec->dev;
- ret = ide_host_add(&rapide_port_info, hws, &host);
+ ret = ide_host_add(&rapide_port_info, hws, 1, &host);
if (ret)
goto release;
@@ -65,7 +63,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
return ret;
}
-static void __devexit rapide_remove(struct expansion_card *ec)
+static void rapide_remove(struct expansion_card *ec)
{
struct ide_host *host = ecard_get_drvdata(ec);
@@ -83,7 +81,7 @@ static struct ecard_id rapide_ids[] = {
static struct ecard_driver rapide_driver = {
.probe = rapide_probe,
- .remove = __devexit_p(rapide_remove),
+ .remove = rapide_remove,
.id_table = rapide_ids,
.drv = {
.name = "rapide",
diff --git a/drivers/ide/rz1000.c b/drivers/ide/rz1000.c
index a6414a884eb..f4b66f7ec9f 100644
--- a/drivers/ide/rz1000.c
+++ b/drivers/ide/rz1000.c
@@ -22,7 +22,7 @@
#define DRV_NAME "rz1000"
-static int __devinit rz1000_disable_readahead(struct pci_dev *dev)
+static int rz1000_disable_readahead(struct pci_dev *dev)
{
u16 reg;
@@ -38,12 +38,12 @@ static int __devinit rz1000_disable_readahead(struct pci_dev *dev)
}
}
-static const struct ide_port_info rz1000_chipset __devinitdata = {
+static const struct ide_port_info rz1000_chipset = {
.name = DRV_NAME,
.host_flags = IDE_HFLAG_NO_DMA,
};
-static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d = rz1000_chipset;
int rc;
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index d467478d68d..a5b70181840 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
@@ -122,13 +123,13 @@ out:
return mask;
}
-static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void sc1200_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned int reg, timings;
unsigned short pci_clock;
unsigned int basereg = hwif->channel ? 0x50 : 0x40;
+ const u8 mode = drive->dma_mode;
static const u32 udma_timing[3][3] = {
{ 0x00921250, 0x00911140, 0x00911030 },
@@ -193,10 +194,10 @@ static int sc1200_dma_end(ide_drive_t *drive)
* will have valid default PIO timings set up before we get here.
*/
-static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void sc1200_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
int mode = -1;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
/*
* bad abuse of ->set_pio_mode interface
@@ -290,7 +291,7 @@ static const struct ide_dma_ops sc1200_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info sc1200_chipset __devinitdata = {
+static const struct ide_port_info sc1200_chipset = {
.name = DRV_NAME,
.port_ops = &sc1200_port_ops,
.dma_ops = &sc1200_dma_ops,
@@ -302,7 +303,7 @@ static const struct ide_port_info sc1200_chipset __devinitdata = {
.udma_mask = ATA_UDMA2,
};
-static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct sc1200_saved_state *ss = NULL;
int rc;
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 5be41f25204..2a2d188b5d5 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -199,16 +199,15 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
/**
* scc_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Load the timing settings for this device mode into the
* controller.
*/
-static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct scc_ports *ports = ide_get_hwifdata(hwif);
unsigned long ctl_base = ports->ctl;
unsigned long cckctrl_port = ctl_base + 0xff0;
@@ -216,6 +215,7 @@ static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
unsigned long pioct_port = ctl_base + 0x004;
unsigned long reg;
int offset;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
reg = in_be32((void __iomem *)cckctrl_port);
if (reg & CCKCTRL_ATACLKOEN) {
@@ -231,16 +231,15 @@ static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
/**
* scc_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Load the timing settings for this device mode into the
* controller.
*/
-static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct scc_ports *ports = ide_get_hwifdata(hwif);
unsigned long ctl_base = ports->ctl;
unsigned long cckctrl_port = ctl_base + 0xff0;
@@ -254,6 +253,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
int offset, idx;
unsigned long reg;
unsigned long jcactsel;
+ const u8 speed = drive->dma_mode;
reg = in_be32((void __iomem *)cckctrl_port);
if (reg & CCKCTRL_ATACLKOEN) {
@@ -559,7 +559,7 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
{
struct scc_ports *ports = pci_get_drvdata(dev);
struct ide_host *host;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
int i, rc;
memset(&hw, 0, sizeof(hw));
@@ -567,9 +567,8 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
hw.io_ports_array[i] = ports->dma + 0x20 + i * 4;
hw.irq = dev->irq;
hw.dev = &dev->dev;
- hw.chipset = ide_pci;
- rc = ide_host_add(d, hws, &host);
+ rc = ide_host_add(d, hws, 1, &host);
if (rc)
return rc;
@@ -586,8 +585,7 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev,
* Perform the initial set up for this device.
*/
-static int __devinit init_setup_scc(struct pci_dev *dev,
- const struct ide_port_info *d)
+static int init_setup_scc(struct pci_dev *dev, const struct ide_port_info *d)
{
unsigned long ctl_base;
unsigned long dma_base;
@@ -719,7 +717,7 @@ static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
*
*/
-static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
+static void init_mmio_iops_scc(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct scc_ports *ports = pci_get_drvdata(dev);
@@ -739,7 +737,7 @@ static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
* and then do the MMIO setup.
*/
-static void __devinit init_iops_scc(ide_hwif_t *hwif)
+static void init_iops_scc(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -749,8 +747,7 @@ static void __devinit init_iops_scc(ide_hwif_t *hwif)
init_mmio_iops_scc(hwif);
}
-static int __devinit scc_init_dma(ide_hwif_t *hwif,
- const struct ide_port_info *d)
+static int scc_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
{
return ide_allocate_dma_engine(hwif);
}
@@ -769,7 +766,7 @@ static u8 scc_cable_detect(ide_hwif_t *hwif)
* ide DMA handlers appropriately.
*/
-static void __devinit init_hwif_scc(ide_hwif_t *hwif)
+static void init_hwif_scc(ide_hwif_t *hwif)
{
/* PTERADD */
out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
@@ -812,7 +809,7 @@ static const struct ide_dma_ops scc_dma_ops = {
.dma_sff_read_status = scc_dma_sff_read_status,
};
-static const struct ide_port_info scc_chipset __devinitdata = {
+static const struct ide_port_info scc_chipset = {
.name = "sccIDE",
.init_iops = init_iops_scc,
.init_dma = scc_init_dma,
@@ -823,6 +820,7 @@ static const struct ide_port_info scc_chipset __devinitdata = {
.host_flags = IDE_HFLAG_SINGLE,
.irq_flags = IRQF_SHARED,
.pio_mask = ATA_PIO4,
+ .chipset = ide_pci,
};
/**
@@ -834,7 +832,7 @@ static const struct ide_port_info scc_chipset __devinitdata = {
* We then use the IDE PCI generic helper to do most of the work.
*/
-static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return init_setup_scc(dev, &scc_chipset);
}
@@ -846,7 +844,7 @@ static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_i
* Called by the PCI code when it removes an SCC PATA controller.
*/
-static void __devexit scc_remove(struct pci_dev *dev)
+static void scc_remove(struct pci_dev *dev)
{
struct scc_ports *ports = pci_get_drvdata(dev);
struct ide_host *host = ports->host;
@@ -869,23 +867,21 @@ static struct pci_driver scc_pci_driver = {
.name = "SCC IDE",
.id_table = scc_pci_tbl,
.probe = scc_init_one,
- .remove = __devexit_p(scc_remove),
+ .remove = scc_remove,
};
-static int scc_ide_init(void)
+static int __init scc_ide_init(void)
{
return ide_pci_register_driver(&scc_pci_driver);
}
-module_init(scc_ide_init);
-/* -- No exit code?
-static void scc_ide_exit(void)
+static void __exit scc_ide_exit(void)
{
- ide_pci_unregister_driver(&scc_pci_driver);
+ pci_unregister_driver(&scc_pci_driver);
}
-module_exit(scc_ide_exit);
- */
+module_init(scc_ide_init);
+module_exit(scc_ide_exit);
MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index b6554ef9271..a97affca18a 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -2,7 +2,7 @@
* Copyright (C) 1998-2000 Michel Aubry
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2010 Bartlomiej Zolnierkiewicz
* Portions copyright (c) 2001 Sun Microsystems
*
*
@@ -52,8 +52,6 @@ static const char *svwks_bad_ata100[] = {
NULL
};
-static struct pci_dev *isa_dev;
-
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
char *m = (char *)&drive->id[ATA_ID_PROD];
@@ -67,26 +65,14 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list)
static u8 svwks_udma_filter(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- u8 mask = 0;
- if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE)
+ if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) {
return 0x1f;
- if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
- u32 reg = 0;
- if (isa_dev)
- pci_read_config_dword(isa_dev, 0x64, &reg);
-
- /*
- * Don't enable UDMA on disk devices for the moment
- */
- if(drive->media == ide_disk)
- return 0;
- /* Check the OSB4 DMA33 enable bit */
- return ((reg & 0x00004000) == 0x00004000) ? 0x07 : 0;
} else if (dev->revision < SVWKS_CSB5_REVISION_NEW) {
return 0x07;
- } else if (dev->revision >= SVWKS_CSB5_REVISION_NEW) {
- u8 btr = 0, mode;
+ } else {
+ u8 btr = 0, mode, mask;
+
pci_read_config_byte(dev, 0x5A, &btr);
mode = btr & 0x3;
@@ -101,13 +87,9 @@ static u8 svwks_udma_filter(ide_drive_t *drive)
case 1: mask = 0x07; break;
default: mask = 0x00; break;
}
- }
- if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
- (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
- (!(PCI_FUNC(dev->devfn) & 1)))
- mask = 0x1f;
- return mask;
+ return mask;
+ }
}
static u8 svwks_csb_check (struct pci_dev *dev)
@@ -124,12 +106,13 @@ static u8 svwks_csb_check (struct pci_dev *dev)
return 0;
}
-static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void svwks_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 };
static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 };
- struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
pci_write_config_byte(dev, drive_pci[drive->dn], pio_modes[pio]);
@@ -145,14 +128,14 @@ static void svwks_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
}
-static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void svwks_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 };
static const u8 dma_modes[] = { 0x77, 0x21, 0x20 };
static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 };
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
+ const u8 speed = drive->dma_mode;
u8 unit = drive->dn & 1;
u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0;
@@ -185,8 +168,9 @@ static int init_chipset_svwks(struct pci_dev *dev)
/* OSB4 : South Bridge and IDE */
if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
- isa_dev = pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
+ struct pci_dev *isa_dev =
+ pci_get_device(PCI_VENDOR_ID_SERVERWORKS,
+ PCI_DEVICE_ID_SERVERWORKS_OSB4, NULL);
if (isa_dev) {
pci_read_config_dword(isa_dev, 0x64, &reg);
reg &= ~0x00002000; /* disable 600ns interrupt mask */
@@ -195,6 +179,7 @@ static int init_chipset_svwks(struct pci_dev *dev)
"enabled.\n", pci_name(dev));
reg |= 0x00004000; /* enable UDMA/33 support */
pci_write_config_dword(isa_dev, 0x64, reg);
+ pci_dev_put(isa_dev);
}
}
@@ -343,7 +328,6 @@ static u8 svwks_cable_detect(ide_hwif_t *hwif)
static const struct ide_port_ops osb4_port_ops = {
.set_pio_mode = svwks_set_pio_mode,
.set_dma_mode = svwks_set_dma_mode,
- .udma_filter = svwks_udma_filter,
};
static const struct ide_port_ops svwks_port_ops = {
@@ -353,7 +337,7 @@ static const struct ide_port_ops svwks_port_ops = {
.cable_detect = svwks_cable_detect,
};
-static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
+static const struct ide_port_info serverworks_chipsets[] = {
{ /* 0: OSB4 */
.name = DRV_NAME,
.init_chipset = init_chipset_svwks,
@@ -407,7 +391,7 @@ static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
* finds a device matching our IDE device tables.
*/
-static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d;
u8 idx = id->driver_data;
@@ -460,6 +444,6 @@ static void __exit svwks_ide_exit(void)
module_init(svwks_ide_init);
module_exit(svwks_ide_exit);
-MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick");
+MODULE_AUTHOR("Michael Aubry. Andrzej Krzysztofowicz, Andre Hedrick, Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("PCI driver module for Serverworks OSB4/CSB5/CSB6 IDE");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 7a3a12d6e63..34a5e5223d5 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -1,13 +1,14 @@
/*
* Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 1995-1998 Mark Lord
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*/
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/export.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -301,11 +302,11 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
}
/**
- * ide_hw_configure - configure a hw_regs_t instance
+ * ide_hw_configure - configure a struct ide_hw instance
* @dev: PCI device holding interface
* @d: IDE port info
* @port: port number
- * @hw: hw_regs_t instance corresponding to this port
+ * @hw: struct ide_hw instance corresponding to this port
*
* Perform the initial set up for the hardware interface structure. This
* is done per interface port rather than per PCI device. There may be
@@ -315,7 +316,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *
*/
static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
- unsigned int port, hw_regs_t *hw)
+ unsigned int port, struct ide_hw *hw)
{
unsigned long ctl = 0, base = 0;
@@ -344,7 +345,6 @@ static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
memset(hw, 0, sizeof(*hw));
hw->dev = &dev->dev;
- hw->chipset = d->chipset ? d->chipset : ide_pci;
ide_std_init_ports(hw, base, ctl | 2);
return 0;
@@ -446,8 +446,8 @@ out:
* ide_pci_setup_ports - configure ports/devices on PCI IDE
* @dev: PCI device
* @d: IDE port info
- * @hw: hw_regs_t instances corresponding to this PCI IDE device
- * @hws: hw_regs_t pointers table to update
+ * @hw: struct ide_hw instances corresponding to this PCI IDE device
+ * @hws: struct ide_hw pointers table to update
*
* Scan the interfaces attached to this device and do any
* necessary per port setup. Attach the devices and ask the
@@ -459,7 +459,7 @@ out:
*/
void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
- hw_regs_t *hw, hw_regs_t **hws)
+ struct ide_hw *hw, struct ide_hw **hws)
{
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
u8 tmp;
@@ -535,61 +535,15 @@ out:
return ret;
}
-int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
- void *priv)
-{
- struct ide_host *host;
- hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
- int ret;
-
- ret = ide_setup_pci_controller(dev, d, 1);
- if (ret < 0)
- goto out;
-
- ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
-
- host = ide_host_alloc(d, hws);
- if (host == NULL) {
- ret = -ENOMEM;
- goto out;
- }
-
- host->dev[0] = &dev->dev;
-
- host->host_priv = priv;
-
- host->irq_flags = IRQF_SHARED;
-
- pci_set_drvdata(dev, host);
-
- ret = do_ide_setup_pci_device(dev, d, 1);
- if (ret < 0)
- goto out;
-
- /* fixup IRQ */
- if (ide_pci_is_in_compatibility_mode(dev)) {
- hw[0].irq = pci_get_legacy_ide_irq(dev, 0);
- hw[1].irq = pci_get_legacy_ide_irq(dev, 1);
- } else
- hw[1].irq = hw[0].irq = ret;
-
- ret = ide_host_register(host, d, hws);
- if (ret)
- ide_host_free(host);
-out:
- return ret;
-}
-EXPORT_SYMBOL_GPL(ide_pci_init_one);
-
int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
const struct ide_port_info *d, void *priv)
{
struct pci_dev *pdev[] = { dev1, dev2 };
struct ide_host *host;
- int ret, i;
- hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL };
+ int ret, i, n_ports = dev2 ? 4 : 2;
+ struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL };
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < n_ports / 2; i++) {
ret = ide_setup_pci_controller(pdev[i], d, !i);
if (ret < 0)
goto out;
@@ -597,23 +551,24 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
}
- host = ide_host_alloc(d, hws);
+ host = ide_host_alloc(d, hws, n_ports);
if (host == NULL) {
ret = -ENOMEM;
goto out;
}
host->dev[0] = &dev1->dev;
- host->dev[1] = &dev2->dev;
+ if (dev2)
+ host->dev[1] = &dev2->dev;
host->host_priv = priv;
-
host->irq_flags = IRQF_SHARED;
pci_set_drvdata(pdev[0], host);
- pci_set_drvdata(pdev[1], host);
+ if (dev2)
+ pci_set_drvdata(pdev[1], host);
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < n_ports / 2; i++) {
ret = do_ide_setup_pci_device(pdev[i], d, !i);
/*
@@ -639,6 +594,13 @@ out:
}
EXPORT_SYMBOL_GPL(ide_pci_init_two);
+int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
+ void *priv)
+{
+ return ide_pci_init_two(dev, NULL, d, priv);
+}
+EXPORT_SYMBOL_GPL(ide_pci_init_one);
+
void ide_pci_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index e5d2a48a84d..63761db6138 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved.
- * Copyright (C) 2008 MontaVista Software, Inc.
+ * Copyright (C) 2008-2009 MontaVista Software, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
@@ -29,8 +29,7 @@
#include <linux/blkdev.h>
#include <linux/scatterlist.h>
#include <linux/ioc4.h>
-#include <asm/io.h>
-
+#include <linux/io.h>
#include <linux/ide.h>
#define DRV_NAME "SGIIOC4"
@@ -72,7 +71,7 @@
#define IOC4_CMD_CTL_BLK_SIZE 0x20
#define IOC4_SUPPORTED_FIRMWARE_REV 46
-typedef struct {
+struct ioc4_dma_regs {
u32 timing_reg0;
u32 timing_reg1;
u32 low_mem_ptr;
@@ -82,17 +81,18 @@ typedef struct {
u32 dev_byte_count;
u32 mem_byte_count;
u32 status;
-} ioc4_dma_regs_t;
+};
/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */
/* IOC4 has only 1 IDE channel */
-#define IOC4_PRD_BYTES 16
-#define IOC4_PRD_ENTRIES (PAGE_SIZE /(4*IOC4_PRD_BYTES))
+#define IOC4_PRD_BYTES 16
+#define IOC4_PRD_ENTRIES (PAGE_SIZE / (4 * IOC4_PRD_BYTES))
-static void
-sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
- unsigned long ctrl_port, unsigned long irq_port)
+static void sgiioc4_init_hwif_ports(struct ide_hw *hw,
+ unsigned long data_port,
+ unsigned long ctrl_port,
+ unsigned long irq_port)
{
unsigned long reg = data_port;
int i;
@@ -105,13 +105,11 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
hw->io_ports.irq_addr = irq_port;
}
-static int
-sgiioc4_checkirq(ide_hwif_t * hwif)
+static int sgiioc4_checkirq(ide_hwif_t *hwif)
{
- unsigned long intr_addr =
- hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
+ unsigned long intr_addr = hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
- if ((u8)readl((void __iomem *)intr_addr) & 0x03)
+ if (readl((void __iomem *)intr_addr) & 0x03)
return 1;
return 0;
@@ -119,8 +117,7 @@ sgiioc4_checkirq(ide_hwif_t * hwif)
static u8 sgiioc4_read_status(ide_hwif_t *);
-static int
-sgiioc4_clearirq(ide_drive_t * drive)
+static int sgiioc4_clearirq(ide_drive_t *drive)
{
u32 intr_reg;
ide_hwif_t *hwif = drive->hwif;
@@ -158,12 +155,10 @@ sgiioc4_clearirq(ide_drive_t * drive)
readl((void __iomem *)(io_ports->irq_addr + 4));
pci_read_config_dword(dev, PCI_COMMAND,
&pci_stat_cmd_reg);
- printk(KERN_ERR
- "%s(%s) : PCI Bus Error when doing DMA:"
- " status-cmd reg is 0x%x\n",
+ printk(KERN_ERR "%s(%s): PCI Bus Error when doing DMA: "
+ "status-cmd reg is 0x%x\n",
__func__, drive->name, pci_stat_cmd_reg);
- printk(KERN_ERR
- "%s(%s) : PCI Error Address is 0x%x%x\n",
+ printk(KERN_ERR "%s(%s): PCI Error Address is 0x%x%x\n",
__func__, drive->name,
pci_err_addr_high, pci_err_addr_low);
/* Clear the PCI Error indicator */
@@ -189,8 +184,7 @@ static void sgiioc4_dma_start(ide_drive_t *drive)
writel(temp_reg, (void __iomem *)ioc4_dma_addr);
}
-static u32
-sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
+static u32 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
{
unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
u32 ioc4_dma;
@@ -227,7 +221,7 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
}
/*
- * The IOC4 will DMA 1's to the ending dma area to indicate that
+ * The IOC4 will DMA 1's to the ending DMA area to indicate that
* previous data DMA is complete. This is necessary because of relaxed
* ordering between register reads and DMA writes on the Altix.
*/
@@ -261,11 +255,11 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
return dma_stat;
}
-static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sgiioc4_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
}
-/* returns 1 if dma irq issued, 0 otherwise */
+/* Returns 1 if DMA IRQ issued, 0 otherwise */
static int sgiioc4_dma_test_irq(ide_drive_t *drive)
{
return sgiioc4_checkirq(drive->hwif);
@@ -286,8 +280,7 @@ static void sgiioc4_resetproc(ide_drive_t *drive)
sgiioc4_clearirq(drive);
}
-static void
-sgiioc4_dma_lost_irq(ide_drive_t * drive)
+static void sgiioc4_dma_lost_irq(ide_drive_t *drive)
{
sgiioc4_resetproc(drive);
@@ -313,13 +306,12 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif)
return reg;
}
-/* Creates a dma map for the scatter-gather list entries */
-static int __devinit
-ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
+/* Creates a DMA map for the scatter-gather list entries */
+static int ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
- int num_ports = sizeof (ioc4_dma_regs_t);
+ int num_ports = sizeof(struct ioc4_dma_regs);
void *pad;
printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
@@ -362,8 +354,7 @@ dma_pci_alloc_failure:
}
/* Initializes the IOC4 DMA Engine */
-static void
-sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
+static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t *drive)
{
u32 ioc4_dma;
ide_hwif_t *hwif = drive->hwif;
@@ -374,31 +365,27 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
- printk(KERN_WARNING
- "%s(%s):Warning!! DMA from previous transfer was still active\n",
- __func__, drive->name);
+ printk(KERN_WARNING "%s(%s): Warning!! DMA from previous "
+ "transfer was still active\n", __func__, drive->name);
writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
if (ioc4_dma & IOC4_S_DMA_STOP)
- printk(KERN_ERR
- "%s(%s) : IOC4 Dma STOP bit is still 1\n",
- __func__, drive->name);
+ printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
+ "still 1\n", __func__, drive->name);
}
ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
if (ioc4_dma & IOC4_S_DMA_ERROR) {
- printk(KERN_WARNING
- "%s(%s) : Warning!! - DMA Error during Previous"
- " transfer | status 0x%x\n",
+ printk(KERN_WARNING "%s(%s): Warning!! DMA Error during "
+ "previous transfer, status 0x%x\n",
__func__, drive->name, ioc4_dma);
writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
if (ioc4_dma & IOC4_S_DMA_STOP)
- printk(KERN_ERR
- "%s(%s) : IOC4 DMA STOP bit is still 1\n",
- __func__, drive->name);
+ printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
+ "still 1\n", __func__, drive->name);
}
/* Address of the Scatter Gather List */
@@ -408,20 +395,22 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
/* Address of the Ending DMA */
memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
ending_dma_addr = cpu_to_le32(hwif->extra_base);
- writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
+ writel(ending_dma_addr, (void __iomem *)(dma_base +
+ IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
}
-/* IOC4 Scatter Gather list Format */
+/* IOC4 Scatter Gather list Format */
/* 128 Bit entries to support 64 bit addresses in the future */
/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format */
/* --------------------------------------------------------------------- */
-/* | Upper 32 bits - Zero | Lower 32 bits- address | */
+/* | Upper 32 bits - Zero | Lower 32 bits- address | */
/* --------------------------------------------------------------------- */
/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
/* --------------------------------------------------------------------- */
-/* Creates the scatter gather list, DMA Table */
+/* Creates the scatter gather list, DMA Table */
+
static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
@@ -448,8 +437,10 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (bcount > cur_len)
bcount = cur_len;
- /* put the addr, length in
- * the IOC4 dma-table format */
+ /*
+ * Put the address, length in
+ * the IOC4 dma-table format
+ */
*table = 0x0;
table++;
*table = cpu_to_be32(cur_addr);
@@ -528,7 +519,7 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
.dma_lost_irq = sgiioc4_dma_lost_irq,
};
-static const struct ide_port_info sgiioc4_port_info __devinitconst = {
+static const struct ide_port_info sgiioc4_port_info = {
.name = DRV_NAME,
.chipset = ide_pci,
.init_dma = ide_dma_sgiioc4,
@@ -540,16 +531,15 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = {
.mwdma_mask = ATA_MWDMA2_ONLY,
};
-static int __devinit
-sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
+static int sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
{
unsigned long cmd_base, irqport;
unsigned long bar0, cmd_phys_base, ctl;
void __iomem *virt_base;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
int rc;
- /* Get the CmdBlk and CtrlBlk Base Registers */
+ /* Get the CmdBlk and CtrlBlk base registers */
bar0 = pci_resource_start(dev, 0);
virt_base = pci_ioremap_bar(dev, 0);
if (virt_base == NULL) {
@@ -557,9 +547,9 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
DRV_NAME, bar0);
return -ENOMEM;
}
- cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET;
- ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET;
- irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET;
+ cmd_base = (unsigned long)virt_base + IOC4_CMD_OFFSET;
+ ctl = (unsigned long)virt_base + IOC4_CTRL_OFFSET;
+ irqport = (unsigned long)virt_base + IOC4_INTR_OFFSET;
cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
@@ -575,13 +565,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
memset(&hw, 0, sizeof(hw));
sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
hw.irq = dev->irq;
- hw.chipset = ide_pci;
hw.dev = &dev->dev;
- /* Initializing chipset IRQ Registers */
+ /* Initialize chipset IRQ registers */
writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
- rc = ide_host_add(&sgiioc4_port_info, hws, NULL);
+ rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL);
if (!rc)
return 0;
@@ -591,8 +580,7 @@ req_mem_rgn_err:
return rc;
}
-static unsigned int __devinit
-pci_init_sgiioc4(struct pci_dev *dev)
+static unsigned int pci_init_sgiioc4(struct pci_dev *dev)
{
int ret;
@@ -612,10 +600,10 @@ out:
return ret;
}
-int __devinit
-ioc4_ide_attach_one(struct ioc4_driver_data *idd)
+static int ioc4_ide_attach_one(struct ioc4_driver_data *idd)
{
- /* PCI-RT does not bring out IDE connection.
+ /*
+ * PCI-RT does not bring out IDE connection.
* Do not attach to this particular IOC4.
*/
if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
@@ -624,11 +612,10 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd)
return pci_init_sgiioc4(idd->idd_pdev);
}
-static struct ioc4_submodule __devinitdata ioc4_ide_submodule = {
+static struct ioc4_submodule ioc4_ide_submodule = {
.is_name = "IOC4_ide",
.is_owner = THIS_MODULE,
.is_probe = ioc4_ide_attach_one,
-/* .is_remove = ioc4_ide_remove_one, */
};
static int __init ioc4_ide_init(void)
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index e4973cd1fba..6a1849bb476 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -32,7 +32,6 @@
* smarter code in libata.
*
* TODO:
- * - IORDY fixes
* - VDMA support
*/
@@ -230,20 +229,18 @@ static u8 sil_sata_udma_filter(ide_drive_t *drive)
/**
* sil_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* Load the timing settings for this device mode into the
- * controller. If we are in PIO mode 3 or 4 turn on IORDY
- * monitoring (bit 9). The TF timing is bits 31:16
+ * controller.
*/
-static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
+static void sil_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
ide_drive_t *pair = ide_get_pair_dev(drive);
u32 speedt = 0;
@@ -251,6 +248,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
unsigned long addr = siimage_seldev(drive, 0x04);
unsigned long tfaddr = siimage_selreg(hwif, 0x02);
unsigned long base = (unsigned long)hwif->hwif_data;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 tf_pio = pio;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
u8 addr_mask = hwif->channel ? (mmio ? 0xF4 : 0x84)
@@ -260,7 +258,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
/* trim *taskfile* PIO to the slowest of the master/slave */
if (pair) {
- u8 pair_pio = ide_get_best_pio_mode(pair, 255, 4);
+ u8 pair_pio = pair->pio_mode - XFER_PIO_0;
if (pair_pio < tf_pio)
tf_pio = pair_pio;
@@ -276,31 +274,33 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
/* now set up IORDY */
speedp = sil_ioread16(dev, tfaddr - 2);
speedp &= ~0x200;
- if (pio > 2)
- speedp |= 0x200;
- sil_iowrite16(dev, speedp, tfaddr - 2);
mode = sil_ioread8(dev, base + addr_mask);
mode &= ~(unit ? 0x30 : 0x03);
- mode |= unit ? 0x10 : 0x01;
+
+ if (ide_pio_need_iordy(drive, pio)) {
+ speedp |= 0x200;
+ mode |= unit ? 0x10 : 0x01;
+ }
+
+ sil_iowrite16(dev, speedp, tfaddr - 2);
sil_iowrite8(dev, mode, base + addr_mask);
}
/**
* sil_set_dma_mode - set host controller for DMA mode
+ * @hwif: port
* @drive: drive
- * @speed: DMA mode
*
* Tune the SiI chipset for the desired DMA mode.
*/
-static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sil_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static const u8 ultra6[] = { 0x0F, 0x0B, 0x07, 0x05, 0x03, 0x02, 0x01 };
static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long base = (unsigned long)hwif->hwif_data;
u16 ultra = 0, multi = 0;
@@ -310,6 +310,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
: (mmio ? 0xB4 : 0x80);
unsigned long ma = siimage_seldev(drive, 0x08);
unsigned long ua = siimage_seldev(drive, 0x0C);
+ const u8 speed = drive->dma_mode;
scsc = sil_ioread8 (dev, base + (mmio ? 0x4A : 0x8A));
mode = sil_ioread8 (dev, base + addr_mask);
@@ -337,24 +338,14 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
sil_iowrite16(dev, ultra, ua);
}
-/* returns 1 if dma irq issued, 0 otherwise */
-static int siimage_io_dma_test_irq(ide_drive_t *drive)
+static int sil_test_irq(ide_hwif_t *hwif)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
- u8 dma_altstat = 0;
unsigned long addr = siimage_selreg(hwif, 1);
+ u8 val = sil_ioread8(dev, addr);
- /* return 1 if INTR asserted */
- if (inb(hwif->dma_base + ATA_DMA_STATUS) & 4)
- return 1;
-
- /* return 1 if Device INTR asserted */
- pci_read_config_byte(dev, addr, &dma_altstat);
- if (dma_altstat & 8)
- return 0; /* return 1; */
-
- return 0;
+ /* Return 1 if INTRQ asserted */
+ return (val & 8) ? 1 : 0;
}
/**
@@ -368,7 +359,6 @@ static int siimage_io_dma_test_irq(ide_drive_t *drive)
static int siimage_mmio_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- unsigned long addr = siimage_selreg(hwif, 0x1);
void __iomem *sata_error_addr
= (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET];
@@ -397,10 +387,6 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive)
if (readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)) & 4)
return 1;
- /* return 1 if Device INTR asserted */
- if (readb((void __iomem *)addr) & 8)
- return 0; /* return 1; */
-
return 0;
}
@@ -409,7 +395,7 @@ static int siimage_dma_test_irq(ide_drive_t *drive)
if (drive->hwif->host_flags & IDE_HFLAG_MMIO)
return siimage_mmio_dma_test_irq(drive);
else
- return siimage_io_dma_test_irq(drive);
+ return ide_dma_test_irq(drive);
}
/**
@@ -451,8 +437,8 @@ static int sil_sata_reset_poll(ide_drive_t *drive)
static void sil_sata_pre_reset(ide_drive_t *drive)
{
if (drive->media == ide_disk) {
- drive->special.b.set_geometry = 0;
- drive->special.b.recalibrate = 0;
+ drive->special_flags &=
+ ~(IDE_SFLAG_SET_GEOMETRY | IDE_SFLAG_RECALIBRATE);
}
}
@@ -560,7 +546,7 @@ static int init_chipset_siimage(struct pci_dev *dev)
* extended PRD tables. For better SI3112 support use the libata driver
*/
-static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
+static void init_mmio_iops_siimage(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
@@ -660,7 +646,7 @@ static void sil_quirkproc(ide_drive_t *drive)
* can get the iops right before using them.
*/
-static void __devinit init_iops_siimage(ide_hwif_t *hwif)
+static void init_iops_siimage(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
@@ -694,6 +680,7 @@ static const struct ide_port_ops sil_pata_port_ops = {
.set_pio_mode = sil_set_pio_mode,
.set_dma_mode = sil_set_dma_mode,
.quirkproc = sil_quirkproc,
+ .test_irq = sil_test_irq,
.udma_filter = sil_pata_udma_filter,
.cable_detect = sil_cable_detect,
};
@@ -704,6 +691,7 @@ static const struct ide_port_ops sil_sata_port_ops = {
.reset_poll = sil_sata_reset_poll,
.pre_reset = sil_sata_pre_reset,
.quirkproc = sil_quirkproc,
+ .test_irq = sil_test_irq,
.udma_filter = sil_sata_udma_filter,
.cable_detect = sil_cable_detect,
};
@@ -731,7 +719,7 @@ static const struct ide_dma_ops sil_dma_ops = {
.udma_mask = ATA_UDMA6, \
}
-static const struct ide_port_info siimage_chipsets[] __devinitdata = {
+static const struct ide_port_info siimage_chipsets[] = {
/* 0: SiI680 */ DECLARE_SII_DEV(&sil_pata_port_ops),
/* 1: SiI3112 */ DECLARE_SII_DEV(&sil_sata_port_ops)
};
@@ -745,8 +733,7 @@ static const struct ide_port_info siimage_chipsets[] __devinitdata = {
* We then use the IDE PCI generic helper to do most of the work.
*/
-static int __devinit siimage_init_one(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
void __iomem *ioaddr = NULL;
resource_size_t bar5 = pci_resource_start(dev, 5);
@@ -802,7 +789,7 @@ static int __devinit siimage_init_one(struct pci_dev *dev,
return rc;
}
-static void __devexit siimage_remove(struct pci_dev *dev)
+static void siimage_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
void __iomem *ioaddr = host->host_priv;
@@ -834,7 +821,7 @@ static struct pci_driver siimage_pci_driver = {
.name = "SiI_IDE",
.id_table = siimage_pci_tbl,
.probe = siimage_init_one,
- .remove = __devexit_p(siimage_remove),
+ .remove = siimage_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index afca22beaad..247853ea136 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -2,7 +2,7 @@
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
* Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz>
- * Copyright (C) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public License
*
@@ -53,7 +53,7 @@
#define DRV_NAME "sis5513"
-/* registers layout and init values are chipset family dependant */
+/* registers layout and init values are chipset family dependent */
#define ATA_16 0x01
#define ATA_33 0x02
@@ -281,17 +281,19 @@ static void config_drive_art_rwp(ide_drive_t *drive)
pci_read_config_byte(dev, 0x4b, &reg4bh);
+ rw_prefetch = reg4bh & ~(0x11 << drive->dn);
+
if (drive->media == ide_disk)
- rw_prefetch = 0x11 << drive->dn;
+ rw_prefetch |= 0x11 << drive->dn;
- if ((reg4bh & (0x11 << drive->dn)) != rw_prefetch)
- pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch);
+ if (reg4bh != rw_prefetch)
+ pci_write_config_byte(dev, 0x4b, rw_prefetch);
}
-static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void sis_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
config_drive_art_rwp(drive);
- sis_program_timings(drive, XFER_PIO_0 + pio);
+ sis_program_timings(drive, drive->pio_mode);
}
static void sis_ata133_program_udma_timings(ide_drive_t *drive, const u8 mode)
@@ -338,8 +340,10 @@ static void sis_program_udma_timings(ide_drive_t *drive, const u8 mode)
sis_ata33_program_udma_timings(drive, mode);
}
-static void sis_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sis_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
+ const u8 speed = drive->dma_mode;
+
if (speed >= XFER_UDMA_0)
sis_program_udma_timings(drive, speed);
else
@@ -358,7 +362,7 @@ static u8 sis_ata133_udma_filter(ide_drive_t *drive)
return (regdw & 0x08) ? ATA_UDMA6 : ATA_UDMA5;
}
-static int __devinit sis_find_family(struct pci_dev *dev)
+static int sis_find_family(struct pci_dev *dev)
{
struct pci_dev *host;
int i = 0;
@@ -402,7 +406,7 @@ static int __devinit sis_find_family(struct pci_dev *dev)
pci_name(dev));
chipset_family = ATA_133;
- /* Check for 5513 compability mapping
+ /* Check for 5513 compatibility mapping
* We must use this, else the port enabled code will fail,
* as it expects the enablebits at 0x4a.
*/
@@ -559,7 +563,7 @@ static const struct ide_port_ops sis_ata133_port_ops = {
.cable_detect = sis_cable_detect,
};
-static const struct ide_port_info sis5513_chipset __devinitdata = {
+static const struct ide_port_info sis5513_chipset = {
.name = DRV_NAME,
.init_chipset = init_chipset_sis5513,
.enablebits = { {0x4a, 0x02, 0x02}, {0x4a, 0x04, 0x04} },
@@ -568,7 +572,7 @@ static const struct ide_port_info sis5513_chipset __devinitdata = {
.mwdma_mask = ATA_MWDMA2,
};
-static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d = sis5513_chipset;
u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f };
@@ -591,7 +595,7 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi
return ide_pci_init_one(dev, &d, NULL);
}
-static void __devexit sis5513_remove(struct pci_dev *dev)
+static void sis5513_remove(struct pci_dev *dev)
{
ide_pci_remove(dev);
pci_disable_device(dev);
@@ -609,7 +613,7 @@ static struct pci_driver sis5513_pci_driver = {
.name = "SIS_IDE",
.id_table = sis5513_pci_tbl,
.probe = sis5513_init_one,
- .remove = __devexit_p(sis5513_remove),
+ .remove = sis5513_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
@@ -630,12 +634,3 @@ module_exit(sis5513_ide_exit);
MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick, Vojtech Pavlik");
MODULE_DESCRIPTION("PCI driver module for SIS IDE");
MODULE_LICENSE("GPL");
-
-/*
- * TODO:
- * - CLEANUP
- * - More checks in the config registers (force values instead of
- * relying on the BIOS setting them correctly).
- * - Further optimisations ?
- * . for example ATA66+ regs 0x48 & 0x4A
- */
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index b0a46062533..8755df3330a 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -10,7 +10,7 @@
* with the timing registers setup.
* -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org
*
- * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
+ * Copyright (C) 2006-2007,2009 MontaVista Software, Inc. <source@mvista.com>
* Copyright (C) 2007 Bartlomiej Zolnierkiewicz
*/
@@ -24,13 +24,6 @@
#define DRV_NAME "sl82c105"
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(arg) printk arg
-#else
-#define DBG(fmt,...)
-#endif
/*
* SL82C105 PCI config register 0x40 bits.
*/
@@ -61,8 +54,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
if (cmd_off == 0)
cmd_off = 1;
- if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
- !(pio > 4 && ata_id_is_cfa(drive->id)))
+ if (ide_pio_need_iordy(drive, pio))
iordy = 0x40;
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
@@ -71,11 +63,13 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
/*
* Configure the chipset for PIO mode.
*/
-static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void sl82c105_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
int reg = 0x44 + drive->dn * 4;
u16 drv_ctrl;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
drv_ctrl = get_pio_timings(drive, pio);
@@ -83,8 +77,9 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
* Store the PIO timings so that we can restore them
* in case DMA will be turned off...
*/
- drive->drive_data &= 0xffff0000;
- drive->drive_data |= drv_ctrl;
+ timings &= 0xffff0000;
+ timings |= drv_ctrl;
+ ide_set_drivedata(drive, (void *)timings);
pci_write_config_word(dev, reg, drv_ctrl);
pci_read_config_word (dev, reg, &drv_ctrl);
@@ -97,13 +92,12 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
/*
* Configure the chipset for DMA mode.
*/
-static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void sl82c105_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200};
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u16 drv_ctrl;
-
- DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n",
- drive->name, ide_xfer_verbose(speed)));
+ const u8 speed = drive->dma_mode;
drv_ctrl = mwdma_timings[speed - XFER_MW_DMA_0];
@@ -111,8 +105,19 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
* Store the DMA timings so that we can actually program
* them when DMA will be turned on...
*/
- drive->drive_data &= 0x0000ffff;
- drive->drive_data |= (unsigned long)drv_ctrl << 16;
+ timings &= 0x0000ffff;
+ timings |= (unsigned long)drv_ctrl << 16;
+ ide_set_drivedata(drive, (void *)timings);
+}
+
+static int sl82c105_test_irq(ide_hwif_t *hwif)
+{
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
+
+ pci_read_config_dword(dev, 0x40, &val);
+
+ return (val & mask) ? 1 : 0;
}
/*
@@ -146,14 +151,15 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive)
u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
u8 dma_cmd;
- printk("sl82c105: lost IRQ, resetting host\n");
+ printk(KERN_WARNING "sl82c105: lost IRQ, resetting host\n");
/*
* Check the raw interrupt from the drive.
*/
pci_read_config_dword(dev, 0x40, &val);
if (val & mask)
- printk("sl82c105: drive was requesting IRQ, but host lost it\n");
+ printk(KERN_INFO "sl82c105: drive was requesting IRQ, "
+ "but host lost it\n");
/*
* Was DMA enabled? If so, disable it - we're resetting the
@@ -162,7 +168,7 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive)
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
if (dma_cmd & 1) {
outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
- printk("sl82c105: DMA was enabled\n");
+ printk(KERN_INFO "sl82c105: DMA was enabled\n");
}
sl82c105_reset_host(dev);
@@ -182,9 +188,8 @@ static void sl82c105_dma_start(ide_drive_t *drive)
struct pci_dev *dev = to_pci_dev(hwif->dev);
int reg = 0x44 + drive->dn * 4;
- DBG(("%s(drive:%s)\n", __func__, drive->name));
-
- pci_write_config_word(dev, reg, drive->drive_data >> 16);
+ pci_write_config_word(dev, reg,
+ (unsigned long)ide_get_drivedata(drive) >> 16);
sl82c105_reset_host(dev);
ide_dma_start(drive);
@@ -194,8 +199,6 @@ static void sl82c105_dma_clear(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
-
sl82c105_reset_host(dev);
}
@@ -203,13 +206,10 @@ static int sl82c105_dma_end(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
int reg = 0x44 + drive->dn * 4;
- int ret;
+ int ret = ide_dma_end(drive);
- DBG(("%s(drive:%s)\n", __func__, drive->name));
-
- ret = ide_dma_end(drive);
-
- pci_write_config_word(dev, reg, drive->drive_data);
+ pci_write_config_word(dev, reg,
+ (unsigned long)ide_get_drivedata(drive));
return ret;
}
@@ -223,8 +223,6 @@ static void sl82c105_resetproc(ide_drive_t *drive)
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
u32 val;
- DBG(("sl82c105_resetproc(drive:%s)\n", drive->name));
-
pci_read_config_dword(dev, 0x40, &val);
val |= (CTRL_P1F16 | CTRL_P0F16);
pci_write_config_dword(dev, 0x40, val);
@@ -275,8 +273,6 @@ static int init_chipset_sl82c105(struct pci_dev *dev)
{
u32 val;
- DBG(("init_chipset_sl82c105()\n"));
-
pci_read_config_dword(dev, 0x40, &val);
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
@@ -288,6 +284,7 @@ static const struct ide_port_ops sl82c105_port_ops = {
.set_pio_mode = sl82c105_set_pio_mode,
.set_dma_mode = sl82c105_set_dma_mode,
.resetproc = sl82c105_resetproc,
+ .test_irq = sl82c105_test_irq,
};
static const struct ide_dma_ops sl82c105_dma_ops = {
@@ -302,7 +299,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info sl82c105_chipset __devinitdata = {
+static const struct ide_port_info sl82c105_chipset = {
.name = DRV_NAME,
.init_chipset = init_chipset_sl82c105,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
@@ -316,7 +313,7 @@ static const struct ide_port_info sl82c105_chipset __devinitdata = {
.mwdma_mask = ATA_MWDMA2,
};
-static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_port_info d = sl82c105_chipset;
u8 rev = sl82c105_bridge_revision(dev);
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index f55d7d6313e..8af92bbb3dc 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -18,9 +18,8 @@
static DEFINE_SPINLOCK(slc90e66_lock);
-static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void slc90e66_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int is_slave = drive->dn & 1;
int master_port = hwif->channel ? 0x42 : 0x40;
@@ -29,6 +28,8 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
u16 master_data;
u8 slave_data;
int control = 0;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
+
/* ISP RTC */
static const u8 timings[][2] = {
{ 0, 0 },
@@ -44,7 +45,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
control |= 1; /* Programmable timing on */
if (drive->media == ide_disk)
control |= 4; /* Prefetch, post write */
- if (pio > 2)
+ if (ide_pio_need_iordy(drive, pio))
control |= 2; /* IORDY */
if (is_slave) {
master_data |= 0x4000;
@@ -71,14 +72,14 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
spin_unlock_irqrestore(&slc90e66_lock, flags);
}
-static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
+static void slc90e66_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 maslave = hwif->channel ? 0x42 : 0x40;
int sitre = 0, a_speed = 7 << (drive->dn * 4);
int u_speed = 0, u_flag = 1 << drive->dn;
u16 reg4042, reg44, reg48, reg4a;
+ const u8 speed = drive->dma_mode;
pci_read_config_word(dev, maslave, &reg4042);
sitre = (reg4042 & 0x4000) ? 1 : 0;
@@ -91,15 +92,13 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
if (!(reg48 & u_flag))
pci_write_config_word(dev, 0x48, reg48|u_flag);
- /* FIXME: (reg4a & a_speed) ? */
- if ((reg4a & u_speed) != u_speed) {
+ if ((reg4a & a_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);
}
} else {
const u8 mwdma_to_pio[] = { 0, 3, 4 };
- u8 pio;
if (reg48 & u_flag)
pci_write_config_word(dev, 0x48, reg48 & ~u_flag);
@@ -107,11 +106,12 @@ static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
if (speed >= XFER_MW_DMA_0)
- pio = mwdma_to_pio[speed - XFER_MW_DMA_0];
+ drive->pio_mode =
+ mwdma_to_pio[speed - XFER_MW_DMA_0] + XFER_PIO_0;
else
- pio = 2; /* only SWDMA2 is allowed */
+ drive->pio_mode = XFER_PIO_2; /* for SWDMA2 */
- slc90e66_set_pio_mode(drive, pio);
+ slc90e66_set_pio_mode(hwif, drive);
}
}
@@ -132,7 +132,7 @@ static const struct ide_port_ops slc90e66_port_ops = {
.cable_detect = slc90e66_cable_detect,
};
-static const struct ide_port_info slc90e66_chipset __devinitdata = {
+static const struct ide_port_info slc90e66_chipset = {
.name = DRV_NAME,
.enablebits = { {0x41, 0x80, 0x80}, {0x43, 0x80, 0x80} },
.port_ops = &slc90e66_port_ops,
@@ -142,7 +142,8 @@ static const struct ide_port_info slc90e66_chipset __devinitdata = {
.udma_mask = ATA_UDMA4,
};
-static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int slc90e66_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &slc90e66_chipset, NULL);
}
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index b4cf42dc8a6..17e6132b99b 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -10,14 +10,15 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/ide.h>
+#include <linux/module.h>
#define DRV_NAME "tc86c001"
-static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
+static void tc86c001_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
u16 mode, scr = inw(scr_port);
+ const u8 speed = drive->dma_mode;
switch (speed) {
case XFER_UDMA_4: mode = 0x00c0; break;
@@ -41,9 +42,10 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
outw(scr, scr_port);
}
-static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void tc86c001_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- tc86c001_set_mode(drive, XFER_PIO_0 + pio);
+ drive->dma_mode = drive->pio_mode;
+ tc86c001_set_mode(hwif, drive);
}
/*
@@ -112,7 +114,7 @@ static void tc86c001_dma_start(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
unsigned long sc_base = hwif->config_data;
unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04);
- unsigned long nsectors = hwif->rq->nr_sectors;
+ unsigned long nsectors = blk_rq_sectors(hwif->rq);
/*
* We have to manually load the sector count and size into
@@ -142,7 +144,7 @@ static u8 tc86c001_cable_detect(ide_hwif_t *hwif)
return (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
+static void init_hwif_tc86c001(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long sc_base = pci_resource_start(dev, 5);
@@ -190,7 +192,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_sff_read_status = ide_dma_sff_read_status,
};
-static const struct ide_port_info tc86c001_chipset __devinitdata = {
+static const struct ide_port_info tc86c001_chipset = {
.name = DRV_NAME,
.init_hwif = init_hwif_tc86c001,
.port_ops = &tc86c001_port_ops,
@@ -201,8 +203,8 @@ static const struct ide_port_info tc86c001_chipset __devinitdata = {
.udma_mask = ATA_UDMA4,
};
-static int __devinit tc86c001_init_one(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int tc86c001_init_one(struct pci_dev *dev,
+ const struct pci_device_id *id)
{
int rc;
@@ -230,7 +232,7 @@ out:
return rc;
}
-static void __devexit tc86c001_remove(struct pci_dev *dev)
+static void tc86c001_remove(struct pci_dev *dev)
{
ide_pci_remove(dev);
pci_release_region(dev, 5);
@@ -247,7 +249,7 @@ static struct pci_driver tc86c001_pci_driver = {
.name = "TC86C001",
.id_table = tc86c001_pci_tbl,
.probe = tc86c001_init_one,
- .remove = __devexit_p(tc86c001_remove),
+ .remove = tc86c001_remove,
};
static int __init tc86c001_ide_init(void)
diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c
index 8773c3ba746..7f1af9493f0 100644
--- a/drivers/ide/triflex.c
+++ b/drivers/ide/triflex.c
@@ -22,7 +22,7 @@
* Loosely based on the piix & svwks drivers.
*
* Documentation:
- * Not publically available.
+ * Not publicly available.
*/
#include <linux/types.h>
@@ -34,9 +34,8 @@
#define DRV_NAME "triflex"
-static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
+static void triflex_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u32 triflex_timings = 0;
u16 timing = 0;
@@ -44,7 +43,7 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
pci_read_config_dword(dev, channel_offset, &triflex_timings);
- switch(speed) {
+ switch (drive->dma_mode) {
case XFER_MW_DMA_2:
timing = 0x0103;
break;
@@ -82,9 +81,10 @@ static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
pci_write_config_dword(dev, channel_offset, triflex_timings);
}
-static void triflex_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void triflex_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- triflex_set_mode(drive, XFER_PIO_0 + pio);
+ drive->dma_mode = drive->pio_mode;
+ triflex_set_mode(hwif, drive);
}
static const struct ide_port_ops triflex_port_ops = {
@@ -92,7 +92,7 @@ static const struct ide_port_ops triflex_port_ops = {
.set_dma_mode = triflex_set_mode,
};
-static const struct ide_port_info triflex_device __devinitdata = {
+static const struct ide_port_info triflex_device = {
.name = DRV_NAME,
.enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
.port_ops = &triflex_port_ops,
@@ -101,8 +101,7 @@ static const struct ide_port_info triflex_device __devinitdata = {
.mwdma_mask = ATA_MWDMA2,
};
-static int __devinit triflex_init_one(struct pci_dev *dev,
- const struct pci_device_id *id)
+static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &triflex_device, NULL);
}
@@ -113,12 +112,26 @@ static const struct pci_device_id triflex_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, triflex_pci_tbl);
+#ifdef CONFIG_PM
+static int triflex_ide_pci_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ /*
+ * We must not disable or powerdown the device.
+ * APM bios refuses to suspend if IDE is not accessible.
+ */
+ pci_save_state(dev);
+ return 0;
+}
+#else
+#define triflex_ide_pci_suspend NULL
+#endif
+
static struct pci_driver triflex_pci_driver = {
.name = "TRIFLEX_IDE",
.id_table = triflex_pci_tbl,
.probe = triflex_init_one,
.remove = ide_pci_remove,
- .suspend = ide_pci_suspend,
+ .suspend = triflex_ide_pci_suspend,
.resume = ide_pci_resume,
};
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index 4b42ca09153..0069f6ce74c 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -231,7 +231,7 @@ static void trm290_dma_host_set(ide_drive_t *drive, int on)
{
}
-static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
+static void init_hwif_trm290(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned int cfg_base = pci_resource_start(dev, 4);
@@ -324,7 +324,7 @@ static struct ide_dma_ops trm290_dma_ops = {
.dma_check = trm290_dma_check,
};
-static const struct ide_port_info trm290_chipset __devinitdata = {
+static const struct ide_port_info trm290_chipset = {
.name = DRV_NAME,
.init_hwif = init_hwif_trm290,
.tp_ops = &trm290_tp_ops,
@@ -338,7 +338,7 @@ static const struct ide_port_info trm290_chipset __devinitdata = {
IDE_HFLAG_NO_LBA48,
};
-static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &trm290_chipset, NULL);
}
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index e33d764e294..68edd4f58a2 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -56,16 +56,15 @@ static void tx4938ide_tune_ebusc(unsigned int ebus_ch,
&tx4938_ebuscptr->cr[ebus_ch]);
}
-static void tx4938ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void tx4938ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
- struct tx4938ide_platform_info *pdata = hwif->dev->platform_data;
- u8 safe = pio;
+ struct tx4938ide_platform_info *pdata = dev_get_platdata(hwif->dev);
+ u8 safe = drive->pio_mode - XFER_PIO_0;
ide_drive_t *pair;
pair = ide_get_pair_dev(drive);
if (pair)
- safe = min(safe, ide_get_best_pio_mode(pair, 255, 5));
+ safe = min_t(u8, safe, pair->pio_mode - XFER_PIO_0);
tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe);
}
@@ -118,7 +117,7 @@ static const struct ide_port_ops tx4938ide_port_ops = {
.set_pio_mode = tx4938ide_set_pio_mode,
};
-static const struct ide_port_info tx4938ide_port_info __initdata = {
+static const struct ide_port_info tx4938ide_port_info __initconst = {
.port_ops = &tx4938ide_port_ops,
#ifdef __BIG_ENDIAN
.tp_ops = &tx4938ide_tp_ops,
@@ -130,11 +129,10 @@ static const struct ide_port_info tx4938ide_port_info __initdata = {
static int __init tx4938ide_probe(struct platform_device *pdev)
{
- hw_regs_t hw;
- hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
struct ide_host *host;
struct resource *res;
- struct tx4938ide_platform_info *pdata = pdev->dev.platform_data;
+ struct tx4938ide_platform_info *pdata = dev_get_platdata(&pdev->dev);
int irq, ret, i;
unsigned long mapbase, mapctl;
struct ide_port_info d = tx4938ide_port_info;
@@ -147,7 +145,7 @@ static int __init tx4938ide_probe(struct platform_device *pdev)
return -ENODEV;
if (!devm_request_mem_region(&pdev->dev, res->start,
- res->end - res->start + 1, "tx4938ide"))
+ resource_size(res), "tx4938ide"))
return -EBUSY;
mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start,
8 << pdata->ioport_shift);
@@ -183,7 +181,7 @@ static int __init tx4938ide_probe(struct platform_device *pdev)
tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, 0);
else
d.port_ops = NULL;
- ret = ide_host_add(&d, hws, &host);
+ ret = ide_host_add(&d, hws, 1, &host);
if (!ret)
platform_set_drvdata(pdev, host);
return ret;
@@ -205,18 +203,7 @@ static struct platform_driver tx4938ide_driver = {
.remove = __exit_p(tx4938ide_remove),
};
-static int __init tx4938ide_init(void)
-{
- return platform_driver_probe(&tx4938ide_driver, tx4938ide_probe);
-}
-
-static void __exit tx4938ide_exit(void)
-{
- platform_driver_unregister(&tx4938ide_driver);
-}
-
-module_init(tx4938ide_init);
-module_exit(tx4938ide_exit);
+module_platform_driver_probe(tx4938ide_driver, tx4938ide_probe);
MODULE_DESCRIPTION("TX4938 internal IDE driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 564422d2397..4ecdee5eca8 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -104,17 +104,17 @@ static void tx4939ide_writeb(u8 val, void __iomem *base, u32 reg)
#define TX4939IDE_BASE(hwif) ((void __iomem *)(hwif)->extra_base)
-static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void tx4939ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
int is_slave = drive->dn;
u32 mask, val;
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
u8 safe = pio;
ide_drive_t *pair;
pair = ide_get_pair_dev(drive);
if (pair)
- safe = min(safe, ide_get_best_pio_mode(pair, 255, 4));
+ safe = min_t(u8, safe, pair->pio_mode - XFER_PIO_0);
/*
* Update Command Transfer Mode for master/slave and Data
* Transfer Mode for this drive.
@@ -125,10 +125,10 @@ static void tx4939ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
/* tx4939ide_tf_load_fixup() will set the Sys_Ctl register */
}
-static void tx4939ide_set_dma_mode(ide_drive_t *drive, const u8 mode)
+static void tx4939ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
u32 mask, val;
+ const u8 mode = drive->dma_mode;
/* Update Data Transfer Mode for this drive. */
if (mode >= XFER_UDMA_0)
@@ -307,7 +307,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
- tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+ tx4939ide_writew(blk_rq_sectors(cmd->rq), base, TX4939IDE_Sec_Cnt);
return 0;
}
@@ -522,7 +522,7 @@ static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
-static const struct ide_port_info tx4939ide_port_info __initdata = {
+static const struct ide_port_info tx4939ide_port_info __initconst = {
.init_hwif = tx4939ide_init_hwif,
.init_dma = tx4939ide_init_dma,
.port_ops = &tx4939ide_port_ops,
@@ -537,8 +537,7 @@ static const struct ide_port_info tx4939ide_port_info __initdata = {
static int __init tx4939ide_probe(struct platform_device *pdev)
{
- hw_regs_t hw;
- hw_regs_t *hws[] = { &hw, NULL, NULL, NULL };
+ struct ide_hw hw, *hws[] = { &hw };
struct ide_host *host;
struct resource *res;
int irq, ret;
@@ -552,10 +551,10 @@ static int __init tx4939ide_probe(struct platform_device *pdev)
return -ENODEV;
if (!devm_request_mem_region(&pdev->dev, res->start,
- res->end - res->start + 1, "tx4938ide"))
+ resource_size(res), "tx4938ide"))
return -EBUSY;
mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start,
- res->end - res->start + 1);
+ resource_size(res));
if (!mapbase)
return -EBUSY;
memset(&hw, 0, sizeof(hw));
@@ -581,7 +580,7 @@ static int __init tx4939ide_probe(struct platform_device *pdev)
hw.dev = &pdev->dev;
pr_info("TX4939 IDE interface (base %#lx, irq %d)\n", mapbase, irq);
- host = ide_host_alloc(&tx4939ide_port_info, hws);
+ host = ide_host_alloc(&tx4939ide_port_info, hws, 1);
if (!host)
return -ENOMEM;
/* use extra_base for base address of the all registers */
@@ -625,18 +624,7 @@ static struct platform_driver tx4939ide_driver = {
.resume = tx4939ide_resume,
};
-static int __init tx4939ide_init(void)
-{
- return platform_driver_probe(&tx4939ide_driver, tx4939ide_probe);
-}
-
-static void __exit tx4939ide_exit(void)
-{
- platform_driver_unregister(&tx4939ide_driver);
-}
-
-module_init(tx4939ide_init);
-module_exit(tx4939ide_exit);
+module_platform_driver_probe(tx4939ide_driver, tx4939ide_probe);
MODULE_DESCRIPTION("TX4939 internal IDE driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c
index 0608d41fb6d..3aa0fea0f3d 100644
--- a/drivers/ide/umc8672.c
+++ b/drivers/ide/umc8672.c
@@ -104,10 +104,11 @@ static void umc_set_speeds(u8 speeds[])
speeds[0], speeds[1], speeds[2], speeds[3]);
}
-static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void umc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif, *mate = hwif->mate;
+ ide_hwif_t *mate = hwif->mate;
unsigned long uninitialized_var(flags);
+ const u8 pio = drive->pio_mode - XFER_PIO_0;
printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
drive->name, pio, pio_to_umc[pio]);
@@ -127,7 +128,7 @@ static const struct ide_port_ops umc8672_port_ops = {
.set_pio_mode = umc_set_pio_mode,
};
-static const struct ide_port_info umc8672_port_info __initdata = {
+static const struct ide_port_info umc8672_port_info __initconst = {
.name = DRV_NAME,
.chipset = ide_umc8672,
.port_ops = &umc8672_port_ops,
@@ -159,7 +160,7 @@ static int __init umc8672_probe(void)
return ide_legacy_device_add(&umc8672_port_info, 0);
}
-static int probe_umc8672;
+static bool probe_umc8672;
module_param_named(probe, probe_umc8672, bool, 0);
MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
@@ -170,9 +171,9 @@ static int __init umc8672_init(void)
goto out;
if (umc8672_probe() == 0)
- return 0;;
+ return 0;
out:
- return -ENODEV;;
+ return -ENODEV;
}
module_init(umc8672_init);
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 3ff7231e485..01464f1e233 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -6,7 +6,7 @@
* vt8235, vt8237, vt8237a
*
* Copyright (c) 2000-2002 Vojtech Pavlik
- * Copyright (c) 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (c) 2007-2010 Bartlomiej Zolnierkiewicz
*
* Based on the work of:
* Michel Aubry
@@ -14,7 +14,7 @@
* Andre Hedrick
*
* Documentation:
- * Obsolete device documentation publically available from via.com.tw
+ * Obsolete device documentation publicly available from via.com.tw
* Current device documentation available under NDA only
*/
@@ -26,6 +26,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ide.h>
@@ -54,6 +55,11 @@
#define VIA_NO_UNMASK 0x08 /* Doesn't work with IRQ unmasking on */
#define VIA_BAD_ID 0x10 /* Has wrong vendor ID (0x1107) */
#define VIA_BAD_AST 0x20 /* Don't touch Address Setup Timing */
+#define VIA_SATA_PATA 0x80 /* SATA/PATA combined configuration */
+
+enum {
+ VIA_IDFLAG_SINGLE = (1 << 1), /* single channel controller */
+};
/*
* VIA SouthBridge chips.
@@ -67,10 +73,13 @@ static struct via_isa_bridge {
u8 udma_mask;
u8 flags;
} via_isa_bridges[] = {
- { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
- { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+ { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+ { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+ { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST | VIA_SATA_PATA },
+ { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
+ { "vt6415", PCI_DEVICE_ID_VIA_6415, 0x00, 0xff, ATA_UDMA6, VIA_BAD_AST },
{ "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
@@ -91,6 +100,7 @@ static struct via_isa_bridge {
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, 0x00, VIA_SET_FIFO },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK },
{ "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, 0x00, VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID },
+ { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, ATA_UDMA6, VIA_BAD_AST },
{ NULL }
};
@@ -136,30 +146,45 @@ static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing)
case ATA_UDMA4: t = timing->udma ? (0xe8 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x0f; break;
case ATA_UDMA5: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
case ATA_UDMA6: t = timing->udma ? (0xe0 | (clamp_val(timing->udma, 2, 9) - 2)) : 0x07; break;
- default: return;
}
- pci_write_config_byte(dev, VIA_UDMA_TIMING + (3 - dn), t);
+ /* Set UDMA unless device is not UDMA capable */
+ if (vdev->via_config->udma_mask) {
+ u8 udma_etc;
+
+ pci_read_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, &udma_etc);
+
+ /* clear transfer mode bit */
+ udma_etc &= ~0x20;
+
+ if (timing->udma) {
+ /* preserve 80-wire cable detection bit */
+ udma_etc &= 0x10;
+ udma_etc |= t;
+ }
+
+ pci_write_config_byte(dev, VIA_UDMA_TIMING + 3 - dn, udma_etc);
+ }
}
/**
* via_set_drive - configure transfer mode
+ * @hwif: port
* @drive: Drive to set up
- * @speed: desired speed
*
* via_set_drive() computes timing values configures the chipset to
* a desired transfer mode. It also can be called by upper layers.
*/
-static void via_set_drive(ide_drive_t *drive, const u8 speed)
+static void via_set_drive(ide_hwif_t *hwif, ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
ide_drive_t *peer = ide_get_pair_dev(drive);
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct via82cxxx_dev *vdev = host->host_priv;
struct ide_timing t, p;
unsigned int T, UT;
+ const u8 speed = drive->dma_mode;
T = 1000000000 / via_clock;
@@ -174,7 +199,7 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_compute(drive, speed, &t, T, UT);
if (peer) {
- ide_timing_compute(peer, peer->current_speed, &p, T, UT);
+ ide_timing_compute(peer, peer->pio_mode, &p, T, UT);
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
@@ -183,22 +208,24 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
/**
* via_set_pio_mode - set host controller for PIO mode
+ * @hwif: port
* @drive: drive
- * @pio: PIO mode number
*
* A callback from the upper layers for PIO-only tuning.
*/
-static void via_set_pio_mode(ide_drive_t *drive, const u8 pio)
+static void via_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
- via_set_drive(drive, XFER_PIO_0 + pio);
+ drive->dma_mode = drive->pio_mode;
+ via_set_drive(hwif, drive);
}
static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
{
struct via_isa_bridge *via_config;
- for (via_config = via_isa_bridges; via_config->id; via_config++)
+ for (via_config = via_isa_bridges;
+ via_config->id != PCI_DEVICE_ID_VIA_ANON; via_config++)
if ((*isa = pci_get_device(PCI_VENDOR_ID_VIA +
!!(via_config->flags & VIA_BAD_ID),
via_config->id, NULL))) {
@@ -361,6 +388,9 @@ static u8 via82cxxx_cable_detect(ide_hwif_t *hwif)
if (via_cable_override(pdev))
return ATA_CBL_PATA40_SHORT;
+ if ((vdev->via_config->flags & VIA_SATA_PATA) && hwif->channel == 0)
+ return ATA_CBL_SATA;
+
if ((vdev->via_80w >> hwif->channel) & 1)
return ATA_CBL_PATA80;
else
@@ -373,7 +403,7 @@ static const struct ide_port_ops via_port_ops = {
.cable_detect = via82cxxx_cable_detect,
};
-static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+static const struct ide_port_info via82cxxx_chipset = {
.name = DRV_NAME,
.init_chipset = init_chipset_via82cxxx,
.enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
@@ -386,7 +416,7 @@ static const struct ide_port_info via82cxxx_chipset __devinitdata = {
.mwdma_mask = ATA_MWDMA2,
};
-static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct pci_dev *isa = NULL;
struct via_isa_bridge *via_config;
@@ -401,11 +431,6 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
* Find the ISA bridge and check we know what it is.
*/
via_config = via_config_find(&isa);
- if (!via_config->id) {
- printk(KERN_WARNING DRV_NAME " %s: unknown chipset, skipping\n",
- pci_name(dev));
- return -ENODEV;
- }
/*
* Print the boot message.
@@ -435,10 +460,13 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
via_clock = 33333;
}
- if (idx == 0)
- d.host_flags |= IDE_HFLAG_NO_AUTODMA;
- else
+ if (idx == 1)
d.enablebits[1].reg = d.enablebits[0].reg = 0;
+ else
+ d.host_flags |= IDE_HFLAG_NO_AUTODMA;
+
+ if (idx == VIA_IDFLAG_SINGLE)
+ d.host_flags |= IDE_HFLAG_SINGLE;
if ((via_config->flags & VIA_NO_UNMASK) == 0)
d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
@@ -461,7 +489,7 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
return rc;
}
-static void __devexit via_remove(struct pci_dev *dev)
+static void via_remove(struct pci_dev *dev)
{
struct ide_host *host = pci_get_drvdata(dev);
struct via82cxxx_dev *vdev = host->host_priv;
@@ -474,7 +502,9 @@ static const struct pci_device_id via_pci_tbl[] = {
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_CX700_IDE), 0 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_VX855_IDE), VIA_IDFLAG_SINGLE },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6410), 1 },
+ { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_6415), 1 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_SATA_EIDE), 1 },
{ 0, },
};
@@ -484,7 +514,7 @@ static struct pci_driver via_pci_driver = {
.name = "VIA_IDE",
.id_table = via_pci_tbl,
.probe = via_init_one,
- .remove = __devexit_p(via_remove),
+ .remove = via_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
@@ -502,6 +532,6 @@ static void __exit via_ide_exit(void)
module_init(via_ide_init);
module_exit(via_ide_exit);
-MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick");
+MODULE_AUTHOR("Vojtech Pavlik, Bartlomiej Zolnierkiewicz, Michel Aubry, Jeff Garzik, Andre Hedrick");
MODULE_DESCRIPTION("PCI driver module for VIA IDE");
MODULE_LICENSE("GPL");