* [git pull] IDE updates part 3
@ 2009-01-06 17:12 Bartlomiej Zolnierkiewicz
0 siblings, 0 replies; 3+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-01-06 17:12 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, Stephen Rothwell, linux-ide, linux-kernel
Part three:
* Resurrect IT8172 IDE host driver.
(from Shane McDonald)
* Fix 32-bit I/O support for ATA-8 and ATA-1 devices.
(from Mario Schwalbe)
* Switch ide-cd over generic ATAPI support.
(from Borislav Petkov)
* New locking scheme (which is both simpler and more efficient) for hosts
with serialized ports and related cleanups.
* struct ide_dma_ops sanitization and related cleanups.
(from Sergei Shtylyov)
* Misc fixups/cleanups...
This should be the final part of IDE updates for 2.6.29 merge window
(I would like to thank all contributors!).
Linus, please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git/
to receive the following updates:
Documentation/ide/warm-plug-howto.txt | 5 +
drivers/ide/Kconfig | 7 +
drivers/ide/Makefile | 1 +
drivers/ide/aec62xx.c | 4 +-
drivers/ide/alim15x3.c | 10 +-
drivers/ide/amd74xx.c | 4 +-
drivers/ide/au1xxx-ide.c | 11 +-
drivers/ide/cmd640.c | 5 +-
drivers/ide/cmd64x.c | 23 +-
drivers/ide/cs5520.c | 2 +-
drivers/ide/cy82c693.c | 2 +-
drivers/ide/falconide.c | 1 -
drivers/ide/hpt366.c | 23 +-
drivers/ide/icside.c | 12 +-
drivers/ide/ide-acpi.c | 22 +-
drivers/ide/ide-atapi.c | 13 +-
drivers/ide/ide-cd.c | 118 +--------
drivers/ide/ide-cd.h | 34 ++--
drivers/ide/ide-disk.c | 4 +-
drivers/ide/ide-dma-sff.c | 63 +++--
drivers/ide/ide-dma.c | 2 +-
drivers/ide/ide-floppy.c | 2 +-
drivers/ide/ide-gd.c | 3 +-
drivers/ide/ide-gd.h | 10 +-
drivers/ide/ide-h8300.c | 1 -
drivers/ide/ide-io.c | 410 ++++++++++++++---------------
drivers/ide/ide-iops.c | 100 +++----
drivers/ide/ide-lib.c | 9 +-
drivers/ide/ide-park.c | 16 +-
drivers/ide/ide-pm.c | 8 +-
drivers/ide/ide-probe.c | 474 +++++++++++++++++----------------
drivers/ide/ide-proc.c | 23 +-
drivers/ide/ide-tape.c | 20 +-
drivers/ide/ide-taskfile.c | 14 +-
drivers/ide/ide.c | 187 +-------------
drivers/ide/it8172.c | 166 ++++++++++++
drivers/ide/it8213.c | 4 +-
drivers/ide/it821x.c | 13 +-
drivers/ide/ns87415.c | 14 +-
drivers/ide/palm_bk3710.c | 3 +-
drivers/ide/pdc202xx_new.c | 4 +-
drivers/ide/pdc202xx_old.c | 14 +-
drivers/ide/piix.c | 8 +-
drivers/ide/pmac.c | 7 +-
drivers/ide/q40ide.c | 1 -
drivers/ide/qd65xx.c | 7 +-
drivers/ide/qd65xx.h | 4 +-
drivers/ide/sc1200.c | 9 +-
drivers/ide/scc_pata.c | 33 ++--
drivers/ide/serverworks.c | 2 +-
drivers/ide/setup-pci.c | 12 +-
drivers/ide/sgiioc4.c | 15 +-
drivers/ide/siimage.c | 11 +-
drivers/ide/sis5513.c | 2 +-
drivers/ide/sl82c105.c | 5 +-
drivers/ide/slc90e66.c | 4 +-
drivers/ide/tc86c001.c | 17 +-
drivers/ide/triflex.c | 2 +-
drivers/ide/trm290.c | 10 +-
drivers/ide/tx4939ide.c | 23 +-
drivers/ide/umc8672.c | 13 +-
drivers/ide/via82cxxx.c | 2 +-
include/linux/ide.h | 171 +++++--------
include/linux/pci_ids.h | 1 +
64 files changed, 1036 insertions(+), 1184 deletions(-)
create mode 100644 drivers/ide/it8172.c
Bartlomiej Zolnierkiewicz (32):
ide: fix LOCKDEP warning
ide: fix setting nIEN on idle devices
ide: add ->cur_port to struct ide_host and use it for serialized hosts
ide: use per-port IRQ handlers
ide: remove hwgroup->hwif and {drive,hwif}->next
ide: use lock bitops for ports serialization (v2)
ide: merge ide_hwgroup_t with ide_hwif_t (v2)
ide: update ide_unregister() documentation
ide: move ide_init_port_data() and friends to ide-probe.c
ide: remove HWIF() macro
ide: remove local_irq_set() macro
ide: remove ide_pci_enablebit_t typedef
ide: remove 'byte' typedef
ide: remove ide_driver_t typedef
ide: unexport ide_wait_not_busy()
ide: remove ->error method from struct ide_driver
amd74xx: use ide_get_pair_dev() helper
cmd640: use ide_get_pair_dev() helper
cmd64x: use ide_get_pair_dev() helper
it821x: use ide_get_pair_dev() helper
ide: NUMA aware allocation of host and port structures
ide: dynamic allocation of device structures
ide: add port and host iterators
ide: make "paranoia" ->handler check in ide_intr() more strict
ide: use ide_pci_is_in_compatibility_mode() helper in setup-pci.c
ide: remove superfluous hwif variable assignment from ide_timer_expiry()
ide: struct ide_atapi_pc - remove unused fields and update documentation
ide: remove unused ide_hwif_t.sg_mapped field
ide: remove now redundant ->cur_dev checks
ide: fix ide_port_scan() to do ACPI setup after initializing request queues
ide: update warm-plug HOWTO
piix: sync ich_laptop[] with ata_piix.c
Borislav Petkov (3):
ide-cd: wait for DRQ to get set per default
ide-cd: start DMA before sending the actual packet command
ide-cd: convert to ide-atapi facilities
Mario Schwalbe (1):
ide: Fix drive's DWORD-IO handling
Sergei Shtylyov (4):
ide: don't set hwif->dma_ops in init_dma() method
ide: move read_sff_dma_status() method to 'struct ide_dma_ops'
ide-dma-sff: factor out ide_dma_sff_write_status()
scc_pata: make use of scc_dma_sff_read_status()
Shane McDonald (1):
Resurrect IT8172 IDE controller driver
diff --git a/Documentation/ide/warm-plug-howto.txt b/Documentation/ide/warm-plug-howto.txt
index d588546..98152bc 100644
--- a/Documentation/ide/warm-plug-howto.txt
+++ b/Documentation/ide/warm-plug-howto.txt
@@ -11,3 +11,8 @@ unplug old device(s) and plug new device(s)
# echo -n "1" > /sys/class/ide_port/idex/scan
done
+
+NOTE: please make sure that partitions are unmounted and that there are
+no other active references to devices before doing "delete_devices" step,
+also do not attempt "scan" step on devices currently in use -- otherwise
+results may be unpredictable and lead to data loss if you're unlucky
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 4ee85fc..3f95038 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -511,6 +511,13 @@ config BLK_DEV_PIIX
This allows the kernel to change PIO, DMA and UDMA speeds and to
configure the chip to optimum performance.
+config BLK_DEV_IT8172
+ tristate "IT8172 IDE support"
+ select BLK_DEV_IDEDMA_PCI
+ help
+ This driver adds support for the IDE controller on the
+ IT8172 System Controller.
+
config BLK_DEV_IT8213
tristate "IT8213 IDE support"
select BLK_DEV_IDEDMA_PCI
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 4107289..c2b9c93 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o
obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
+obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o
obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o
obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o
diff --git a/drivers/ide/aec62xx.c b/drivers/ide/aec62xx.c
index 4142c69..4485b9c 100644
--- a/drivers/ide/aec62xx.c
+++ b/drivers/ide/aec62xx.c
@@ -83,7 +83,7 @@ static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entr
static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -111,7 +111,7 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed)
static void aec6260_set_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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;
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index 45d2356..66f4308 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -68,7 +68,7 @@ static struct pci_dev *isa_dev;
static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -150,7 +150,7 @@ static u8 ali_udma_filter(ide_drive_t *drive)
static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 speed1 = speed;
u8 unit = drive->dn & 1;
@@ -198,7 +198,7 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
static int ali15x3_dma_setup(ide_drive_t *drive)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
- if (rq_data_dir(drive->hwif->hwgroup->rq))
+ if (rq_data_dir(drive->hwif->rq))
return 1; /* try PIO instead of DMA */
}
return ide_dma_setup(drive);
@@ -490,8 +490,6 @@ static int __devinit init_dma_ali15x3(ide_hwif_t *hwif,
if (ide_allocate_dma_engine(hwif))
return -1;
- hwif->dma_ops = &sff_dma_ops;
-
return 0;
}
@@ -511,6 +509,7 @@ static const struct ide_dma_ops ali_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_port_info ali15x3_chipset __devinitdata = {
@@ -519,6 +518,7 @@ static const struct ide_port_info ali15x3_chipset __devinitdata = {
.init_hwif = init_hwif_ali15x3,
.init_dma = init_dma_ali15x3,
.port_ops = &ali_port_ops,
+ .dma_ops = &sff_dma_ops,
.pio_mask = ATA_PIO5,
.swdma_mask = ATA_SWDMA2,
.mwdma_mask = ATA_MWDMA2,
diff --git a/drivers/ide/amd74xx.c b/drivers/ide/amd74xx.c
index c6bcd30..69660a4 100644
--- a/drivers/ide/amd74xx.c
+++ b/drivers/ide/amd74xx.c
@@ -82,7 +82,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
- ide_drive_t *peer = hwif->drives + (~drive->dn & 1);
+ ide_drive_t *peer = ide_get_pair_dev(drive);
struct ide_timing t, p;
int T, UT;
u8 udma_mask = hwif->ultra_mask;
@@ -92,7 +92,7 @@ static void amd_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_compute(drive, speed, &t, T, UT);
- if (peer->dev_flags & IDE_DFLAG_PRESENT) {
+ if (peer) {
ide_timing_compute(peer, peer->current_speed, &p, T, UT);
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 0ec8fd1..79a2dfe 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -212,8 +212,8 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
static int auide_build_dmatable(ide_drive_t *drive)
{
int i, iswrite, count = 0;
- ide_hwif_t *hwif = HWIF(drive);
- struct request *rq = HWGROUP(drive)->rq;
+ ide_hwif_t *hwif = drive->hwif;
+ struct request *rq = hwif->rq;
_auide_hwif *ahwif = &auide_hwif;
struct scatterlist *sg;
@@ -286,7 +286,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
if (hwif->sg_nents) {
ide_destroy_dmatable(drive);
@@ -309,8 +309,8 @@ static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
}
static int auide_dma_setup(ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
+{
+ struct request *rq = drive->hwif->rq;
if (!auide_build_dmatable(drive)) {
ide_map_sg(drive, rq);
@@ -502,7 +502,6 @@ static const struct ide_tp_ops au1xxx_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c
index e430664..8890276 100644
--- a/drivers/ide/cmd640.c
+++ b/drivers/ide/cmd640.c
@@ -467,11 +467,10 @@ static void program_drive_counts(ide_drive_t *drive, unsigned int index)
* so we merge the timings, using the slowest value for each timing.
*/
if (index > 1) {
- ide_hwif_t *hwif = drive->hwif;
- ide_drive_t *peer = &hwif->drives[!(drive->dn & 1)];
+ ide_drive_t *peer = ide_get_pair_dev(drive);
unsigned int mate = index ^ 1;
- if (peer->dev_flags & IDE_DFLAG_PRESENT) {
+ if (peer) {
if (setup_count < setup_counts[mate])
setup_count = setup_counts[mate];
if (active_count < active_counts[mate])
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 3623bf0..2f9688d 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -115,7 +115,7 @@ static void program_cycle_times (ide_drive_t *drive, int cycle_time, int active_
*/
static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(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);
unsigned int cycle_time;
@@ -138,10 +138,12 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio)
* the slowest address setup timing ourselves.
*/
if (hwif->channel) {
- ide_drive_t *drives = hwif->drives;
+ ide_drive_t *pair = ide_get_pair_dev(drive);
drive->drive_data = setup_count;
- setup_count = max(drives[0].drive_data, drives[1].drive_data);
+
+ if (pair)
+ setup_count = max_t(u8, setup_count, pair->drive_data);
}
if (setup_count > 5) /* shouldn't actually happen... */
@@ -180,7 +182,7 @@ static void cmd64x_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -226,7 +228,7 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
static int cmd648_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long base = hwif->dma_base - (hwif->channel * 8);
int err = ide_dma_end(drive);
u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
@@ -242,7 +244,7 @@ static int cmd648_dma_end(ide_drive_t *drive)
static int cmd64x_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ 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 :
@@ -259,7 +261,7 @@ static int cmd64x_dma_end(ide_drive_t *drive)
static int cmd648_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long base = hwif->dma_base - (hwif->channel * 8);
u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 :
MRDMODE_INTR_CH0;
@@ -282,7 +284,7 @@ static int cmd648_dma_test_irq(ide_drive_t *drive)
static int cmd64x_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ 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 :
@@ -313,7 +315,7 @@ static int cmd64x_dma_test_irq(ide_drive_t *drive)
static int cmd646_1_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
drive->waiting_for_dma = 0;
@@ -383,6 +385,7 @@ static const struct ide_dma_ops cmd64x_dma_ops = {
.dma_test_irq = cmd64x_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd646_rev1_dma_ops = {
@@ -394,6 +397,7 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd648_dma_ops = {
@@ -405,6 +409,7 @@ static const struct ide_dma_ops cmd648_dma_ops = {
.dma_test_irq = cmd648_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c
index 5efb467..d003bec 100644
--- a/drivers/ide/cs5520.c
+++ b/drivers/ide/cs5520.c
@@ -59,7 +59,7 @@ static struct pio_clocks cs5520_pio_clocks[]={
static void cs5520_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *pdev = to_pci_dev(hwif->dev);
int controller = drive->dn > 1 ? 1 : 0;
diff --git a/drivers/ide/cy82c693.c b/drivers/ide/cy82c693.c
index d37baf8..74fc540 100644
--- a/drivers/ide/cy82c693.c
+++ b/drivers/ide/cy82c693.c
@@ -203,7 +203,7 @@ static void cy82c693_set_dma_mode(ide_drive_t *drive, const u8 mode)
static void cy82c693_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
pio_clocks_t pclk;
unsigned int addrCtrl;
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index 39d500d..a5ba820 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -70,7 +70,6 @@ static const struct ide_tp_ops falconide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index b18e10d..3eb9b5c 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -626,7 +626,7 @@ static struct hpt_info *hpt3xx_get_info(struct device *dev)
static u8 hpt3xx_udma_filter(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
u8 mask = hwif->ultra_mask;
@@ -665,7 +665,7 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
switch (info->chip_type) {
@@ -743,7 +743,7 @@ static void hpt3xx_quirkproc(ide_drive_t *drive)
static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
{
- ide_hwif_t *hwif = HWIF(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);
@@ -788,7 +788,7 @@ static void hpt366_dma_lost_irq(ide_drive_t *drive)
static void hpt370_clear_engine(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
pci_write_config_byte(dev, hwif->select_data, 0x37);
@@ -797,7 +797,7 @@ static void hpt370_clear_engine(ide_drive_t *drive)
static void hpt370_irq_timeout(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u16 bfifo = 0;
u8 dma_cmd;
@@ -822,7 +822,7 @@ static void hpt370_dma_start(ide_drive_t *drive)
static int hpt370_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
if (dma_stat & 0x01) {
@@ -844,7 +844,7 @@ static void hpt370_dma_timeout(ide_drive_t *drive)
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u16 bfifo = 0;
u8 dma_stat;
@@ -865,7 +865,7 @@ static int hpt374_dma_test_irq(ide_drive_t *drive)
static int hpt374_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 mcr = 0, mcr_addr = hwif->select_data;
u8 bwsr = 0, mask = hwif->channel ? 0x02 : 0x01;
@@ -927,7 +927,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(HWIF(drive), rq_data_dir(rq) ? 0x23 : 0x21);
+ hpt3xxn_set_clock(drive->hwif, rq_data_dir(rq) ? 0x23 : 0x21);
}
/**
@@ -1349,8 +1349,6 @@ static int __devinit init_dma_hpt366(ide_hwif_t *hwif,
if (ide_allocate_dma_engine(hwif))
return -1;
- hwif->dma_ops = &sff_dma_ops;
-
return 0;
}
@@ -1426,6 +1424,7 @@ static const struct ide_dma_ops hpt37x_dma_ops = {
.dma_test_irq = hpt374_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt370_dma_ops = {
@@ -1437,6 +1436,7 @@ static const struct ide_dma_ops hpt370_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = hpt370_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt36x_dma_ops = {
@@ -1448,6 +1448,7 @@ static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = hpt366_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 81f70ca..97a35c6 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -166,7 +166,7 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {
*/
static void icside_maskproc(ide_drive_t *drive, int mask)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
unsigned long flags;
@@ -284,7 +284,7 @@ static void icside_dma_host_set(ide_drive_t *drive, int on)
static int icside_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
drive->waiting_for_dma = 0;
@@ -299,7 +299,7 @@ static int icside_dma_end(ide_drive_t *drive)
static void icside_dma_start(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
/* We can not enable DMA on both channels simultaneously. */
@@ -309,10 +309,10 @@ static void icside_dma_start(ide_drive_t *drive)
static int icside_dma_setup(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
unsigned int dma_mode;
if (rq_data_dir(rq))
@@ -362,7 +362,7 @@ static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
static int icside_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index fd4a364..2f9e941 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -218,7 +218,7 @@ static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif)
*/
static acpi_handle ide_acpi_drive_get_handle(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
int port;
acpi_handle drive_handle;
@@ -263,7 +263,7 @@ static int do_drive_get_GTF(ide_drive_t *drive,
acpi_status status;
struct acpi_buffer output;
union acpi_object *out_obj;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct device *dev = hwif->gendev.parent;
int err = -ENODEV;
int port;
@@ -641,7 +641,8 @@ void ide_acpi_push_timing(ide_hwif_t *hwif)
*/
void ide_acpi_set_state(ide_hwif_t *hwif, int on)
{
- int unit;
+ ide_drive_t *drive;
+ int i;
if (ide_noacpi || ide_noacpi_psx)
return;
@@ -655,9 +656,8 @@ void ide_acpi_set_state(ide_hwif_t *hwif, int on)
/* 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);
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
+ ide_port_for_each_dev(i, drive, hwif) {
if (!drive->acpidata->obj_handle)
drive->acpidata->obj_handle = ide_acpi_drive_get_handle(drive);
@@ -711,15 +711,13 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
* for both drives, regardless whether they are connected
* or not.
*/
- hwif->drives[0].acpidata = &hwif->acpidata->master;
- hwif->drives[1].acpidata = &hwif->acpidata->slave;
+ hwif->devices[0]->acpidata = &hwif->acpidata->master;
+ hwif->devices[1]->acpidata = &hwif->acpidata->slave;
/*
* Send IDENTIFY for each drive
*/
- for (i = 0; i < MAX_DRIVES; i++) {
- drive = &hwif->drives[i];
-
+ ide_port_for_each_dev(i, drive, hwif) {
memset(drive->acpidata, 0, sizeof(*drive->acpidata));
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
@@ -744,9 +742,7 @@ void ide_acpi_port_init_devices(ide_hwif_t *hwif)
ide_acpi_get_timing(hwif);
ide_acpi_push_timing(hwif);
- for (i = 0; i < MAX_DRIVES; i++) {
- drive = &hwif->drives[i];
-
+ ide_port_for_each_dev(i, drive, hwif) {
if (drive->dev_flags & IDE_DFLAG_PRESENT)
/* Execute ACPI startup code */
ide_acpi_exec_tfs(drive);
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index e8688c0..e96c012 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -243,7 +243,7 @@ EXPORT_SYMBOL_GPL(ide_retry_pc);
int ide_cd_expiry(ide_drive_t *drive)
{
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = drive->hwif->rq;
unsigned long wait = 0;
debug_log("%s: rq->cmd[0]: 0x%x\n", __func__, rq->cmd[0]);
@@ -294,7 +294,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
unsigned int timeout, temp;
@@ -491,7 +491,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
{
struct ide_atapi_pc *uninitialized_var(pc);
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
ide_expiry_t *expiry;
unsigned int timeout;
int cmd_len;
@@ -549,7 +549,10 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
/* Set the interrupt routine */
- ide_set_handler(drive, ide_pc_intr, timeout, expiry);
+ ide_set_handler(drive,
+ (dev_is_idecd(drive) ? drive->irq_handler
+ : ide_pc_intr),
+ timeout, expiry);
/* Begin DMA, if necessary */
if (dev_is_idecd(drive)) {
@@ -580,7 +583,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
if (dev_is_idecd(drive)) {
tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
- bcount = ide_cd_get_xferlen(hwif->hwgroup->rq);
+ bcount = ide_cd_get_xferlen(hwif->rq);
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 1a7410f..cae6937 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -239,7 +239,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
static void cdrom_end_request(ide_drive_t *drive, int uptodate)
{
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = drive->hwif->rq;
int nsectors = rq->hard_cur_sectors;
ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, "
@@ -306,8 +306,7 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
- struct request *rq = hwgroup->rq;
+ struct request *rq = hwif->rq;
int stat, err, sense_key;
/* check for errors */
@@ -502,7 +501,7 @@ end_request:
blkdev_dequeue_request(rq);
spin_unlock_irqrestore(q->queue_lock, flags);
- hwgroup->rq = NULL;
+ hwif->rq = NULL;
cdrom_queue_request_sense(drive, rq->sense, rq);
} else
@@ -511,106 +510,6 @@ end_request:
return 1;
}
-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *);
-static ide_startstop_t cdrom_newpc_intr(ide_drive_t *);
-
-/*
- * Set up the device registers for transferring a packet command on DEV,
- * expecting to later transfer XFERLEN bytes. HANDLER is the routine
- * which actually transfers the command to the drive. If this is a
- * drq_interrupt device, this routine will arrange for HANDLER to be
- * called when the interrupt from the drive arrives. Otherwise, HANDLER
- * will be called immediately after the drive is prepared for the transfer.
- */
-static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
- int xferlen;
-
- xferlen = ide_cd_get_xferlen(rq);
-
- ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen);
-
- /* FIXME: for Virtual DMA we must check harder */
- if (drive->dma)
- drive->dma = !hwif->dma_ops->dma_setup(drive);
-
- /* set up the controller registers */
- ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL,
- xferlen, drive->dma);
-
- if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
- /* waiting for CDB interrupt, not DMA yet. */
- if (drive->dma)
- drive->waiting_for_dma = 0;
-
- /* packet command */
- ide_execute_command(drive, ATA_CMD_PACKET,
- cdrom_transfer_packet_command,
- ATAPI_WAIT_PC, ide_cd_expiry);
- return ide_started;
- } else {
- ide_execute_pkt_cmd(drive);
-
- return cdrom_transfer_packet_command(drive);
- }
-}
-
-/*
- * Send a packet command to DRIVE described by CMD_BUF and CMD_LEN. The device
- * registers must have already been prepared by cdrom_start_packet_command.
- * HANDLER is the interrupt handler to call when the command completes or
- * there's data ready.
- */
-#define ATAPI_MIN_CDB_BYTES 12
-static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
- int cmd_len;
- ide_startstop_t startstop;
-
- ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__);
-
- if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
- /*
- * Here we should have been called after receiving an interrupt
- * from the device. DRQ should how be set.
- */
-
- /* check for errors */
- if (cdrom_decode_status(drive, ATA_DRQ, NULL))
- return ide_stopped;
-
- /* ok, next interrupt will be DMA interrupt */
- if (drive->dma)
- drive->waiting_for_dma = 1;
- } else {
- /* otherwise, we must wait for DRQ to get set */
- if (ide_wait_stat(&startstop, drive, ATA_DRQ,
- ATA_BUSY, WAIT_READY))
- return startstop;
- }
-
- /* arm the interrupt handler */
- ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, ide_cd_expiry);
-
- /* ATAPI commands get padded out to 12 bytes minimum */
- cmd_len = COMMAND_SIZE(rq->cmd[0]);
- if (cmd_len < ATAPI_MIN_CDB_BYTES)
- cmd_len = ATAPI_MIN_CDB_BYTES;
-
- /* send the command to the device */
- hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
- /* start the DMA if need be */
- if (drive->dma)
- hwif->dma_ops->dma_start(drive);
-
- return ide_started;
-}
-
/*
* Check the contents of the interrupt reason register from the cdrom
* and attempt to recover if there are problems. Returns 0 if everything's
@@ -854,8 +753,7 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq)
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
- struct request *rq = hwgroup->rq;
+ struct request *rq = hwif->rq;
xfer_func_t *xferfunc;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, stat, thislen, uptodate = 0;
@@ -1061,7 +959,7 @@ end_request:
if (blk_end_request(rq, 0, dlen))
BUG();
- hwgroup->rq = NULL;
+ hwif->rq = NULL;
} else {
if (!uptodate)
rq->cmd_flags |= REQ_FAILED;
@@ -1183,7 +1081,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
return ide_stopped;
}
- return cdrom_start_packet_command(drive);
+ return ide_issue_pc(drive);
}
/*
@@ -1916,7 +1814,7 @@ static void ide_cd_release(struct kref *kref)
static int ide_cd_probe(ide_drive_t *);
-static ide_driver_t ide_cdrom_driver = {
+static struct ide_driver ide_cdrom_driver = {
.gen_driver = {
.owner = THIS_MODULE,
.name = "ide-cdrom",
@@ -1927,7 +1825,6 @@ static ide_driver_t ide_cdrom_driver = {
.version = IDECD_VERSION,
.do_request = ide_cd_do_request,
.end_request = ide_end_request,
- .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_cd_proc_entries,
.proc_devsets = ide_cd_proc_devsets,
@@ -2082,6 +1979,7 @@ static int ide_cd_probe(ide_drive_t *drive)
}
drive->debug_mask = debug_mask;
+ drive->irq_handler = cdrom_newpc_intr;
info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
if (info == NULL) {
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index bf676b2..ac40d6c 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -33,33 +33,33 @@
/* Structure of a MSF cdrom address. */
struct atapi_msf {
- byte reserved;
- byte minute;
- byte second;
- byte frame;
+ u8 reserved;
+ u8 minute;
+ u8 second;
+ u8 frame;
};
/* Space to hold the disk TOC. */
#define MAX_TRACKS 99
struct atapi_toc_header {
unsigned short toc_length;
- byte first_track;
- byte last_track;
+ u8 first_track;
+ u8 last_track;
};
struct atapi_toc_entry {
- byte reserved1;
+ u8 reserved1;
#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 adr : 4;
- __u8 control : 4;
+ u8 adr : 4;
+ u8 control : 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 control : 4;
- __u8 adr : 4;
+ u8 control : 4;
+ u8 adr : 4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
- byte track;
- byte reserved2;
+ u8 track;
+ u8 reserved2;
union {
unsigned lba;
struct atapi_msf msf;
@@ -77,10 +77,10 @@ struct atapi_toc {
/* Extra per-device info for cdrom drives. */
struct cdrom_info {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
+ ide_drive_t *drive;
+ struct ide_driver *driver;
+ struct gendisk *disk;
+ struct kref kref;
/* Buffer for table of contents. NULL if we haven't allocated
a TOC buffer for this device yet. */
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index eb9fac4..4088a62 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -89,7 +89,7 @@ static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
sector_t block)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u16 nsectors = (u16)rq->nr_sectors;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
@@ -187,7 +187,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
sector_t block)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED);
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index f6d2d44..123d393 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -50,6 +50,27 @@ int config_drive_for_dma(ide_drive_t *drive)
return 0;
}
+u8 ide_dma_sff_read_status(ide_hwif_t *hwif)
+{
+ unsigned long addr = hwif->dma_base + ATA_DMA_STATUS;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ return readb((void __iomem *)addr);
+ else
+ return inb(addr);
+}
+EXPORT_SYMBOL_GPL(ide_dma_sff_read_status);
+
+static void ide_dma_sff_write_status(ide_hwif_t *hwif, u8 val)
+{
+ unsigned long addr = hwif->dma_base + ATA_DMA_STATUS;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(val, (void __iomem *)addr);
+ else
+ outb(val, addr);
+}
+
/**
* ide_dma_host_set - Enable/disable DMA on a host
* @drive: drive to control
@@ -62,18 +83,14 @@ void ide_dma_host_set(ide_drive_t *drive, int on)
{
ide_hwif_t *hwif = drive->hwif;
u8 unit = drive->dn & 1;
- u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
if (on)
dma_stat |= (1 << (5 + unit));
else
dma_stat &= ~(1 << (5 + unit));
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- writeb(dma_stat,
- (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
- else
- outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
+ ide_dma_sff_write_status(hwif, dma_stat);
}
EXPORT_SYMBOL_GPL(ide_dma_host_set);
@@ -175,7 +192,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
int ide_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
u8 dma_stat;
@@ -187,7 +204,7 @@ int ide_dma_setup(ide_drive_t *drive)
}
/* PRD table */
- if (hwif->host_flags & IDE_HFLAG_MMIO)
+ if (mmio)
writel(hwif->dmatable_dma,
(void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
else
@@ -200,15 +217,10 @@ int ide_dma_setup(ide_drive_t *drive)
outb(reading, hwif->dma_base + ATA_DMA_CMD);
/* read DMA status for INTR & ERROR flags */
- dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* clear INTR & ERROR flags */
- if (mmio)
- writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
- (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
- else
- outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
- hwif->dma_base + ATA_DMA_STATUS);
+ ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
drive->waiting_for_dma = 1;
return 0;
@@ -232,7 +244,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
static int dma_timer_expiry(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n",
drive->name, __func__, dma_stat);
@@ -240,7 +252,7 @@ static int dma_timer_expiry(ide_drive_t *drive)
if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */
return WAIT_CMD;
- hwif->hwgroup->expiry = NULL; /* one free ride for now */
+ hwif->expiry = NULL; /* one free ride for now */
if (dma_stat & ATA_DMA_ERR) /* ERROR */
return -1;
@@ -289,13 +301,12 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
int ide_dma_end(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
u8 dma_stat = 0, dma_cmd = 0, mask;
drive->waiting_for_dma = 0;
/* stop DMA */
- if (mmio) {
+ if (hwif->host_flags & IDE_HFLAG_MMIO) {
dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
writeb(dma_cmd & ~ATA_DMA_START,
(void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
@@ -305,15 +316,10 @@ int ide_dma_end(ide_drive_t *drive)
}
/* get DMA status */
- dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
- if (mmio)
- /* clear the INTR & ERROR bits */
- writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
- (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
- else
- outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
- hwif->dma_base + ATA_DMA_STATUS);
+ /* clear INTR & ERROR bits */
+ ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
/* purge DMA mappings */
ide_destroy_dmatable(drive);
@@ -331,7 +337,7 @@ EXPORT_SYMBOL_GPL(ide_dma_end);
int ide_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
return (dma_stat & ATA_DMA_INTR) ? 1 : 0;
}
@@ -346,5 +352,6 @@ const struct ide_dma_ops sff_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
EXPORT_SYMBOL_GPL(sff_dma_ops);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index fffd117..72ebab0 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -96,7 +96,7 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive)
if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
if (!dma_stat) {
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
task_end_request(drive, rq, stat);
return ide_stopped;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 0a48e2d..3eab1c6 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -71,7 +71,7 @@
static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
{
struct ide_disk_obj *floppy = drive->driver_data;
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = drive->hwif->rq;
int error;
ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index b8078b3..7857b20 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -149,7 +149,7 @@ static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
return drive->disk_ops->end_request(drive, uptodate, nrsecs);
}
-static ide_driver_t ide_gd_driver = {
+static struct ide_driver ide_gd_driver = {
.gen_driver = {
.owner = THIS_MODULE,
.name = "ide-gd",
@@ -162,7 +162,6 @@ static ide_driver_t ide_gd_driver = {
.version = IDE_GD_VERSION,
.do_request = ide_gd_do_request,
.end_request = ide_gd_end_request,
- .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_disk_proc_entries,
.proc_devsets = ide_disk_proc_devsets,
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
index 7d3d101..a86779f 100644
--- a/drivers/ide/ide-gd.h
+++ b/drivers/ide/ide-gd.h
@@ -14,11 +14,11 @@
#endif
struct ide_disk_obj {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
- unsigned int openers; /* protected by BKL for now */
+ ide_drive_t *drive;
+ struct ide_driver *driver;
+ struct gendisk *disk;
+ struct kref kref;
+ unsigned int openers; /* protected by BKL for now */
/* Last failed packet command */
struct ide_atapi_pc *failed_pc;
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index e2cdd2e..9270d32 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -159,7 +159,6 @@ static const struct ide_tp_ops h8300_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 1c36a8e..cc16331 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -88,7 +88,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
ret = 0;
if (ret == 0 && dequeue)
- drive->hwif->hwgroup->rq = NULL;
+ drive->hwif->rq = NULL;
return ret;
}
@@ -107,7 +107,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
{
unsigned int nr_bytes = nr_sectors << 9;
- struct request *rq = drive->hwif->hwgroup->rq;
+ struct request *rq = drive->hwif->rq;
if (!nr_bytes) {
if (blk_pc_request(rq))
@@ -160,8 +160,8 @@ EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
- struct request *rq = hwgroup->rq;
+ ide_hwif_t *hwif = drive->hwif;
+ struct request *rq = hwif->rq;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
ide_task_t *task = (ide_task_t *)rq->special;
@@ -186,7 +186,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
return;
}
- hwgroup->rq = NULL;
+ hwif->rq = NULL;
rq->errors = err;
@@ -199,9 +199,9 @@ EXPORT_SYMBOL(ide_end_drive_cmd);
static void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
if (rq->rq_disk) {
- ide_driver_t *drv;
+ struct ide_driver *drv;
- drv = *(ide_driver_t **)rq->rq_disk->private_data;
+ drv = *(struct ide_driver **)rq->rq_disk->private_data;
drv->end_request(drive, 0, 0);
} else
ide_end_request(drive, 0, 0);
@@ -291,7 +291,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u
return ide_stopped;
}
-ide_startstop_t
+static ide_startstop_t
__ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
{
if (drive->media == ide_disk)
@@ -299,8 +299,6 @@ __ide_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err)
return ide_atapi_error(drive, rq, stat, err);
}
-EXPORT_SYMBOL_GPL(__ide_error);
-
/**
* ide_error - handle an error on the IDE
* @drive: drive the error occurred on
@@ -321,7 +319,8 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
err = ide_dump_status(drive, msg, stat);
- if ((rq = HWGROUP(drive)->rq) == NULL)
+ rq = drive->hwif->rq;
+ if (rq == NULL)
return ide_stopped;
/* retry only "normal" I/O: */
@@ -331,15 +330,8 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat)
return ide_stopped;
}
- if (rq->rq_disk) {
- ide_driver_t *drv;
-
- drv = *(ide_driver_t **)rq->rq_disk->private_data;
- return drv->error(drive, rq, stat, err);
- } else
- return __ide_error(drive, rq, stat, err);
+ return __ide_error(drive, rq, stat, err);
}
-
EXPORT_SYMBOL_GPL(ide_error);
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
@@ -462,7 +454,7 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
struct request *rq)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
ide_task_t *task = rq->special;
if (task) {
@@ -586,7 +578,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
#ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n",
- HWIF(drive)->name, (unsigned long) rq);
+ drive->hwif->name, (unsigned long) rq);
#endif
/* bail early if we've exceeded max_failures */
@@ -605,7 +597,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
return startstop;
}
if (!drive->special.all) {
- ide_driver_t *drv;
+ struct ide_driver *drv;
/*
* We reset the drive so we need to issue a SETFEATURES.
@@ -638,7 +630,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
*/
return ide_special_rq(drive, rq);
- drv = *(ide_driver_t **)rq->rq_disk->private_data;
+ drv = *(struct ide_driver **)rq->rq_disk->private_data;
return drv->do_request(drive, rq, rq->sector);
}
@@ -654,7 +646,7 @@ kill_rq:
* @timeout: time to stall for (jiffies)
*
* ide_stall_queue() can be used by a drive to give excess bandwidth back
- * to the hwgroup by sleeping for timeout jiffies.
+ * to the port by sleeping for timeout jiffies.
*/
void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
@@ -666,45 +658,53 @@ void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
}
EXPORT_SYMBOL(ide_stall_queue);
+static inline int ide_lock_port(ide_hwif_t *hwif)
+{
+ if (hwif->busy)
+ return 1;
+
+ hwif->busy = 1;
+
+ return 0;
+}
+
+static inline void ide_unlock_port(ide_hwif_t *hwif)
+{
+ hwif->busy = 0;
+}
+
+static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
+{
+ int rc = 0;
+
+ if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+ rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
+ if (rc == 0) {
+ /* for atari only */
+ ide_get_lock(ide_intr, hwif);
+ }
+ }
+ return rc;
+}
+
+static inline void ide_unlock_host(struct ide_host *host)
+{
+ if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+ /* for atari only */
+ ide_release_lock();
+ clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
+ }
+}
+
/*
- * Issue a new request to a drive from hwgroup
- *
- * A hwgroup is a serialized group of IDE interfaces. Usually there is
- * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640)
- * may have both interfaces in a single hwgroup to "serialize" access.
- * Or possibly multiple ISA interfaces can share a common IRQ by being grouped
- * together into one hwgroup for serialized access.
- *
- * Note also that several hwgroups can end up sharing a single IRQ,
- * possibly along with many other devices. This is especially common in
- * PCI-based systems with off-board IDE controller cards.
- *
- * The IDE driver uses a per-hwgroup lock to protect the hwgroup->busy flag.
- *
- * The first thread into the driver for a particular hwgroup sets the
- * hwgroup->busy flag to indicate that this hwgroup is now active,
- * and then initiates processing of the top request from the request queue.
- *
- * Other threads attempting entry notice the busy setting, and will simply
- * queue their new requests and exit immediately. Note that hwgroup->busy
- * remains set even when the driver is merely awaiting the next interrupt.
- * Thus, the meaning is "this hwgroup is busy processing a request".
- *
- * When processing of a request completes, the completing thread or IRQ-handler
- * will start the next request from the queue. If no more work remains,
- * the driver will clear the hwgroup->busy flag and exit.
- *
- * The per-hwgroup spinlock is used to protect all access to the
- * hwgroup->busy flag, but is otherwise not needed for most processing in
- * the driver. This makes the driver much more friendlier to shared IRQs
- * than previous designs, while remaining 100% (?) SMP safe and capable.
+ * Issue a new request to a device.
*/
void do_ide_request(struct request_queue *q)
{
ide_drive_t *drive = q->queuedata;
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
- struct request *rq;
+ struct ide_host *host = hwif->host;
+ struct request *rq = NULL;
ide_startstop_t startstop;
/*
@@ -721,32 +721,40 @@ void do_ide_request(struct request_queue *q)
blk_remove_plug(q);
spin_unlock_irq(q->queue_lock);
- spin_lock_irq(&hwgroup->lock);
- if (!ide_lock_hwgroup(hwgroup)) {
+ if (ide_lock_host(host, hwif))
+ goto plug_device_2;
+
+ spin_lock_irq(&hwif->lock);
+
+ if (!ide_lock_port(hwif)) {
+ ide_hwif_t *prev_port;
repeat:
- hwgroup->rq = NULL;
+ prev_port = hwif->host->cur_port;
+ hwif->rq = NULL;
if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
if (time_before(drive->sleep, jiffies)) {
- ide_unlock_hwgroup(hwgroup);
+ ide_unlock_port(hwif);
goto plug_device;
}
}
- if (hwif != hwgroup->hwif) {
+ if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
+ hwif != prev_port) {
/*
- * set nIEN for previous hwif, drives in the
+ * set nIEN for previous port, drives in the
* quirk_list may not like intr setups/cleanups
*/
- if (drive->quirk_list == 0)
- hwif->tp_ops->set_irq(hwif, 0);
+ if (prev_port && prev_port->cur_dev->quirk_list == 0)
+ prev_port->tp_ops->set_irq(prev_port, 0);
+
+ hwif->host->cur_port = hwif;
}
- hwgroup->hwif = hwif;
- hwgroup->drive = drive;
+ hwif->cur_dev = drive;
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
spin_lock_irq(q->queue_lock);
/*
* we know that the queue isn't empty, but this can happen
@@ -754,10 +762,10 @@ repeat:
*/
rq = elv_next_request(drive->queue);
spin_unlock_irq(q->queue_lock);
- spin_lock_irq(&hwgroup->lock);
+ spin_lock_irq(&hwif->lock);
if (!rq) {
- ide_unlock_hwgroup(hwgroup);
+ ide_unlock_port(hwif);
goto out;
}
@@ -778,27 +786,31 @@ repeat:
blk_pm_request(rq) == 0 &&
(rq->cmd_flags & REQ_PREEMPT) == 0) {
/* there should be no pending command at this point */
- ide_unlock_hwgroup(hwgroup);
+ ide_unlock_port(hwif);
goto plug_device;
}
- hwgroup->rq = rq;
+ hwif->rq = rq;
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
startstop = start_request(drive, rq);
- spin_lock_irq(&hwgroup->lock);
+ spin_lock_irq(&hwif->lock);
if (startstop == ide_stopped)
goto repeat;
} else
goto plug_device;
out:
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
+ if (rq == NULL)
+ ide_unlock_host(host);
spin_lock_irq(q->queue_lock);
return;
plug_device:
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
+ ide_unlock_host(host);
+plug_device_2:
spin_lock_irq(q->queue_lock);
if (!elv_queue_empty(q))
@@ -806,13 +818,13 @@ plug_device:
}
/*
- * un-busy the hwgroup etc, and clear any pending DMA status. we want to
+ * un-busy the port etc, and clear any pending DMA status. we want to
* retry the current request in pio mode instead of risking tossing it
* all away
*/
static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct request *rq;
ide_startstop_t ret = ide_stopped;
@@ -840,15 +852,14 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
ide_dma_off_quietly(drive);
/*
- * un-busy drive etc (hwgroup->busy is cleared on return) and
- * make sure request is sane
+ * un-busy drive etc and make sure request is sane
*/
- rq = HWGROUP(drive)->rq;
+ rq = hwif->rq;
if (!rq)
goto out;
- HWGROUP(drive)->rq = NULL;
+ hwif->rq = NULL;
rq->errors = 0;
@@ -876,7 +887,7 @@ static void ide_plug_device(ide_drive_t *drive)
/**
* ide_timer_expiry - handle lack of an IDE interrupt
- * @data: timer callback magic (hwgroup)
+ * @data: timer callback magic (hwif)
*
* An IDE command has timed out before the expected drive return
* occurred. At this point we attempt to clean up the current
@@ -890,18 +901,18 @@ static void ide_plug_device(ide_drive_t *drive)
void ide_timer_expiry (unsigned long data)
{
- ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
+ ide_hwif_t *hwif = (ide_hwif_t *)data;
ide_drive_t *uninitialized_var(drive);
ide_handler_t *handler;
- ide_expiry_t *expiry;
unsigned long flags;
unsigned long wait = -1;
int plug_device = 0;
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
- if (((handler = hwgroup->handler) == NULL) ||
- (hwgroup->req_gen != hwgroup->req_gen_timer)) {
+ handler = hwif->handler;
+
+ if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) {
/*
* Either a marginal timeout occurred
* (got the interrupt just as timer expired),
@@ -909,72 +920,68 @@ void ide_timer_expiry (unsigned long data)
* Either way, we don't really want to complain about anything.
*/
} else {
- drive = hwgroup->drive;
- if (!drive) {
- printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n");
- hwgroup->handler = NULL;
- } else {
- ide_hwif_t *hwif;
- ide_startstop_t startstop = ide_stopped;
-
- if ((expiry = hwgroup->expiry) != NULL) {
- /* continue */
- if ((wait = expiry(drive)) > 0) {
- /* reset timer */
- hwgroup->timer.expires = jiffies + wait;
- hwgroup->req_gen_timer = hwgroup->req_gen;
- add_timer(&hwgroup->timer);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
- return;
- }
- }
- hwgroup->handler = NULL;
- /*
- * We need to simulate a real interrupt when invoking
- * the handler() function, which means we need to
- * globally mask the specific IRQ:
- */
- spin_unlock(&hwgroup->lock);
- hwif = HWIF(drive);
- /* disable_irq_nosync ?? */
- disable_irq(hwif->irq);
- /* local CPU only,
- * as if we were handling an interrupt */
- local_irq_disable();
- if (hwgroup->polling) {
- startstop = handler(drive);
- } else if (drive_is_ready(drive)) {
- if (drive->waiting_for_dma)
- hwif->dma_ops->dma_lost_irq(drive);
- (void)ide_ack_intr(hwif);
- printk(KERN_WARNING "%s: lost interrupt\n", drive->name);
- startstop = handler(drive);
- } else {
- if (drive->waiting_for_dma) {
- startstop = ide_dma_timeout_retry(drive, wait);
- } else
- startstop =
- ide_error(drive, "irq timeout",
- hwif->tp_ops->read_status(hwif));
- }
- spin_lock_irq(&hwgroup->lock);
- enable_irq(hwif->irq);
- if (startstop == ide_stopped) {
- ide_unlock_hwgroup(hwgroup);
- plug_device = 1;
+ ide_expiry_t *expiry = hwif->expiry;
+ ide_startstop_t startstop = ide_stopped;
+
+ drive = hwif->cur_dev;
+
+ if (expiry) {
+ wait = expiry(drive);
+ if (wait > 0) { /* continue */
+ /* reset timer */
+ hwif->timer.expires = jiffies + wait;
+ hwif->req_gen_timer = hwif->req_gen;
+ add_timer(&hwif->timer);
+ spin_unlock_irqrestore(&hwif->lock, flags);
+ return;
}
}
+ hwif->handler = NULL;
+ /*
+ * We need to simulate a real interrupt when invoking
+ * the handler() function, which means we need to
+ * globally mask the specific IRQ:
+ */
+ spin_unlock(&hwif->lock);
+ /* disable_irq_nosync ?? */
+ disable_irq(hwif->irq);
+ /* local CPU only, as if we were handling an interrupt */
+ local_irq_disable();
+ if (hwif->polling) {
+ startstop = handler(drive);
+ } else if (drive_is_ready(drive)) {
+ if (drive->waiting_for_dma)
+ hwif->dma_ops->dma_lost_irq(drive);
+ (void)ide_ack_intr(hwif);
+ printk(KERN_WARNING "%s: lost interrupt\n",
+ drive->name);
+ startstop = handler(drive);
+ } else {
+ if (drive->waiting_for_dma)
+ startstop = ide_dma_timeout_retry(drive, wait);
+ else
+ startstop = ide_error(drive, "irq timeout",
+ hwif->tp_ops->read_status(hwif));
+ }
+ spin_lock_irq(&hwif->lock);
+ enable_irq(hwif->irq);
+ if (startstop == ide_stopped) {
+ ide_unlock_port(hwif);
+ plug_device = 1;
+ }
}
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
- if (plug_device)
+ if (plug_device) {
+ ide_unlock_host(hwif->host);
ide_plug_device(drive);
+ }
}
/**
* unexpected_intr - handle an unexpected IDE interrupt
* @irq: interrupt line
- * @hwgroup: hwgroup being processed
+ * @hwif: port being processed
*
* There's nothing really useful we can do with an unexpected interrupt,
* other than reading the status register (to clear it), and logging it.
@@ -998,52 +1005,38 @@ void ide_timer_expiry (unsigned long data)
* before completing the issuance of any new drive command, so we will not
* be accidentally invoked as a result of any valid command completion
* interrupt.
- *
- * Note that we must walk the entire hwgroup here. We know which hwif
- * is doing the current command, but we don't know which hwif burped
- * mysteriously.
*/
-
-static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
-{
- u8 stat;
- ide_hwif_t *hwif = hwgroup->hwif;
- /*
- * handle the unexpected interrupt
- */
- do {
- if (hwif->irq == irq) {
- stat = hwif->tp_ops->read_status(hwif);
-
- if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
- /* Try to not flood the console with msgs */
- static unsigned long last_msgtime, count;
- ++count;
- if (time_after(jiffies, last_msgtime + HZ)) {
- last_msgtime = jiffies;
- printk(KERN_ERR "%s%s: unexpected interrupt, "
- "status=0x%02x, count=%ld\n",
- hwif->name,
- (hwif->next==hwgroup->hwif) ? "" : "(?)", stat, count);
- }
- }
+static void unexpected_intr(int irq, ide_hwif_t *hwif)
+{
+ u8 stat = hwif->tp_ops->read_status(hwif);
+
+ if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
+ /* Try to not flood the console with msgs */
+ static unsigned long last_msgtime, count;
+ ++count;
+
+ if (time_after(jiffies, last_msgtime + HZ)) {
+ last_msgtime = jiffies;
+ printk(KERN_ERR "%s: unexpected interrupt, "
+ "status=0x%02x, count=%ld\n",
+ hwif->name, stat, count);
}
- } while ((hwif = hwif->next) != hwgroup->hwif);
+ }
}
/**
* ide_intr - default IDE interrupt handler
* @irq: interrupt number
- * @dev_id: hwif group
+ * @dev_id: hwif
* @regs: unused weirdness from the kernel irq layer
*
* This is the default IRQ handler for the IDE layer. You should
* not need to override it. If you do be aware it is subtle in
* places
*
- * hwgroup->hwif is the interface in the group currently performing
- * a command. hwgroup->drive is the drive and hwgroup->handler is
+ * hwif is the interface in the group currently performing
+ * a command. hwif->cur_dev is the drive and hwif->handler is
* the IRQ handler to call. As we issue a command the handlers
* step through multiple states, reassigning the handler to the
* next step in the process. Unlike a smart SCSI controller IDE
@@ -1054,26 +1047,32 @@ static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
*
* The handler eventually returns ide_stopped to indicate the
* request completed. At this point we issue the next request
- * on the hwgroup and the process begins again.
+ * on the port and the process begins again.
*/
-
+
irqreturn_t ide_intr (int irq, void *dev_id)
{
- unsigned long flags;
- ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id;
- ide_hwif_t *hwif = hwgroup->hwif;
+ ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
ide_drive_t *uninitialized_var(drive);
ide_handler_t *handler;
+ unsigned long flags;
ide_startstop_t startstop;
irqreturn_t irq_ret = IRQ_NONE;
int plug_device = 0;
- spin_lock_irqsave(&hwgroup->lock, flags);
+ if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
+ if (hwif != hwif->host->cur_port)
+ goto out_early;
+ }
+
+ spin_lock_irqsave(&hwif->lock, flags);
if (!ide_ack_intr(hwif))
goto out;
- if ((handler = hwgroup->handler) == NULL || hwgroup->polling) {
+ handler = hwif->handler;
+
+ if (handler == NULL || hwif->polling) {
/*
* Not expecting an interrupt from this drive.
* That means this could be:
@@ -1097,7 +1096,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
* Probably not a shared PCI interrupt,
* so we can safely try to do something about it:
*/
- unexpected_intr(irq, hwgroup);
+ unexpected_intr(irq, hwif);
#ifdef CONFIG_BLK_DEV_IDEPCI
} else {
/*
@@ -1110,16 +1109,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
goto out;
}
- drive = hwgroup->drive;
- if (!drive) {
- /*
- * This should NEVER happen, and there isn't much
- * we could do about it here.
- *
- * [Note - this can occur if the drive is hot unplugged]
- */
- goto out_handled;
- }
+ drive = hwif->cur_dev;
if (!drive_is_ready(drive))
/*
@@ -1131,10 +1121,10 @@ irqreturn_t ide_intr (int irq, void *dev_id)
*/
goto out;
- hwgroup->handler = NULL;
- hwgroup->req_gen++;
- del_timer(&hwgroup->timer);
- spin_unlock(&hwgroup->lock);
+ hwif->handler = NULL;
+ hwif->req_gen++;
+ del_timer(&hwif->timer);
+ spin_unlock(&hwif->lock);
if (hwif->port_ops && hwif->port_ops->clear_irq)
hwif->port_ops->clear_irq(drive);
@@ -1145,7 +1135,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
/* service this interrupt, may set handler for next interrupt */
startstop = handler(drive);
- spin_lock_irq(&hwgroup->lock);
+ spin_lock_irq(&hwif->lock);
/*
* Note that handler() may have set things up for another
* interrupt to occur soon, but it cannot happen until
@@ -1154,20 +1144,18 @@ irqreturn_t ide_intr (int irq, void *dev_id)
* won't allow another of the same (on any CPU) until we return.
*/
if (startstop == ide_stopped) {
- if (hwgroup->handler == NULL) { /* paranoia */
- ide_unlock_hwgroup(hwgroup);
- plug_device = 1;
- } else
- printk(KERN_ERR "%s: %s: huh? expected NULL handler "
- "on exit\n", __func__, drive->name);
+ BUG_ON(hwif->handler);
+ ide_unlock_port(hwif);
+ plug_device = 1;
}
-out_handled:
irq_ret = IRQ_HANDLED;
out:
- spin_unlock_irqrestore(&hwgroup->lock, flags);
-
- if (plug_device)
+ spin_unlock_irqrestore(&hwif->lock, flags);
+out_early:
+ if (plug_device) {
+ ide_unlock_host(hwif->host);
ide_plug_device(drive);
+ }
return irq_ret;
}
@@ -1189,15 +1177,13 @@ out:
void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
struct request_queue *q = drive->queue;
unsigned long flags;
- hwgroup->rq = NULL;
+ drive->hwif->rq = NULL;
spin_lock_irqsave(q->queue_lock, flags);
__elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0);
- blk_start_queueing(q);
spin_unlock_irqrestore(q->queue_lock, flags);
}
EXPORT_SYMBOL(ide_do_drive_cmd);
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index ad8bd65..e728cfe 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -105,15 +105,6 @@ u8 ide_read_altstatus(ide_hwif_t *hwif)
}
EXPORT_SYMBOL_GPL(ide_read_altstatus);
-u8 ide_read_sff_dma_status(ide_hwif_t *hwif)
-{
- if (hwif->host_flags & IDE_HFLAG_MMIO)
- return readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
- else
- return inb(hwif->dma_base + ATA_DMA_STATUS);
-}
-EXPORT_SYMBOL_GPL(ide_read_sff_dma_status);
-
void ide_set_irq(ide_hwif_t *hwif, int on)
{
u8 ctl = ATA_DEVCTL_OBS;
@@ -388,7 +379,6 @@ const struct ide_tp_ops default_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
@@ -451,7 +441,7 @@ EXPORT_SYMBOL(ide_fixstring);
*/
int drive_is_ready (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u8 stat = 0;
if (drive->waiting_for_dma)
@@ -503,7 +493,8 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti
stat = tp_ops->read_status(hwif);
if (stat & ATA_BUSY) {
- local_irq_set(flags);
+ local_irq_save(flags);
+ local_irq_enable_in_hardirq();
timeout += jiffies;
while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) {
if (time_after(jiffies, timeout)) {
@@ -822,25 +813,25 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
static void __ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
unsigned int timeout, ide_expiry_t *expiry)
{
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
-
- BUG_ON(hwgroup->handler);
- hwgroup->handler = handler;
- hwgroup->expiry = expiry;
- hwgroup->timer.expires = jiffies + timeout;
- hwgroup->req_gen_timer = hwgroup->req_gen;
- add_timer(&hwgroup->timer);
+ ide_hwif_t *hwif = drive->hwif;
+
+ BUG_ON(hwif->handler);
+ hwif->handler = handler;
+ hwif->expiry = expiry;
+ hwif->timer.expires = jiffies + timeout;
+ hwif->req_gen_timer = hwif->req_gen;
+ add_timer(&hwif->timer);
}
void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
unsigned int timeout, ide_expiry_t *expiry)
{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
+ ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
__ide_set_handler(drive, handler, timeout, expiry);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
}
EXPORT_SYMBOL(ide_set_handler);
@@ -863,10 +854,9 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
unsigned timeout, ide_expiry_t *expiry)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
unsigned long flags;
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
__ide_set_handler(drive, handler, timeout, expiry);
hwif->tp_ops->exec_command(hwif, cmd);
/*
@@ -876,26 +866,25 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
* FIXME: we could skip this delay with care on non shared devices
*/
ndelay(400);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
}
EXPORT_SYMBOL(ide_execute_command);
void ide_execute_pkt_cmd(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
unsigned long flags;
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET);
ndelay(400);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
}
EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
{
- struct request *rq = drive->hwif->hwgroup->rq;
+ struct request *rq = drive->hwif->rq;
if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
ide_end_request(drive, err ? err : 1, 0);
@@ -913,7 +902,6 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int);
static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
u8 stat;
SELECT_DRIVE(drive);
@@ -923,20 +911,20 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive)
if (OK_STAT(stat, 0, ATA_BUSY))
printk("%s: ATAPI reset complete\n", drive->name);
else {
- if (time_before(jiffies, hwgroup->poll_timeout)) {
+ if (time_before(jiffies, hwif->poll_timeout)) {
ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
/* continue polling */
return ide_started;
}
/* end of polling */
- hwgroup->polling = 0;
+ hwif->polling = 0;
printk("%s: ATAPI reset timed-out, status=0x%02x\n",
drive->name, stat);
/* do it the old fashioned way */
return do_reset1(drive, 1);
}
/* done polling */
- hwgroup->polling = 0;
+ hwif->polling = 0;
ide_complete_drive_reset(drive, 0);
return ide_stopped;
}
@@ -968,8 +956,7 @@ static void ide_reset_report_error(ide_hwif_t *hwif, u8 err)
*/
static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
{
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
const struct ide_port_ops *port_ops = hwif->port_ops;
u8 tmp;
int err = 0;
@@ -986,7 +973,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
tmp = hwif->tp_ops->read_status(hwif);
if (!OK_STAT(tmp, 0, ATA_BUSY)) {
- if (time_before(jiffies, hwgroup->poll_timeout)) {
+ if (time_before(jiffies, hwif->poll_timeout)) {
ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
/* continue polling */
return ide_started;
@@ -1007,7 +994,7 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
}
}
out:
- hwgroup->polling = 0; /* done polling */
+ hwif->polling = 0; /* done polling */
ide_complete_drive_reset(drive, err);
return ide_stopped;
}
@@ -1081,18 +1068,18 @@ static void pre_reset(ide_drive_t *drive)
static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
struct ide_io_ports *io_ports = &hwif->io_ports;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
const struct ide_port_ops *port_ops;
+ ide_drive_t *tdrive;
unsigned long flags, timeout;
- unsigned int unit;
+ int i;
DEFINE_WAIT(wait);
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
/* We must not reset with running handlers */
- BUG_ON(hwgroup->handler != NULL);
+ BUG_ON(hwif->handler != NULL);
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk && !do_not_try_atapi) {
@@ -1101,10 +1088,10 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
udelay (20);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
ndelay(400);
- hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwgroup->polling = 1;
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
__ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
return ide_started;
}
@@ -1114,9 +1101,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE);
timeout = jiffies;
- for (unit = 0; unit < MAX_DRIVES; unit++) {
- ide_drive_t *tdrive = &hwif->drives[unit];
-
+ ide_port_for_each_dev(i, tdrive, hwif) {
if (tdrive->dev_flags & IDE_DFLAG_PRESENT &&
tdrive->dev_flags & IDE_DFLAG_PARKED &&
time_after(tdrive->sleep, timeout))
@@ -1127,9 +1112,9 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
if (time_before_eq(timeout, now))
break;
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
timeout = schedule_timeout_uninterruptible(timeout - now);
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
} while (timeout);
finish_wait(&ide_park_wq, &wait);
@@ -1137,11 +1122,11 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
* First, reset any device state data we were maintaining
* for any of the drives on this interface.
*/
- for (unit = 0; unit < MAX_DRIVES; ++unit)
- pre_reset(&hwif->drives[unit]);
+ ide_port_for_each_dev(i, tdrive, hwif)
+ pre_reset(tdrive);
if (io_ports->ctl_addr == 0) {
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
ide_complete_drive_reset(drive, -ENXIO);
return ide_stopped;
}
@@ -1164,8 +1149,8 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
tp_ops->set_irq(hwif, drive->quirk_list == 2);
/* more than enough time */
udelay(10);
- hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- hwgroup->polling = 1;
+ hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
+ hwif->polling = 1;
__ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
/*
@@ -1177,7 +1162,7 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
if (port_ops && port_ops->resetproc)
port_ops->resetproc(drive);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
return ide_started;
}
@@ -1221,6 +1206,3 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
}
return -EBUSY;
}
-
-EXPORT_SYMBOL_GPL(ide_wait_not_busy);
-
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 9f6e33d..09526a0 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -273,7 +273,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
static void ide_dump_opcode(ide_drive_t *drive)
{
- struct request *rq = drive->hwif->hwgroup->rq;
+ struct request *rq = drive->hwif->rq;
ide_task_t *task = NULL;
if (!rq)
@@ -346,10 +346,13 @@ static void ide_dump_ata_error(ide_drive_t *drive, u8 err)
printk(KERN_CONT "}");
if ((err & (ATA_BBK | ATA_ABORTED)) == ATA_BBK ||
(err & (ATA_UNC | ATA_IDNF | ATA_AMNF))) {
+ struct request *rq = drive->hwif->rq;
+
ide_dump_sector(drive);
- if (HWGROUP(drive) && HWGROUP(drive)->rq)
+
+ if (rq)
printk(KERN_CONT ", sector=%llu",
- (unsigned long long)HWGROUP(drive)->rq->sector);
+ (unsigned long long)rq->sector);
}
printk(KERN_CONT "\n");
}
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 678454a..c875a95 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -7,22 +7,22 @@ DECLARE_WAIT_QUEUE_HEAD(ide_park_wq);
static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
+ ide_hwif_t *hwif = drive->hwif;
struct request_queue *q = drive->queue;
struct request *rq;
int rc;
timeout += jiffies;
- spin_lock_irq(&hwgroup->lock);
+ spin_lock_irq(&hwif->lock);
if (drive->dev_flags & IDE_DFLAG_PARKED) {
int reset_timer = time_before(timeout, drive->sleep);
int start_queue = 0;
drive->sleep = timeout;
wake_up_all(&ide_park_wq);
- if (reset_timer && del_timer(&hwgroup->timer))
+ if (reset_timer && del_timer(&hwif->timer))
start_queue = 1;
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
if (start_queue) {
spin_lock_irq(q->queue_lock);
@@ -31,7 +31,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
}
return;
}
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
rq = blk_get_request(q, READ, __GFP_WAIT);
rq->cmd[0] = REQ_PARK_HEADS;
@@ -64,21 +64,21 @@ ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
+ ide_hwif_t *hwif = drive->hwif;
unsigned long now;
unsigned int msecs;
if (drive->dev_flags & IDE_DFLAG_NO_UNLOAD)
return -EOPNOTSUPP;
- spin_lock_irq(&hwgroup->lock);
+ spin_lock_irq(&hwif->lock);
now = jiffies;
if (drive->dev_flags & IDE_DFLAG_PARKED &&
time_after(drive->sleep, now))
msecs = jiffies_to_msecs(drive->sleep - now);
else
msecs = 0;
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
return snprintf(buf, 20, "%u\n", msecs);
}
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 8282c60..4b3bf6a 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -5,7 +5,7 @@
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_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
ide_task_t args;
@@ -39,7 +39,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
int generic_ide_resume(struct device *dev)
{
ide_drive_t *drive = dev->driver_data, *pair = ide_get_pair_dev(drive);
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
ide_task_t args;
@@ -67,7 +67,7 @@ int generic_ide_resume(struct device *dev)
blk_put_request(rq);
if (err == 0 && dev->driver) {
- ide_driver_t *drv = to_ide_driver(dev->driver);
+ struct ide_driver *drv = to_ide_driver(dev->driver);
if (drv->resume)
drv->resume(drive);
@@ -194,7 +194,7 @@ void ide_complete_pm_request(ide_drive_t *drive, struct request *rq)
}
spin_unlock_irqrestore(q->queue_lock, flags);
- drive->hwif->hwgroup->rq = NULL;
+ drive->hwif->rq = NULL;
if (blk_end_request(rq, 0, 0))
BUG();
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index c5adb7b..0ccbb44 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -189,7 +189,7 @@ static void ide_classify_atapi_dev(ide_drive_t *drive)
static void do_identify(ide_drive_t *drive, u8 cmd)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u16 *id = drive->id;
char *m = (char *)&id[ATA_ID_PROD];
unsigned long flags;
@@ -266,7 +266,7 @@ err_misc:
static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int use_altstatus = 0, rc;
@@ -341,7 +341,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
static int try_to_identify (ide_drive_t *drive, u8 cmd)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int retval;
int autoprobe = 0;
@@ -438,7 +438,7 @@ static u8 ide_read_device(ide_drive_t *drive)
static int do_probe (ide_drive_t *drive, u8 cmd)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
int rc;
u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
@@ -463,7 +463,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if (ide_read_device(drive) != drive->select && present == 0) {
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(&hwif->drives[0]);
+ SELECT_DRIVE(hwif->devices[0]);
/* allow ATA_BUSY to assert & clear */
msleep(50);
}
@@ -509,7 +509,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
}
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(&hwif->drives[0]);
+ SELECT_DRIVE(hwif->devices[0]);
msleep(50);
/* ensure drive irq is clear */
(void)tp_ops->read_status(hwif);
@@ -522,7 +522,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
*/
static void enable_nest (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u8 stat;
@@ -697,7 +697,8 @@ out:
static int ide_port_wait_ready(ide_hwif_t *hwif)
{
- int unit, rc;
+ ide_drive_t *drive;
+ int i, rc;
printk(KERN_DEBUG "Probing IDE interface %s...\n", hwif->name);
@@ -714,9 +715,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
return rc;
/* Now make sure both master & slave are ready */
- for (unit = 0; unit < MAX_DRIVES; unit++) {
- ide_drive_t *drive = &hwif->drives[unit];
-
+ ide_port_for_each_dev(i, drive, hwif) {
/* Ignore disks that we will not probe for later. */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
(drive->dev_flags & IDE_DFLAG_PRESENT)) {
@@ -732,8 +731,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
}
out:
/* Exit function with master reselected (let's be sane) */
- if (unit)
- SELECT_DRIVE(&hwif->drives[0]);
+ if (i)
+ SELECT_DRIVE(hwif->devices[0]);
return rc;
}
@@ -749,7 +748,7 @@ out:
void ide_undecoded_slave(ide_drive_t *dev1)
{
- ide_drive_t *dev0 = &dev1->hwif->drives[0];
+ ide_drive_t *dev0 = dev1->hwif->devices[0];
if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0)
return;
@@ -778,14 +777,15 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
static int ide_probe_port(ide_hwif_t *hwif)
{
+ ide_drive_t *drive;
unsigned long flags;
unsigned int irqd;
- int unit, rc = -ENODEV;
+ int i, rc = -ENODEV;
BUG_ON(hwif->present);
- if ((hwif->drives[0].dev_flags & IDE_DFLAG_NOPROBE) &&
- (hwif->drives[1].dev_flags & IDE_DFLAG_NOPROBE))
+ if ((hwif->devices[0]->dev_flags & IDE_DFLAG_NOPROBE) &&
+ (hwif->devices[1]->dev_flags & IDE_DFLAG_NOPROBE))
return -EACCES;
/*
@@ -796,7 +796,8 @@ static int ide_probe_port(ide_hwif_t *hwif)
if (irqd)
disable_irq(hwif->irq);
- local_irq_set(flags);
+ local_irq_save(flags);
+ local_irq_enable_in_hardirq();
if (ide_port_wait_ready(hwif) == -EBUSY)
printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
@@ -805,9 +806,7 @@ static int ide_probe_port(ide_hwif_t *hwif)
* Second drive should only exist if first drive was found,
* but a lot of cdrom drives are configured as single slaves.
*/
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
-
+ ide_port_for_each_dev(i, drive, hwif) {
(void) probe_for_drive(drive);
if (drive->dev_flags & IDE_DFLAG_PRESENT)
rc = 0;
@@ -828,20 +827,17 @@ static int ide_probe_port(ide_hwif_t *hwif)
static void ide_port_tune_devices(ide_hwif_t *hwif)
{
const struct ide_port_ops *port_ops = hwif->port_ops;
- int unit;
-
- for (unit = 0; unit < MAX_DRIVES; unit++) {
- ide_drive_t *drive = &hwif->drives[unit];
+ ide_drive_t *drive;
+ int i;
+ ide_port_for_each_dev(i, drive, hwif) {
if (drive->dev_flags & IDE_DFLAG_PRESENT) {
if (port_ops && port_ops->quirkproc)
port_ops->quirkproc(drive);
}
}
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
-
+ ide_port_for_each_dev(i, drive, hwif) {
if (drive->dev_flags & IDE_DFLAG_PRESENT) {
ide_set_max_pio(drive);
@@ -852,11 +848,8 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
}
}
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
-
- if ((hwif->host_flags & IDE_HFLAG_NO_IO_32BIT) ||
- drive->id[ATA_ID_DWORD_IO])
+ ide_port_for_each_dev(i, drive, hwif) {
+ if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
else
drive->dev_flags &= ~IDE_DFLAG_NO_IO_32BIT;
@@ -869,7 +862,7 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
static int ide_init_queue(ide_drive_t *drive)
{
struct request_queue *q;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
int max_sectors = 256;
int max_sg_entries = PRD_ENTRIES;
@@ -918,36 +911,19 @@ static int ide_init_queue(ide_drive_t *drive)
return 0;
}
-static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
-
- spin_lock_irq(&hwgroup->lock);
- if (!hwgroup->drive) {
- /* first drive for hwgroup. */
- drive->next = drive;
- hwgroup->drive = drive;
- hwgroup->hwif = HWIF(hwgroup->drive);
- } else {
- drive->next = hwgroup->drive->next;
- hwgroup->drive->next = drive;
- }
- spin_unlock_irq(&hwgroup->lock);
-}
+static DEFINE_MUTEX(ide_cfg_mtx);
/*
* For any present drive:
* - allocate the block device queue
- * - link drive into the hwgroup
*/
static int ide_port_setup_devices(ide_hwif_t *hwif)
{
+ ide_drive_t *drive;
int i, j = 0;
mutex_lock(&ide_cfg_mtx);
- for (i = 0; i < MAX_DRIVES; i++) {
- ide_drive_t *drive = &hwif->drives[i];
-
+ ide_port_for_each_dev(i, drive, hwif) {
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
continue;
@@ -961,139 +937,39 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
}
j++;
-
- ide_add_drive_to_hwgroup(drive);
}
mutex_unlock(&ide_cfg_mtx);
return j;
}
-static ide_hwif_t *ide_ports[MAX_HWIFS];
-
-void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
-{
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
-
- ide_ports[hwif->index] = NULL;
-
- spin_lock_irq(&hwgroup->lock);
- /*
- * Remove us from the hwgroup, and free
- * the hwgroup if we were the only member
- */
- if (hwif->next == hwif) {
- BUG_ON(hwgroup->hwif != hwif);
- kfree(hwgroup);
- } else {
- /* There is another interface in hwgroup.
- * Unlink us, and set hwgroup->drive and ->hwif to
- * something sane.
- */
- ide_hwif_t *g = hwgroup->hwif;
-
- while (g->next != hwif)
- g = g->next;
- g->next = hwif->next;
- if (hwgroup->hwif == hwif) {
- /* Chose a random hwif for hwgroup->hwif.
- * It's guaranteed that there are no drives
- * left in the hwgroup.
- */
- BUG_ON(hwgroup->drive != NULL);
- hwgroup->hwif = g;
- }
- BUG_ON(hwgroup->hwif == hwif);
- }
- spin_unlock_irq(&hwgroup->lock);
-}
-
/*
- * This routine sets up the irq for an ide interface, and creates a new
- * hwgroup for the irq/hwif if none was previously assigned.
- *
- * Much of the code is for correctly detecting/handling irq sharing
- * and irq serialization situations. This is somewhat complex because
- * it handles static as well as dynamic (PCMCIA) IDE interfaces.
+ * This routine sets up the IRQ for an IDE interface.
*/
static int init_irq (ide_hwif_t *hwif)
{
struct ide_io_ports *io_ports = &hwif->io_ports;
- unsigned int index;
- ide_hwgroup_t *hwgroup;
- ide_hwif_t *match = NULL;
+ int sa = 0;
mutex_lock(&ide_cfg_mtx);
- hwif->hwgroup = NULL;
+ spin_lock_init(&hwif->lock);
- for (index = 0; index < MAX_HWIFS; index++) {
- ide_hwif_t *h = ide_ports[index];
+ init_timer(&hwif->timer);
+ hwif->timer.function = &ide_timer_expiry;
+ hwif->timer.data = (unsigned long)hwif;
- if (h && h->hwgroup) { /* scan only initialized ports */
- if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
- if (hwif->host == h->host)
- match = h;
- }
- }
- }
-
- /*
- * If we are still without a hwgroup, then form a new one
- */
- if (match) {
- hwgroup = match->hwgroup;
- hwif->hwgroup = hwgroup;
- /*
- * Link us into the hwgroup.
- * This must be done early, do ensure that unexpected_intr
- * can find the hwif and prevent irq storms.
- * No drives are attached to the new hwif, choose_drive
- * can't do anything stupid (yet).
- * Add ourself as the 2nd entry to the hwgroup->hwif
- * linked list, the first entry is the hwif that owns
- * hwgroup->handler - do not change that.
- */
- spin_lock_irq(&hwgroup->lock);
- hwif->next = hwgroup->hwif->next;
- hwgroup->hwif->next = hwif;
- BUG_ON(hwif->next == hwif);
- spin_unlock_irq(&hwgroup->lock);
- } else {
- hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO,
- hwif_to_node(hwif));
- if (hwgroup == NULL)
- goto out_up;
-
- spin_lock_init(&hwgroup->lock);
-
- hwif->hwgroup = hwgroup;
- hwgroup->hwif = hwif->next = hwif;
-
- init_timer(&hwgroup->timer);
- hwgroup->timer.function = &ide_timer_expiry;
- hwgroup->timer.data = (unsigned long) hwgroup;
- }
-
- ide_ports[hwif->index] = hwif;
-
- /*
- * Allocate the irq, if not already obtained for another hwif
- */
- if (!match || match->irq != hwif->irq) {
- int sa = 0;
#if defined(__mc68000__)
- sa = IRQF_SHARED;
+ sa = IRQF_SHARED;
#endif /* __mc68000__ */
- if (hwif->chipset == ide_pci)
- sa = IRQF_SHARED;
+ if (hwif->chipset == ide_pci)
+ sa = IRQF_SHARED;
- if (io_ports->ctl_addr)
- hwif->tp_ops->set_irq(hwif, 1);
+ if (io_ports->ctl_addr)
+ hwif->tp_ops->set_irq(hwif, 1);
- if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
- goto out_unlink;
- }
+ if (request_irq(hwif->irq, &ide_intr, sa, hwif->name, hwif))
+ goto out_up;
if (!hwif->rqsize) {
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
@@ -1111,14 +987,12 @@ static int init_irq (ide_hwif_t *hwif)
printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name,
io_ports->data_addr, hwif->irq);
#endif /* __mc68000__ */
- if (match)
- printk(KERN_CONT " (serialized with %s)", match->name);
+ if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE)
+ printk(KERN_CONT " (serialized)");
printk(KERN_CONT "\n");
mutex_unlock(&ide_cfg_mtx);
return 0;
-out_unlink:
- ide_remove_port_from_hwgroup(hwif);
out_up:
mutex_unlock(&ide_cfg_mtx);
return 1;
@@ -1134,7 +1008,7 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data)
{
ide_hwif_t *hwif = data;
int unit = *part >> PARTN_BITS;
- ide_drive_t *drive = &hwif->drives[unit];
+ ide_drive_t *drive = hwif->devices[unit];
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
return NULL;
@@ -1196,47 +1070,23 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
EXPORT_SYMBOL_GPL(ide_init_disk);
-static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
-
- if (drive == drive->next) {
- /* special case: last drive from hwgroup. */
- BUG_ON(hwgroup->drive != drive);
- hwgroup->drive = NULL;
- } else {
- ide_drive_t *walk;
-
- walk = hwgroup->drive;
- while (walk->next != drive)
- walk = walk->next;
- walk->next = drive->next;
- if (hwgroup->drive == drive) {
- hwgroup->drive = drive->next;
- hwgroup->hwif = hwgroup->drive->hwif;
- }
- }
- BUG_ON(hwgroup->drive == drive);
-}
-
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
- ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
+ ide_hwif_t *hwif = drive->hwif;
ide_proc_unregister_device(drive);
- spin_lock_irq(&hwgroup->lock);
- ide_remove_drive_from_hwgroup(drive);
+ spin_lock_irq(&hwif->lock);
kfree(drive->id);
drive->id = NULL;
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
/* Messed up locking ... */
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
blk_cleanup_queue(drive->queue);
- spin_lock_irq(&hwgroup->lock);
+ spin_lock_irq(&hwif->lock);
drive->queue = NULL;
- spin_unlock_irq(&hwgroup->lock);
+ spin_unlock_irq(&hwif->lock);
complete(&drive->gendev_rel_comp);
}
@@ -1302,10 +1152,10 @@ out:
static void hwif_register_devices(ide_hwif_t *hwif)
{
+ ide_drive_t *drive;
unsigned int i;
- for (i = 0; i < MAX_DRIVES; i++) {
- ide_drive_t *drive = &hwif->drives[i];
+ ide_port_for_each_dev(i, drive, hwif) {
struct device *dev = &drive->gendev;
int ret;
@@ -1328,11 +1178,10 @@ static void hwif_register_devices(ide_hwif_t *hwif)
static void ide_port_init_devices(ide_hwif_t *hwif)
{
const struct ide_port_ops *port_ops = hwif->port_ops;
+ ide_drive_t *drive;
int i;
- for (i = 0; i < MAX_DRIVES; i++) {
- ide_drive_t *drive = &hwif->drives[i];
-
+ ide_port_for_each_dev(i, drive, hwif) {
drive->dn = i + hwif->channel * 2;
if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
@@ -1380,6 +1229,8 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
int rc;
+ hwif->dma_ops = d->dma_ops;
+
if (d->init_dma)
rc = d->init_dma(hwif, d);
else
@@ -1387,12 +1238,13 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (rc < 0) {
printk(KERN_INFO "%s: DMA disabled\n", hwif->name);
+
+ hwif->dma_ops = NULL;
hwif->dma_base = 0;
hwif->swdma_mask = 0;
hwif->mwdma_mask = 0;
hwif->ultra_mask = 0;
- } else if (d->dma_ops)
- hwif->dma_ops = d->dma_ops;
+ }
}
if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
@@ -1417,6 +1269,66 @@ static void ide_port_cable_detect(ide_hwif_t *hwif)
}
}
+static const u8 ide_hwif_to_major[] =
+ { IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR,
+ IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR };
+
+static void ide_port_init_devices_data(ide_hwif_t *hwif)
+{
+ ide_drive_t *drive;
+ int i;
+
+ ide_port_for_each_dev(i, drive, hwif) {
+ u8 j = (hwif->index * MAX_DRIVES) + i;
+
+ memset(drive, 0, sizeof(*drive));
+
+ 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->name[0] = 'h';
+ drive->name[1] = 'd';
+ drive->name[2] = 'a' + j;
+ drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
+
+ INIT_LIST_HEAD(&drive->list);
+ init_completion(&drive->gendev_rel_comp);
+ }
+}
+
+static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
+{
+ /* fill in any non-zero initial values */
+ hwif->index = index;
+ hwif->major = ide_hwif_to_major[index];
+
+ hwif->name[0] = 'i';
+ hwif->name[1] = 'd';
+ hwif->name[2] = 'e';
+ hwif->name[3] = '0' + index;
+
+ init_completion(&hwif->gendev_rel_comp);
+
+ hwif->tp_ops = &default_tp_ops;
+
+ ide_port_init_devices_data(hwif);
+}
+
+static void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *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;
+}
+
static unsigned int ide_indexes;
/**
@@ -1466,12 +1378,43 @@ static void ide_free_port_slot(int idx)
mutex_unlock(&ide_cfg_mtx);
}
+static void ide_port_free_devices(ide_hwif_t *hwif)
+{
+ ide_drive_t *drive;
+ int i;
+
+ ide_port_for_each_dev(i, drive, hwif)
+ kfree(drive);
+}
+
+static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
+{
+ int i;
+
+ for (i = 0; i < MAX_DRIVES; i++) {
+ ide_drive_t *drive;
+
+ drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node);
+ if (drive == NULL)
+ goto out_nomem;
+
+ hwif->devices[i] = drive;
+ }
+ return 0;
+
+out_nomem:
+ ide_port_free_devices(hwif);
+ return -ENOMEM;
+}
+
struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
{
struct ide_host *host;
+ struct device *dev = hws[0] ? hws[0]->dev : NULL;
+ int node = dev ? dev_to_node(dev) : -1;
int i;
- host = kzalloc(sizeof(*host), GFP_KERNEL);
+ host = kzalloc_node(sizeof(*host), GFP_KERNEL, node);
if (host == NULL)
return NULL;
@@ -1482,10 +1425,15 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
if (hws[i] == NULL)
continue;
- hwif = kzalloc(sizeof(*hwif), GFP_KERNEL);
+ hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node);
if (hwif == NULL)
continue;
+ if (ide_port_alloc_devices(hwif, node) < 0) {
+ kfree(hwif);
+ continue;
+ }
+
idx = ide_find_port_slot(d);
if (idx < 0) {
printk(KERN_ERR "%s: no free slot for interface\n",
@@ -1507,8 +1455,7 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
return NULL;
}
- if (hws[0])
- host->dev[0] = hws[0]->dev;
+ host->dev[0] = dev;
if (d) {
host->init_chipset = d->init_chipset;
@@ -1525,9 +1472,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_hwif_t *hwif, *mate = NULL;
int i, j = 0;
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- hwif = host->ports[i];
-
+ ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL) {
mate = NULL;
continue;
@@ -1553,9 +1498,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_port_init_devices(hwif);
}
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- hwif = host->ports[i];
-
+ ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
@@ -1570,9 +1513,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_port_tune_devices(hwif);
}
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- hwif = host->ports[i];
-
+ ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
@@ -1597,9 +1538,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_acpi_port_init_devices(hwif);
}
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- hwif = host->ports[i];
-
+ ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
@@ -1607,9 +1546,7 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
hwif_register_devices(hwif);
}
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- hwif = host->ports[i];
-
+ ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
@@ -1647,17 +1584,85 @@ int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws,
}
EXPORT_SYMBOL_GPL(ide_host_add);
+static void __ide_port_unregister_devices(ide_hwif_t *hwif)
+{
+ ide_drive_t *drive;
+ int i;
+
+ ide_port_for_each_dev(i, drive, hwif) {
+ if (drive->dev_flags & IDE_DFLAG_PRESENT) {
+ device_unregister(&drive->gendev);
+ wait_for_completion(&drive->gendev_rel_comp);
+ }
+ }
+}
+
+void ide_port_unregister_devices(ide_hwif_t *hwif)
+{
+ mutex_lock(&ide_cfg_mtx);
+ __ide_port_unregister_devices(hwif);
+ hwif->present = 0;
+ ide_port_init_devices_data(hwif);
+ mutex_unlock(&ide_cfg_mtx);
+}
+EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
+
+/**
+ * ide_unregister - free an IDE interface
+ * @hwif: IDE interface
+ *
+ * Perform the final unregister of an IDE interface.
+ *
+ * Locking:
+ * The caller must not hold the IDE locks.
+ *
+ * It is up to the caller to be sure there is no pending I/O here,
+ * and that the interface will not be reopened (present/vanishing
+ * locking isn't yet done BTW).
+ */
+
+static void ide_unregister(ide_hwif_t *hwif)
+{
+ BUG_ON(in_interrupt());
+ BUG_ON(irqs_disabled());
+
+ mutex_lock(&ide_cfg_mtx);
+
+ if (hwif->present) {
+ __ide_port_unregister_devices(hwif);
+ hwif->present = 0;
+ }
+
+ ide_proc_unregister_port(hwif);
+
+ free_irq(hwif->irq, hwif);
+
+ device_unregister(hwif->portdev);
+ device_unregister(&hwif->gendev);
+ wait_for_completion(&hwif->gendev_rel_comp);
+
+ /*
+ * Remove us from the kernel's knowledge
+ */
+ blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);
+ kfree(hwif->sg_table);
+ unregister_blkdev(hwif->major, hwif->name);
+
+ ide_release_dma_engine(hwif);
+
+ mutex_unlock(&ide_cfg_mtx);
+}
+
void ide_host_free(struct ide_host *host)
{
ide_hwif_t *hwif;
int i;
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- hwif = host->ports[i];
-
+ ide_host_for_each_port(i, hwif, host) {
if (hwif == NULL)
continue;
+ ide_port_free_devices(hwif);
ide_free_port_slot(hwif->index);
kfree(hwif);
}
@@ -1668,11 +1673,12 @@ EXPORT_SYMBOL_GPL(ide_host_free);
void ide_host_remove(struct ide_host *host)
{
+ ide_hwif_t *hwif;
int i;
- for (i = 0; i < MAX_HOST_PORTS; i++) {
- if (host->ports[i])
- ide_unregister(host->ports[i]);
+ ide_host_for_each_port(i, hwif, host) {
+ if (hwif)
+ ide_unregister(hwif);
}
ide_host_free(host);
@@ -1691,8 +1697,8 @@ void ide_port_scan(ide_hwif_t *hwif)
hwif->present = 1;
ide_port_tune_devices(hwif);
- ide_acpi_port_init_devices(hwif);
ide_port_setup_devices(hwif);
+ ide_acpi_port_init_devices(hwif);
hwif_register_devices(hwif);
ide_proc_port_register_devices(hwif);
}
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index a14e293..1d8978b 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -439,13 +439,13 @@ static int proc_ide_read_dmodel
static int proc_ide_read_driver
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
- ide_drive_t *drive = (ide_drive_t *) data;
- struct device *dev = &drive->gendev;
- ide_driver_t *ide_drv;
- int len;
+ ide_drive_t *drive = (ide_drive_t *)data;
+ struct device *dev = &drive->gendev;
+ struct ide_driver *ide_drv;
+ int len;
if (dev->driver) {
- ide_drv = container_of(dev->driver, ide_driver_t, gen_driver);
+ ide_drv = to_ide_driver(dev->driver);
len = sprintf(page, "%s version %s\n",
dev->driver->name, ide_drv->version);
} else
@@ -555,7 +555,7 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t
}
}
-void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver)
+void ide_proc_register_driver(ide_drive_t *drive, struct ide_driver *driver)
{
mutex_lock(&ide_setting_mtx);
drive->settings = driver->proc_devsets(drive);
@@ -577,7 +577,7 @@ EXPORT_SYMBOL(ide_proc_register_driver);
* Takes ide_setting_mtx.
*/
-void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
+void ide_proc_unregister_driver(ide_drive_t *drive, struct ide_driver *driver)
{
ide_remove_proc_entries(drive->proc, driver->proc_entries(drive));
@@ -593,14 +593,13 @@ EXPORT_SYMBOL(ide_proc_unregister_driver);
void ide_proc_port_register_devices(ide_hwif_t *hwif)
{
- int d;
struct proc_dir_entry *ent;
struct proc_dir_entry *parent = hwif->proc;
+ ide_drive_t *drive;
char name[64];
+ int i;
- for (d = 0; d < MAX_DRIVES; d++) {
- ide_drive_t *drive = &hwif->drives[d];
-
+ ide_port_for_each_dev(i, drive, hwif) {
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0 || drive->proc)
continue;
@@ -653,7 +652,7 @@ void ide_proc_unregister_port(ide_hwif_t *hwif)
static int proc_print_driver(struct device_driver *drv, void *data)
{
- ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver);
+ struct ide_driver *ide_drv = to_ide_driver(drv);
struct seq_file *s = data;
seq_printf(s, "%s version %s\n", drv->name, ide_drv->version);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 5d2aa22..d7ecd3c 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -166,10 +166,10 @@ struct idetape_bh {
* to an interrupt or a timer event is stored in the struct defined below.
*/
typedef struct ide_tape_obj {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
+ ide_drive_t *drive;
+ struct ide_driver *driver;
+ struct gendisk *disk;
+ struct kref kref;
/*
* failed_pc points to the last failed packet command, or contains
@@ -479,7 +479,7 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
{
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = drive->hwif->rq;
idetape_tape_t *tape = drive->driver_data;
unsigned long flags;
int error;
@@ -531,7 +531,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
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) {
- struct request *rq = drive->hwif->hwgroup->rq;
+ struct request *rq = drive->hwif->rq;
int blocks = pc->xferred / tape->blk_size;
tape->avg_size += blocks * tape->blk_size;
@@ -576,7 +576,7 @@ static void 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 hwgroup while we are polling for DSC.
+ * from another device on the same port while we are polling for DSC.
*/
static void idetape_postpone_request(ide_drive_t *drive)
{
@@ -584,7 +584,8 @@ static void idetape_postpone_request(ide_drive_t *drive)
debug_log(DBG_PROCS, "Enter %s\n", __func__);
- tape->postponed_rq = HWGROUP(drive)->rq;
+ tape->postponed_rq = drive->hwif->rq;
+
ide_stall_queue(drive, tape->dsc_poll_freq);
}
@@ -2312,7 +2313,7 @@ static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive)
static int ide_tape_probe(ide_drive_t *);
-static ide_driver_t idetape_driver = {
+static struct ide_driver idetape_driver = {
.gen_driver = {
.owner = THIS_MODULE,
.name = "ide-tape",
@@ -2323,7 +2324,6 @@ static ide_driver_t idetape_driver = {
.version = IDETAPE_VERSION,
.do_request = idetape_do_request,
.end_request = idetape_end_request,
- .error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_tape_proc_entries,
.proc_devsets = ide_tape_proc_devsets,
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index bf4fb9d..16138bc 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -58,7 +58,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *);
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct ide_taskfile *tf = &task->tf;
ide_handler_t *handler = NULL;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
@@ -309,9 +309,9 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
}
if (sectors > 0) {
- ide_driver_t *drv;
+ struct ide_driver *drv;
- drv = *(ide_driver_t **)rq->rq_disk->private_data;
+ drv = *(struct ide_driver **)rq->rq_disk->private_data;
drv->end_request(drive, 1, sectors);
}
}
@@ -328,9 +328,9 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
}
if (rq->rq_disk) {
- ide_driver_t *drv;
+ struct ide_driver *drv;
- drv = *(ide_driver_t **)rq->rq_disk->private_data;;
+ drv = *(struct ide_driver **)rq->rq_disk->private_data;;
drv->end_request(drive, 1, rq->nr_sectors);
} else
ide_end_request(drive, 1, rq->nr_sectors);
@@ -361,7 +361,7 @@ static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq
static ide_startstop_t task_in_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
u8 stat = hwif->tp_ops->read_status(hwif);
/* Error? */
@@ -395,7 +395,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
static ide_startstop_t task_out_intr (ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = hwif->rq;
u8 stat = hwif->tp_ops->read_status(hwif);
if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 46a2d4c..258805d 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -60,179 +60,8 @@
#include <linux/completion.h>
#include <linux/device.h>
-
-/* default maximum number of failures */
-#define IDE_DEFAULT_MAX_FAILURES 1
-
struct class *ide_port_class;
-static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR,
- IDE2_MAJOR, IDE3_MAJOR,
- IDE4_MAJOR, IDE5_MAJOR,
- IDE6_MAJOR, IDE7_MAJOR,
- IDE8_MAJOR, IDE9_MAJOR };
-
-DEFINE_MUTEX(ide_cfg_mtx);
-
-static void ide_port_init_devices_data(ide_hwif_t *);
-
-/*
- * Do not even *think* about calling this!
- */
-void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
-{
- /* bulk initialize hwif & drive info with zeros */
- memset(hwif, 0, sizeof(ide_hwif_t));
-
- /* fill in any non-zero initial values */
- hwif->index = index;
- hwif->major = ide_hwif_to_major[index];
-
- hwif->name[0] = 'i';
- hwif->name[1] = 'd';
- hwif->name[2] = 'e';
- hwif->name[3] = '0' + index;
-
- init_completion(&hwif->gendev_rel_comp);
-
- hwif->tp_ops = &default_tp_ops;
-
- ide_port_init_devices_data(hwif);
-}
-
-static void ide_port_init_devices_data(ide_hwif_t *hwif)
-{
- int unit;
-
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
- u8 j = (hwif->index * MAX_DRIVES) + unit;
-
- memset(drive, 0, sizeof(*drive));
-
- drive->media = ide_disk;
- drive->select = (unit << 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->name[0] = 'h';
- drive->name[1] = 'd';
- drive->name[2] = 'a' + j;
- drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
-
- INIT_LIST_HEAD(&drive->list);
- init_completion(&drive->gendev_rel_comp);
- }
-}
-
-static void __ide_port_unregister_devices(ide_hwif_t *hwif)
-{
- int i;
-
- for (i = 0; i < MAX_DRIVES; i++) {
- ide_drive_t *drive = &hwif->drives[i];
-
- if (drive->dev_flags & IDE_DFLAG_PRESENT) {
- device_unregister(&drive->gendev);
- wait_for_completion(&drive->gendev_rel_comp);
- }
- }
-}
-
-void ide_port_unregister_devices(ide_hwif_t *hwif)
-{
- mutex_lock(&ide_cfg_mtx);
- __ide_port_unregister_devices(hwif);
- hwif->present = 0;
- ide_port_init_devices_data(hwif);
- mutex_unlock(&ide_cfg_mtx);
-}
-EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
-
-/**
- * ide_unregister - free an IDE interface
- * @hwif: IDE interface
- *
- * Perform the final unregister of an IDE interface. At the moment
- * we don't refcount interfaces so this will also get split up.
- *
- * Locking:
- * The caller must not hold the IDE locks
- * The drive present/vanishing is not yet properly locked
- * Take care with the callbacks. These have been split to avoid
- * deadlocking the IDE layer. The shutdown callback is called
- * before we take the lock and free resources. It is up to the
- * caller to be sure there is no pending I/O here, and that
- * the interface will not be reopened (present/vanishing locking
- * isn't yet done BTW). After we commit to the final kill we
- * call the cleanup callback with the ide locks held.
- *
- * Unregister restores the hwif structures to the default state.
- * This is raving bonkers.
- */
-
-void ide_unregister(ide_hwif_t *hwif)
-{
- ide_hwif_t *g;
- ide_hwgroup_t *hwgroup;
- int irq_count = 0;
-
- BUG_ON(in_interrupt());
- BUG_ON(irqs_disabled());
-
- mutex_lock(&ide_cfg_mtx);
-
- if (hwif->present) {
- __ide_port_unregister_devices(hwif);
- hwif->present = 0;
- }
-
- ide_proc_unregister_port(hwif);
-
- hwgroup = hwif->hwgroup;
- /*
- * free the irq if we were the only hwif using it
- */
- g = hwgroup->hwif;
- do {
- if (g->irq == hwif->irq)
- ++irq_count;
- g = g->next;
- } while (g != hwgroup->hwif);
- if (irq_count == 1)
- free_irq(hwif->irq, hwgroup);
-
- ide_remove_port_from_hwgroup(hwif);
-
- device_unregister(hwif->portdev);
- device_unregister(&hwif->gendev);
- wait_for_completion(&hwif->gendev_rel_comp);
-
- /*
- * Remove us from the kernel's knowledge
- */
- blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);
- kfree(hwif->sg_table);
- unregister_blkdev(hwif->major, hwif->name);
-
- ide_release_dma_engine(hwif);
-
- mutex_unlock(&ide_cfg_mtx);
-}
-
-void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *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;
-}
-
/*
* Locks for IDE setting functionality
*/
@@ -330,7 +159,6 @@ static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
static int set_pio_mode(ide_drive_t *drive, int arg)
{
ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *hwgroup = hwif->hwgroup;
const struct ide_port_ops *port_ops = hwif->port_ops;
if (arg < 0 || arg > 255)
@@ -345,9 +173,9 @@ static int set_pio_mode(ide_drive_t *drive, int arg)
unsigned long flags;
/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
- spin_lock_irqsave(&hwgroup->lock, flags);
+ spin_lock_irqsave(&hwif->lock, flags);
port_ops->set_pio_mode(drive, arg);
- spin_unlock_irqrestore(&hwgroup->lock, flags);
+ spin_unlock_irqrestore(&hwif->lock, flags);
} else
port_ops->set_pio_mode(drive, arg);
} else {
@@ -453,7 +281,7 @@ static int ide_uevent(struct device *dev, struct kobj_uevent_env *env)
static int generic_ide_probe(struct device *dev)
{
ide_drive_t *drive = to_ide_device(dev);
- ide_driver_t *drv = to_ide_driver(dev->driver);
+ struct ide_driver *drv = to_ide_driver(dev->driver);
return drv->probe ? drv->probe(drive) : -ENODEV;
}
@@ -461,7 +289,7 @@ static int generic_ide_probe(struct device *dev)
static int generic_ide_remove(struct device *dev)
{
ide_drive_t *drive = to_ide_device(dev);
- ide_driver_t *drv = to_ide_driver(dev->driver);
+ struct ide_driver *drv = to_ide_driver(dev->driver);
if (drv->remove)
drv->remove(drive);
@@ -472,7 +300,7 @@ static int generic_ide_remove(struct device *dev)
static void generic_ide_shutdown(struct device *dev)
{
ide_drive_t *drive = to_ide_device(dev);
- ide_driver_t *drv = to_ide_driver(dev->driver);
+ struct ide_driver *drv = to_ide_driver(dev->driver);
if (dev->driver && drv->shutdown)
drv->shutdown(drive);
@@ -660,6 +488,7 @@ MODULE_PARM_DESC(ignore_cable, "ignore cable detection");
void ide_port_apply_params(ide_hwif_t *hwif)
{
+ ide_drive_t *drive;
int i;
if (ide_ignore_cable & (1 << hwif->index)) {
@@ -668,8 +497,8 @@ void ide_port_apply_params(ide_hwif_t *hwif)
hwif->cbl = ATA_CBL_PATA40_SHORT;
}
- for (i = 0; i < MAX_DRIVES; i++)
- ide_dev_apply_params(&hwif->drives[i], i);
+ ide_port_for_each_dev(i, drive, hwif)
+ ide_dev_apply_params(drive, i);
}
/*
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
new file mode 100644
index 0000000..e021078
--- /dev/null
+++ b/drivers/ide/it8172.c
@@ -0,0 +1,166 @@
+/*
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IT8172 IDE controller support
+ *
+ * Copyright (C) 2000 MontaVista Software Inc.
+ * Copyright (C) 2008 Shane McDonald
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+
+#define DRV_NAME "IT8172"
+
+static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ u16 drive_enables;
+ u32 drive_timing;
+
+ /*
+ * The highest value of DIOR/DIOW pulse width and recovery time
+ * that can be set in the IT8172 is 8 PCI clock cycles. As a result,
+ * it cannot be configured for PIO mode 0. This table sets these
+ * parameters to the maximum supported by the IT8172.
+ */
+ static const u8 timings[] = { 0x3f, 0x3c, 0x1b, 0x12, 0x0a };
+
+ pci_read_config_word(dev, 0x40, &drive_enables);
+ pci_read_config_dword(dev, 0x44, &drive_timing);
+
+ /*
+ * Enable port 0x44. The IT8172 spec is confused; it calls
+ * this register the "Slave IDE Timing Register", but in fact,
+ * it controls timing for both master and slave drives.
+ */
+ drive_enables |= 0x4000;
+
+ drive_enables &= drive->dn ? 0xc006 : 0xc060;
+ if (drive->media == ide_disk)
+ /* enable prefetch */
+ drive_enables |= 0x0004 << (drive->dn * 4);
+ if (ata_id_has_iordy(drive->id))
+ /* enable IORDY sample-point */
+ drive_enables |= 0x0002 << (drive->dn * 4);
+
+ drive_timing &= drive->dn ? 0x00003f00 : 0x000fc000;
+ drive_timing |= timings[pio] << (drive->dn * 6 + 8);
+
+ pci_write_config_word(dev, 0x40, drive_enables);
+ pci_write_config_dword(dev, 0x44, drive_timing);
+}
+
+static void it8172_set_dma_mode(ide_drive_t *drive, const u8 speed)
+{
+ 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;
+
+ pci_read_config_byte(dev, 0x48, ®48);
+ pci_read_config_byte(dev, 0x4a, ®4a);
+
+ if (speed >= XFER_UDMA_0) {
+ u8 udma = speed - XFER_UDMA_0;
+ u_speed = udma << (drive->dn * 4);
+
+ pci_write_config_byte(dev, 0x48, reg48 | u_flag);
+ reg4a &= ~a_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];
+
+ it8172_set_pio_mode(drive, pio);
+ }
+}
+
+
+static const struct ide_port_ops it8172_port_ops = {
+ .set_pio_mode = it8172_set_pio_mode,
+ .set_dma_mode = it8172_set_dma_mode,
+};
+
+static const struct ide_port_info it8172_port_info __devinitdata = {
+ .name = DRV_NAME,
+ .port_ops = &it8172_port_ops,
+ .enablebits = { {0x41, 0x80, 0x80}, {0x00, 0x00, 0x00} },
+ .host_flags = IDE_HFLAG_SINGLE,
+ .pio_mask = ATA_PIO4 & ~ATA_PIO0,
+ .mwdma_mask = ATA_MWDMA2,
+ .udma_mask = ATA_UDMA2,
+};
+
+static int __devinit 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 */
+ return ide_pci_init_one(dev, &it8172_port_info, NULL);
+}
+
+static struct pci_device_id it8172_pci_tbl[] = {
+ { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8172), 0 },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, it8172_pci_tbl);
+
+static struct pci_driver it8172_pci_driver = {
+ .name = "IT8172_IDE",
+ .id_table = it8172_pci_tbl,
+ .probe = it8172_init_one,
+ .remove = ide_pci_remove,
+ .suspend = ide_pci_suspend,
+ .resume = ide_pci_resume,
+};
+
+static int __init it8172_ide_init(void)
+{
+ return ide_pci_register_driver(&it8172_pci_driver);
+}
+
+static void __exit it8172_ide_exit(void)
+{
+ pci_unregister_driver(&it8172_pci_driver);
+}
+
+module_init(it8172_ide_init);
+module_exit(it8172_ide_exit);
+
+MODULE_AUTHOR("Steve Longerbeam");
+MODULE_DESCRIPTION("PCI driver module for ITE 8172 IDE");
+MODULE_LICENSE("GPL");
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c
index 7c2feeb..d7969b6 100644
--- a/drivers/ide/it8213.c
+++ b/drivers/ide/it8213.c
@@ -25,7 +25,7 @@
static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -82,7 +82,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void it8213_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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);
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index ef00408..0be27ac 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -167,12 +167,10 @@ static void it821x_clock_strategy(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct it821x_dev *itdev = ide_get_hwifdata(hwif);
- ide_drive_t *pair;
+ ide_drive_t *pair = ide_get_pair_dev(drive);
int clock, altclock, sel = 0;
u8 unit = drive->dn & 1, v;
- pair = &hwif->drives[1 - unit];
-
if(itdev->want[0][0] > itdev->want[1][0]) {
clock = itdev->want[0][1];
altclock = itdev->want[1][1];
@@ -239,15 +237,13 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = drive->hwif;
struct it821x_dev *itdev = ide_get_hwifdata(hwif);
- ide_drive_t *pair;
+ ide_drive_t *pair = ide_get_pair_dev(drive);
u8 unit = drive->dn & 1, set_pio = pio;
/* Spec says 89 ref driver uses 88 */
static u16 pio_timings[]= { 0xAA88, 0xA382, 0xA181, 0x3332, 0x3121 };
static u8 pio_want[] = { ATA_66, ATA_66, ATA_66, ATA_66, ATA_ANY };
- pair = &hwif->drives[1 - unit];
-
/*
* Compute the best PIO mode we can for a given device. We must
* pick a speed that does not cause problems with the other device
@@ -279,7 +275,7 @@ static void it821x_set_pio_mode(ide_drive_t *drive, const u8 pio)
* the shared MWDMA/PIO timing register.
*/
-static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
+static void it821x_tune_mwdma(ide_drive_t *drive, u8 mode_wanted)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -316,7 +312,7 @@ static void it821x_tune_mwdma (ide_drive_t *drive, byte mode_wanted)
* controller when doing UDMA modes in pass through.
*/
-static void it821x_tune_udma (ide_drive_t *drive, byte mode_wanted)
+static void it821x_tune_udma(ide_drive_t *drive, u8 mode_wanted)
{
ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -516,6 +512,7 @@ static struct ide_dma_ops it821x_pass_through_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
/**
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 1378906..83643ed 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -56,7 +56,7 @@ static u8 superio_read_status(ide_hwif_t *hwif)
return superio_ide_inb(hwif->io_ports.status_addr);
}
-static u8 superio_read_sff_dma_status(ide_hwif_t *hwif)
+static u8 superio_dma_sff_read_status(ide_hwif_t *hwif)
{
return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
}
@@ -109,7 +109,6 @@ static const struct ide_tp_ops superio_tp_ops = {
.exec_command = ide_exec_command,
.read_status = superio_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = superio_read_sff_dma_status,
.set_irq = ide_set_irq,
@@ -132,18 +131,20 @@ static void __devinit superio_init_iops(struct hwif_s *hwif)
tmp = superio_ide_inb(dma_stat);
outb(tmp | 0x66, dma_stat);
}
+#else
+#define superio_dma_sff_read_status ide_dma_sff_read_status
#endif
static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 };
/*
* This routine either enables/disables (according to IDE_DFLAG_PRESENT)
- * the IRQ associated with the port (HWIF(drive)),
+ * the IRQ associated with the port,
* and selects either PIO or DMA handshaking for the next I/O operation.
*/
static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned int bit, other, new, *old = (unsigned int *) hwif->select_data;
unsigned long flags;
@@ -197,11 +198,11 @@ static void ns87415_selectproc (ide_drive_t *drive)
static int ns87415_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
drive->waiting_for_dma = 0;
- dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
/* stop DMA */
@@ -308,6 +309,7 @@ static const struct ide_dma_ops ns87415_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = superio_dma_sff_read_status,
};
static const struct ide_port_info ns87415_chipset __devinitdata = {
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index 122ed3c..a7ac490 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -324,8 +324,6 @@ static int __devinit palm_bk3710_init_dma(ide_hwif_t *hwif,
hwif->dma_base = hwif->io_ports.data_addr - IDE_PALM_ATA_PRI_REG_OFFSET;
- hwif->dma_ops = &sff_dma_ops;
-
return 0;
}
@@ -338,6 +336,7 @@ static const struct ide_port_ops palm_bk3710_ports_ops = {
static struct ide_port_info __devinitdata 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,
diff --git a/drivers/ide/pdc202xx_new.c b/drivers/ide/pdc202xx_new.c
index 211ae46..f21290c 100644
--- a/drivers/ide/pdc202xx_new.c
+++ b/drivers/ide/pdc202xx_new.c
@@ -143,7 +143,7 @@ static struct udma_timing {
static void pdcnew_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 adj = (drive->dn & 1) ? 0x08 : 0x00;
@@ -219,7 +219,7 @@ static void pdcnew_reset(ide_drive_t *drive)
* Deleted this because it is redundant from the caller.
*/
printk(KERN_WARNING "pdc202xx_new: %s channel reset.\n",
- HWIF(drive)->channel ? "Secondary" : "Primary");
+ drive->hwif->channel ? "Secondary" : "Primary");
}
/**
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index 624e62e..9719332 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -39,7 +39,7 @@ static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 drive_pci = 0x60 + (drive->dn << 2);
@@ -169,8 +169,8 @@ static void pdc202xx_dma_start(ide_drive_t *drive)
if (drive->current_speed > XFER_UDMA_2)
pdc_old_enable_66MHz_clock(drive->hwif);
if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) {
- struct request *rq = HWGROUP(drive)->rq;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
+ struct request *rq = hwif->rq;
unsigned long high_16 = hwif->extra_base - 16;
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
u32 word_count = 0;
@@ -189,7 +189,7 @@ static void pdc202xx_dma_start(ide_drive_t *drive)
static int pdc202xx_dma_end(ide_drive_t *drive)
{
if (drive->media != ide_disk || (drive->dev_flags & IDE_DFLAG_LBA48)) {
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long high_16 = hwif->extra_base - 16;
unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
u8 clock = 0;
@@ -205,7 +205,7 @@ static int pdc202xx_dma_end(ide_drive_t *drive)
static int pdc202xx_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(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);
@@ -243,7 +243,7 @@ static void pdc202xx_reset_host (ide_hwif_t *hwif)
static void pdc202xx_reset (ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
ide_hwif_t *mate = hwif->mate;
pdc202xx_reset_host(hwif);
@@ -337,6 +337,7 @@ static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
.dma_timeout = pdc202xx_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops pdc2026x_dma_ops = {
@@ -348,6 +349,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
.dma_timeout = pdc202xx_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
#define DECLARE_PDC2026X_DEV(udma, sectors) \
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index 61d2d92..f1e2e4e 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -67,7 +67,7 @@ static int no_piix_dma;
static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -136,7 +136,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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);
@@ -224,7 +224,7 @@ static unsigned int init_chipset_ich(struct pci_dev *dev)
*/
static void ich_clear_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u8 dma_stat;
/*
@@ -260,6 +260,8 @@ static const struct ich_laptop ich_laptop[] = {
{ 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */
{ 0x27DF, 0x1071, 0xD221 }, /* ICH7 on Hercules EC-900 */
{ 0x24CA, 0x1025, 0x0061 }, /* ICH4 on Acer Aspire 2023WLMi */
+ { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */
+ { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
{ 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
/* end marker */
{ 0, }
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 7c481bb..74625e8 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -955,7 +955,6 @@ static const struct ide_tp_ops pmac_tp_ops = {
.exec_command = pmac_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = pmac_set_irq,
@@ -1513,10 +1512,10 @@ use_pio_instead:
static int
pmac_ide_dma_setup(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = hwif->rq;
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
if (!pmac_ide_build_dmatable(drive, rq)) {
@@ -1637,7 +1636,7 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
break;
if (++timeout > 100) {
printk(KERN_WARNING "ide%d, ide_dma_test_irq \
- timeout flushing channel\n", HWIF(drive)->index);
+ timeout flushing channel\n", hwif->index);
break;
}
}
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index 4af4a8c..9f9c0b3 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -99,7 +99,6 @@ static const struct ide_tp_ops q40ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index bc27c7a..5b2e3af 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -202,7 +202,8 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio)
recovery_time = drive->id[ATA_ID_EIDE_PIO] - 120;
}
- qd_set_timing(drive, qd6500_compute_timing(HWIF(drive), active_time, recovery_time));
+ qd_set_timing(drive, qd6500_compute_timing(drive->hwif,
+ active_time, recovery_time));
}
static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
@@ -245,11 +246,11 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
printk(KERN_INFO "%s: PIO mode%d\n", drive->name,pio);
}
- if (!HWIF(drive)->channel && drive->media != ide_disk) {
+ if (!hwif->channel && drive->media != ide_disk) {
outb(0x5f, QD_CONTROL_PORT);
printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO "
"and post-write buffer on %s.\n",
- drive->name, HWIF(drive)->name);
+ drive->name, hwif->name);
}
qd_set_timing(drive, qd6580_compute_timing(active_time, recovery_time));
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
index c83dea8..6636f96 100644
--- a/drivers/ide/qd65xx.h
+++ b/drivers/ide/qd65xx.h
@@ -31,8 +31,8 @@
#define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff)
-#define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff)
-#define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8)
+#define QD_TIMING(drive) (u8)(((drive)->drive_data) & 0x00ff)
+#define QD_TIMREG(drive) (u8)((((drive)->drive_data) & 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/sc1200.c b/drivers/ide/sc1200.c
index ec7f766..dbdd298 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -125,7 +125,7 @@ out:
static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned int reg, timings;
unsigned short pci_clock;
@@ -170,9 +170,9 @@ static void sc1200_set_dma_mode(ide_drive_t *drive, const u8 mode)
*/
static int sc1200_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long dma_base = hwif->dma_base;
- byte dma_stat;
+ u8 dma_stat;
dma_stat = inb(dma_base+2); /* get DMA status */
@@ -199,7 +199,7 @@ static int sc1200_dma_end(ide_drive_t *drive)
static void sc1200_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
int mode = -1;
/*
@@ -292,6 +292,7 @@ static const struct ide_dma_ops sc1200_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_port_info sc1200_chipset __devinitdata = {
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 0f48f9d..8d2314b 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -143,7 +143,7 @@ static u8 scc_read_altstatus(ide_hwif_t *hwif)
return (u8)in_be32((void *)hwif->io_ports.ctl_addr);
}
-static u8 scc_read_sff_dma_status(ide_hwif_t *hwif)
+static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
{
return (u8)in_be32((void *)(hwif->dma_base + 4));
}
@@ -217,7 +217,7 @@ scc_ide_outsl(unsigned long port, void *addr, u32 count)
static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -249,7 +249,7 @@ static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -259,7 +259,7 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
unsigned long scrcst_port = ctl_base + 0x014;
unsigned long udenvt_port = ctl_base + 0x018;
unsigned long tdvhsel_port = ctl_base + 0x020;
- int is_slave = (&hwif->drives[1] == drive);
+ int is_slave = drive->dn & 1;
int offset, idx;
unsigned long reg;
unsigned long jcactsel;
@@ -292,7 +292,7 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
{
ide_hwif_t *hwif = drive->hwif;
u8 unit = drive->dn & 1;
- u8 dma_stat = scc_ide_inb(hwif->dma_base + 4);
+ u8 dma_stat = scc_dma_sff_read_status(hwif);
if (on)
dma_stat |= (1 << (5 + unit));
@@ -316,7 +316,7 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
static int scc_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = hwif->rq;
unsigned int reading;
u8 dma_stat;
@@ -338,7 +338,7 @@ static int scc_dma_setup(ide_drive_t *drive)
out_be32((void __iomem *)hwif->dma_base, reading);
/* read DMA status for INTR & ERROR flags */
- dma_stat = in_be32((void __iomem *)(hwif->dma_base + 4));
+ dma_stat = scc_dma_sff_read_status(hwif);
/* clear INTR & ERROR flags */
out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
@@ -367,7 +367,7 @@ static int __scc_dma_end(ide_drive_t *drive)
/* stop DMA */
scc_ide_outb(dma_cmd & ~1, hwif->dma_base);
/* get DMA status */
- dma_stat = scc_ide_inb(hwif->dma_base + 4);
+ dma_stat = scc_dma_sff_read_status(hwif);
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
/* purge DMA mappings */
@@ -387,7 +387,7 @@ static int __scc_dma_end(ide_drive_t *drive)
static int scc_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
void __iomem *dma_base = (void __iomem *)hwif->dma_base;
unsigned long intsts_port = hwif->dma_base + 0x014;
u32 reg;
@@ -405,17 +405,18 @@ static int scc_dma_end(ide_drive_t *drive)
drive->name);
data_loss = 1;
if (retry++) {
- struct request *rq = HWGROUP(drive)->rq;
- int unit;
+ struct request *rq = hwif->rq;
+ ide_drive_t *drive;
+ int i;
+
/* ERROR_RESET and drive->crc_count are needed
* to reduce DMA transfer mode in retry process.
*/
if (rq)
rq->errors |= ERROR_RESET;
- for (unit = 0; unit < MAX_DRIVES; unit++) {
- ide_drive_t *drive = &hwif->drives[unit];
+
+ ide_port_for_each_dev(i, drive, hwif)
drive->crc_count++;
- }
}
}
}
@@ -496,7 +497,7 @@ static int scc_dma_end(ide_drive_t *drive)
/* returns 1 if dma irq issued, 0 otherwise */
static int scc_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u32 int_stat = in_be32((void __iomem *)hwif->dma_base + 0x014);
/* SCC errata A252,A308 workaround: Step4 */
@@ -852,7 +853,6 @@ static const struct ide_tp_ops scc_tp_ops = {
.exec_command = scc_exec_command,
.read_status = scc_read_status,
.read_altstatus = scc_read_altstatus,
- .read_sff_dma_status = scc_read_sff_dma_status,
.set_irq = scc_set_irq,
@@ -879,6 +879,7 @@ static const struct ide_dma_ops scc_dma_ops = {
.dma_test_irq = scc_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = scc_dma_sff_read_status,
};
#define DECLARE_SCC_DEV(name_str) \
diff --git a/drivers/ide/serverworks.c b/drivers/ide/serverworks.c
index 437bc91..382102b 100644
--- a/drivers/ide/serverworks.c
+++ b/drivers/ide/serverworks.c
@@ -151,7 +151,7 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
static const u8 dma_modes[] = { 0x77, 0x21, 0x20 };
static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 };
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 unit = drive->dn & 1;
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 9f1f916..e85d1ed 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -130,7 +130,7 @@ int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d)
* we tune the drive then try to grab DMA ownership if we want to be
* the DMA end. This has to be become dynamic to handle hot-plug.
*/
- dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
+ dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
printk(KERN_INFO "%s %s: simplex device: DMA disabled\n",
d->name, pci_name(dev));
@@ -377,6 +377,9 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
hwif->dma_base = base;
+ if (hwif->dma_ops == NULL)
+ hwif->dma_ops = &sff_dma_ops;
+
if (ide_pci_check_simplex(hwif, d) < 0)
return -1;
@@ -393,8 +396,6 @@ int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
if (ide_allocate_dma_engine(hwif))
return -1;
-
- hwif->dma_ops = &sff_dma_ops;
}
return 0;
@@ -471,7 +472,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
*/
for (port = 0; port < channels; ++port) {
- const ide_pci_enablebit_t *e = &(d->enablebits[port]);
+ const struct ide_pci_enablebit *e = &d->enablebits[port];
if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
(tmp & e->mask) != e->val)) {
@@ -519,8 +520,7 @@ static int do_ide_setup_pci_device(struct pci_dev *dev,
if (ret < 0)
goto out;
- /* Is it an "IDE storage" device in non-PCI mode? */
- if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 5) != 5) {
+ if (ide_pci_is_in_compatibility_mode(dev)) {
if (noisy)
printk(KERN_INFO "%s %s: not 100%% native mode: will "
"probe irqs later\n", d->name, pci_name(dev));
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index a687a7d..fdb9d70 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -123,7 +123,7 @@ static int
sgiioc4_clearirq(ide_drive_t * drive)
{
u32 intr_reg;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
@@ -181,7 +181,7 @@ sgiioc4_clearirq(ide_drive_t * drive)
static void sgiioc4_dma_start(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
unsigned int temp_reg = reg | IOC4_S_DMA_START;
@@ -209,7 +209,7 @@ sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
static int sgiioc4_dma_end(ide_drive_t *drive)
{
u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long dma_base = hwif->dma_base;
int dma_stat = 0;
unsigned long *ending_dma = ide_get_hwifdata(hwif);
@@ -271,7 +271,7 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
/* returns 1 if dma irq issued, 0 otherwise */
static int sgiioc4_dma_test_irq(ide_drive_t *drive)
{
- return sgiioc4_checkirq(HWIF(drive));
+ return sgiioc4_checkirq(drive->hwif);
}
static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
@@ -367,7 +367,7 @@ static void
sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
{
u32 ioc4_dma;
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long dma_base = hwif->dma_base;
unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
u32 dma_addr, ending_dma_addr;
@@ -427,7 +427,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
static unsigned int
sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned int *table = hwif->dmatable_cpu;
unsigned int count = 0, i = 1;
struct scatterlist *sg;
@@ -492,7 +492,7 @@ use_pio_instead:
static int sgiioc4_dma_setup(ide_drive_t *drive)
{
- struct request *rq = HWGROUP(drive)->rq;
+ struct request *rq = drive->hwif->rq;
unsigned int count = 0;
int ddir;
@@ -523,7 +523,6 @@ static const struct ide_tp_ops sgiioc4_tp_ops = {
.exec_command = ide_exec_command,
.read_status = sgiioc4_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index 7d622d2..cb2b352 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -114,7 +114,7 @@ static unsigned long siimage_selreg(ide_hwif_t *hwif, int r)
static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long base = (unsigned long)hwif->hwif_data;
u8 unit = drive->dn & 1;
@@ -243,7 +243,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio)
static const u16 tf_speed[] = { 0x328a, 0x2283, 0x1281, 0x10c3, 0x10c1 };
static const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 };
- ide_hwif_t *hwif = HWIF(drive);
+ 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;
@@ -300,7 +300,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
static const u8 ultra5[] = { 0x0C, 0x07, 0x05, 0x04, 0x02, 0x01 };
static const u16 dma[] = { 0x2208, 0x10C2, 0x10C1 };
- ide_hwif_t *hwif = HWIF(drive);
+ 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;
@@ -340,7 +340,7 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed)
/* returns 1 if dma irq issued, 0 otherwise */
static int siimage_io_dma_test_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ 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);
@@ -367,7 +367,7 @@ 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 = HWIF(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];
@@ -717,6 +717,7 @@ static const struct ide_dma_ops sil_dma_ops = {
.dma_test_irq = siimage_dma_test_irq,
.dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
#define DECLARE_SII_DEV(p_ops) \
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index ad32e18..9ec1a4a 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -274,7 +274,7 @@ static void sis_program_timings(ide_drive_t *drive, const u8 mode)
static void config_drive_art_rwp(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 reg4bh = 0;
u8 rw_prefetch = 0;
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 84dc336..48cc748 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -140,7 +140,7 @@ static inline void sl82c105_reset_host(struct pci_dev *dev)
*/
static void sl82c105_dma_lost_irq(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
u8 dma_cmd;
@@ -177,7 +177,7 @@ static void sl82c105_dma_lost_irq(ide_drive_t *drive)
*/
static void sl82c105_dma_start(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
int reg = 0x44 + drive->dn * 4;
@@ -299,6 +299,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = sl82c105_dma_lost_irq,
.dma_timeout = sl82c105_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_port_info sl82c105_chipset __devinitdata = {
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index 0f759e4..40b4b94 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -20,7 +20,7 @@ static DEFINE_SPINLOCK(slc90e66_lock);
static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = HWIF(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;
@@ -73,7 +73,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(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);
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index 93e2cce..84109f5 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -15,7 +15,7 @@
static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00);
u16 mode, scr = inw(scr_port);
@@ -62,13 +62,12 @@ static void tc86c001_set_pio_mode(ide_drive_t *drive, const u8 pio)
*/
static int tc86c001_timer_expiry(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
ide_expiry_t *expiry = ide_get_hwifdata(hwif);
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* Restore a higher level driver's expiry handler first. */
- hwgroup->expiry = expiry;
+ hwif->expiry = expiry;
if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */
unsigned long sc_base = hwif->config_data;
@@ -110,11 +109,10 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
static void tc86c001_dma_start(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
- ide_hwgroup_t *hwgroup = HWGROUP(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 = hwgroup->rq->nr_sectors;
+ unsigned long nsectors = hwif->rq->nr_sectors;
/*
* We have to manually load the sector count and size into
@@ -125,8 +123,8 @@ static void tc86c001_dma_start(ide_drive_t *drive)
outw(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */
/* Install our timeout expiry hook, saving the current handler... */
- ide_set_hwifdata(hwif, hwgroup->expiry);
- hwgroup->expiry = &tc86c001_timer_expiry;
+ ide_set_hwifdata(hwif, hwif->expiry);
+ hwif->expiry = &tc86c001_timer_expiry;
ide_dma_start(drive);
}
@@ -190,6 +188,7 @@ static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_port_info tc86c001_chipset __devinitdata = {
diff --git a/drivers/ide/triflex.c b/drivers/ide/triflex.c
index b6ff403..8773c3b 100644
--- a/drivers/ide/triflex.c
+++ b/drivers/ide/triflex.c
@@ -36,7 +36,7 @@
static void triflex_set_mode(ide_drive_t *drive, const u8 speed)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct pci_dev *dev = to_pci_dev(hwif->dev);
u32 triflex_timings = 0;
u16 timing = 0;
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index 2a5ea90..b6a1285 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -144,7 +144,7 @@
static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
u16 reg = 0;
unsigned long flags;
@@ -184,7 +184,7 @@ static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
static int trm290_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
unsigned int count, rw;
if (rq_data_dir(rq)) {
@@ -222,15 +222,15 @@ static int trm290_dma_end(ide_drive_t *drive)
drive->waiting_for_dma = 0;
/* purge DMA mappings */
ide_destroy_dmatable(drive);
- status = inw(HWIF(drive)->dma_base + 2);
+ status = inw(drive->hwif->dma_base + 2);
+
return status != 0x00ff;
}
static int trm290_dma_test_irq(ide_drive_t *drive)
{
- u16 status;
+ u16 status = inw(drive->hwif->dma_base + 2);
- status = inw(HWIF(drive)->dma_base + 2);
return status == 0x00ff;
}
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 4a8c5a2..882f6f0 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -293,7 +293,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
- struct request *rq = hwif->hwgroup->rq;
+ struct request *rq = hwif->rq;
u8 reading;
int nent;
@@ -397,6 +397,17 @@ static int tx4939ide_dma_test_irq(ide_drive_t *drive)
return found;
}
+#ifdef __BIG_ENDIAN
+static u8 tx4939ide_dma_sff_read_status(ide_hwif_t *hwif)
+{
+ void __iomem *base = TX4939IDE_BASE(hwif);
+
+ return tx4939ide_readb(base, TX4939IDE_DMA_Stat);
+}
+#else
+#define tx4939ide_dma_sff_read_status ide_dma_sff_read_status
+#endif
+
static void tx4939ide_init_hwif(ide_hwif_t *hwif)
{
void __iomem *base = TX4939IDE_BASE(hwif);
@@ -443,13 +454,6 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
#ifdef __BIG_ENDIAN
-static u8 tx4939ide_read_sff_dma_status(ide_hwif_t *hwif)
-{
- void __iomem *base = TX4939IDE_BASE(hwif);
-
- return tx4939ide_readb(base, TX4939IDE_DMA_Stat);
-}
-
/* custom iops (independent from SWAP_IO_SPACE) */
static u8 tx4939ide_inb(unsigned long port)
{
@@ -585,7 +589,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = tx4939ide_read_sff_dma_status,
.set_irq = ide_set_irq,
@@ -609,7 +612,6 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .read_sff_dma_status = ide_read_sff_dma_status,
.set_irq = ide_set_irq,
@@ -638,6 +640,7 @@ static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_test_irq = tx4939ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timeout = ide_dma_timeout,
+ .dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
static const struct ide_port_info tx4939ide_port_info __initdata = {
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c
index e29978c..0608d41 100644
--- a/drivers/ide/umc8672.c
+++ b/drivers/ide/umc8672.c
@@ -106,22 +106,21 @@ static void umc_set_speeds(u8 speeds[])
static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- ide_hwif_t *hwif = drive->hwif;
- ide_hwgroup_t *mate_hwgroup = hwif->mate ? hwif->mate->hwgroup : NULL;
+ ide_hwif_t *hwif = drive->hwif, *mate = hwif->mate;
unsigned long uninitialized_var(flags);
printk("%s: setting umc8672 to PIO mode%d (speed %d)\n",
drive->name, pio, pio_to_umc[pio]);
- if (mate_hwgroup)
- spin_lock_irqsave(&mate_hwgroup->lock, flags);
- if (mate_hwgroup && mate_hwgroup->handler) {
+ if (mate)
+ spin_lock_irqsave(&mate->lock, flags);
+ if (mate && mate->handler) {
printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n");
} else {
current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio];
umc_set_speeds(current_speeds);
}
- if (mate_hwgroup)
- spin_unlock_irqrestore(&mate_hwgroup->lock, flags);
+ if (mate)
+ spin_unlock_irqrestore(&mate->lock, flags);
}
static const struct ide_port_ops umc8672_port_ops = {
diff --git a/drivers/ide/via82cxxx.c b/drivers/ide/via82cxxx.c
index 2a812d3..fecc0e0 100644
--- a/drivers/ide/via82cxxx.c
+++ b/drivers/ide/via82cxxx.c
@@ -178,7 +178,7 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed)
ide_timing_merge(&p, &t, &t, IDE_TIMING_8BIT);
}
- via_set_speed(HWIF(drive), drive->dn, &t);
+ via_set_speed(hwif, drive->dn, &t);
}
/**
diff --git a/include/linux/ide.h b/include/linux/ide.h
index db5ef8a..3644f63 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -32,18 +32,14 @@
# define SUPPORT_VLB_SYNC 1
#endif
-typedef unsigned char byte; /* used everywhere */
-
/*
* Probably not wise to fiddle with these
*/
+#define IDE_DEFAULT_MAX_FAILURES 1
#define ERROR_MAX 8 /* Max read/write errors per sector */
#define ERROR_RESET 3 /* Reset controller every 4th retry */
#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */
-#define HWIF(drive) ((ide_hwif_t *)((drive)->hwif))
-#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))
-
/*
* Definitions for accessing IDE controller registers
*/
@@ -185,9 +181,6 @@ typedef struct hw_regs_s {
unsigned long config;
} hw_regs_t;
-void ide_init_port_data(struct hwif_s *, unsigned int);
-void ide_init_port_hw(struct hwif_s *, hw_regs_t *);
-
static inline void ide_std_init_ports(hw_regs_t *hw,
unsigned long io_addr,
unsigned long ctl_addr)
@@ -433,18 +426,14 @@ struct ide_atapi_pc {
struct idetape_bh *bh;
char *b_data;
- /* idescsi only for now */
struct scatterlist *sg;
unsigned int sg_cnt;
- struct scsi_cmnd *scsi_cmd;
- void (*done) (struct scsi_cmnd *);
-
unsigned long timeout;
};
struct ide_devset;
-struct ide_driver_s;
+struct ide_driver;
#ifdef CONFIG_BLK_DEV_IDEACPI
struct ide_acpi_drive_link;
@@ -588,7 +577,6 @@ struct ide_drive_s {
struct request_queue *queue; /* request queue */
struct request *rq; /* current request */
- struct ide_drive_s *next; /* circular list of hwgroup drives */
void *driver_data; /* extra driver data */
u16 *id; /* identification info */
#ifdef CONFIG_IDE_PROC_FS
@@ -662,6 +650,8 @@ struct ide_drive_s {
int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *,
unsigned int, int);
+ ide_startstop_t (*irq_handler)(struct ide_drive_s *);
+
unsigned long atapi_flags;
struct ide_atapi_pc request_sense_pc;
@@ -684,7 +674,6 @@ struct ide_tp_ops {
void (*exec_command)(struct hwif_s *, u8);
u8 (*read_status)(struct hwif_s *);
u8 (*read_altstatus)(struct hwif_s *);
- u8 (*read_sff_dma_status)(struct hwif_s *);
void (*set_irq)(struct hwif_s *, int);
@@ -745,14 +734,17 @@ struct ide_dma_ops {
int (*dma_test_irq)(struct ide_drive_s *);
void (*dma_lost_irq)(struct ide_drive_s *);
void (*dma_timeout)(struct ide_drive_s *);
+ /*
+ * The following method is optional and only required to be
+ * implemented for the SFF-8038i compatible controllers.
+ */
+ u8 (*dma_sff_read_status)(struct hwif_s *);
};
struct ide_host;
typedef struct hwif_s {
- struct hwif_s *next; /* for linked-list in ide_hwgroup_t */
struct hwif_s *mate; /* other hwif from same PCI chip */
- struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
struct ide_host *host;
@@ -763,7 +755,7 @@ typedef struct hwif_s {
unsigned long sata_scr[SATA_NR_PORTS];
- ide_drive_t drives[MAX_DRIVES]; /* drive info */
+ ide_drive_t *devices[MAX_DRIVES + 1];
u8 major; /* our major number */
u8 index; /* 0 for ide0; 1 for ide1; ... */
@@ -829,7 +821,7 @@ typedef struct hwif_s {
unsigned extra_ports; /* number of extra dma ports */
unsigned present : 1; /* this interface exists */
- unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
+ unsigned busy : 1; /* serializes devices on a port */
struct device gendev;
struct device *portdev;
@@ -841,19 +833,49 @@ typedef struct hwif_s {
#ifdef CONFIG_BLK_DEV_IDEACPI
struct ide_acpi_hwif_link *acpidata;
#endif
+
+ /* IRQ handler, if active */
+ ide_startstop_t (*handler)(ide_drive_t *);
+
+ /* BOOL: polling active & poll_timeout field valid */
+ unsigned int polling : 1;
+
+ /* current drive */
+ ide_drive_t *cur_dev;
+
+ /* current request */
+ struct request *rq;
+
+ /* failsafe timer */
+ struct timer_list timer;
+ /* timeout value during long polls */
+ unsigned long poll_timeout;
+ /* queried upon timeouts */
+ int (*expiry)(ide_drive_t *);
+
+ int req_gen;
+ int req_gen_timer;
+
+ spinlock_t lock;
} ____cacheline_internodealigned_in_smp ide_hwif_t;
#define MAX_HOST_PORTS 4
struct ide_host {
- ide_hwif_t *ports[MAX_HOST_PORTS];
+ ide_hwif_t *ports[MAX_HOST_PORTS + 1];
unsigned int n_ports;
struct device *dev[2];
unsigned int (*init_chipset)(struct pci_dev *);
unsigned long host_flags;
void *host_priv;
+ ide_hwif_t *cur_port; /* for hosts requiring serialization */
+
+ /* used for hosts requiring serialization */
+ volatile long host_busy;
};
+#define IDE_HOST_BUSY 0
+
/*
* internal ide interrupt handler type
*/
@@ -863,38 +885,6 @@ typedef int (ide_expiry_t)(ide_drive_t *);
/* used by ide-cd, ide-floppy, etc. */
typedef void (xfer_func_t)(ide_drive_t *, struct request *rq, void *, unsigned);
-typedef struct hwgroup_s {
- /* irq handler, if active */
- ide_startstop_t (*handler)(ide_drive_t *);
-
- /* BOOL: protects all fields below */
- volatile int busy;
- /* BOOL: polling active & poll_timeout field valid */
- unsigned int polling : 1;
-
- /* current drive */
- ide_drive_t *drive;
- /* ptr to current hwif in linked-list */
- ide_hwif_t *hwif;
-
- /* current request */
- struct request *rq;
-
- /* failsafe timer */
- struct timer_list timer;
- /* timeout value during long polls */
- unsigned long poll_timeout;
- /* queried upon timeouts */
- int (*expiry)(ide_drive_t *);
-
- int req_gen;
- int req_gen_timer;
-
- spinlock_t lock;
-} ide_hwgroup_t;
-
-typedef struct ide_driver_s ide_driver_t;
-
extern struct mutex ide_setting_mtx;
/*
@@ -1020,8 +1010,8 @@ void ide_proc_register_port(ide_hwif_t *);
void ide_proc_port_register_devices(ide_hwif_t *);
void ide_proc_unregister_device(ide_drive_t *);
void ide_proc_unregister_port(ide_hwif_t *);
-void ide_proc_register_driver(ide_drive_t *, ide_driver_t *);
-void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *);
+void ide_proc_register_driver(ide_drive_t *, struct ide_driver *);
+void ide_proc_unregister_driver(ide_drive_t *, struct ide_driver *);
read_proc_t proc_ide_read_capacity;
read_proc_t proc_ide_read_geometry;
@@ -1048,8 +1038,10 @@ static inline void ide_proc_register_port(ide_hwif_t *hwif) { ; }
static inline void ide_proc_port_register_devices(ide_hwif_t *hwif) { ; }
static inline void ide_proc_unregister_device(ide_drive_t *drive) { ; }
static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; }
-static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
-static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; }
+static inline void ide_proc_register_driver(ide_drive_t *drive,
+ struct ide_driver *driver) { ; }
+static inline void ide_proc_unregister_driver(ide_drive_t *drive,
+ struct ide_driver *driver) { ; }
#define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0;
#endif
@@ -1118,11 +1110,10 @@ void ide_check_pm_state(ide_drive_t *, struct request *);
* The gendriver.owner field should be set to the module owner of this driver.
* The gendriver.name field should be set to the name of this driver
*/
-struct ide_driver_s {
+struct ide_driver {
const char *version;
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
int (*end_request)(ide_drive_t *, int, int);
- ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8);
struct device_driver gen_driver;
int (*probe)(ide_drive_t *);
void (*remove)(ide_drive_t *);
@@ -1134,7 +1125,7 @@ struct ide_driver_s {
#endif
};
-#define to_ide_driver(drv) container_of(drv, ide_driver_t, gen_driver)
+#define to_ide_driver(drv) container_of(drv, struct ide_driver, gen_driver)
int ide_device_get(ide_drive_t *);
void ide_device_put(ide_drive_t *);
@@ -1166,9 +1157,7 @@ void ide_execute_pkt_cmd(ide_drive_t *);
void ide_pad_transfer(ide_drive_t *, int, int);
-ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8);
-
-ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
+ide_startstop_t ide_error(ide_drive_t *, const char *, u8);
void ide_fix_driveid(u16 *);
@@ -1192,7 +1181,6 @@ void ide_tf_dump(const char *, struct ide_taskfile *);
void ide_exec_command(ide_hwif_t *, u8);
u8 ide_read_status(ide_hwif_t *);
u8 ide_read_altstatus(ide_hwif_t *);
-u8 ide_read_sff_dma_status(ide_hwif_t *);
void ide_set_irq(ide_hwif_t *, int);
@@ -1272,26 +1260,6 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id);
-
-static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)
-{
- if (hwgroup->busy)
- return 1;
-
- hwgroup->busy = 1;
- /* for atari only */
- ide_get_lock(ide_intr, hwgroup);
-
- return 0;
-}
-
-static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
-{
- /* for atari only */
- ide_release_lock();
- hwgroup->busy = 0;
-}
-
extern void do_ide_request(struct request_queue *);
void ide_init_disk(struct gendisk *, ide_drive_t *);
@@ -1327,11 +1295,11 @@ static inline int ide_hwif_setup_dma(ide_hwif_t *hwif,
}
#endif
-typedef struct ide_pci_enablebit_s {
+struct ide_pci_enablebit {
u8 reg; /* byte pci reg holding the enable-bit */
u8 mask; /* mask to isolate the enable-bit */
u8 val; /* value of masked reg when "enabled" */
-} ide_pci_enablebit_t;
+};
enum {
/* Uses ISA control ports not PCI ones. */
@@ -1420,7 +1388,8 @@ struct ide_port_info {
const struct ide_port_ops *port_ops;
const struct ide_dma_ops *dma_ops;
- ide_pci_enablebit_t enablebits[2];
+ struct ide_pci_enablebit enablebits[2];
+
hwif_chipset_t chipset;
u16 max_sectors; /* if < than the default one */
@@ -1492,6 +1461,7 @@ void ide_dma_exec_cmd(ide_drive_t *, u8);
extern void ide_dma_start(ide_drive_t *);
int ide_dma_end(ide_drive_t *);
int ide_dma_test_irq(ide_drive_t *);
+u8 ide_dma_sff_read_status(ide_hwif_t *);
extern const struct ide_dma_ops sff_dma_ops;
#else
static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
@@ -1529,9 +1499,6 @@ static inline void ide_acpi_port_init_devices(ide_hwif_t *hwif) { ; }
static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {}
#endif
-void ide_remove_port_from_hwgroup(ide_hwif_t *);
-void ide_unregister(ide_hwif_t *);
-
void ide_register_region(struct gendisk *);
void ide_unregister_region(struct gendisk *);
@@ -1616,23 +1583,6 @@ static inline void ide_set_max_pio(ide_drive_t *drive)
ide_set_pio(drive, 255);
}
-extern spinlock_t ide_lock;
-extern struct mutex ide_cfg_mtx;
-/*
- * Structure locking:
- *
- * ide_cfg_mtx and hwgroup->lock together protect changes to
- * ide_hwif_t->next
- * ide_drive_t->next
- *
- * ide_hwgroup_t->busy: hwgroup->lock
- * ide_hwgroup_t->hwif: hwgroup->lock
- * ide_hwif_t->{hwgroup,mate}: constant, no locking
- * ide_drive_t->hwif: constant, no locking
- */
-
-#define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0)
-
char *ide_media_string(ide_drive_t *);
extern struct device_attribute ide_dev_attrs[];
@@ -1651,8 +1601,15 @@ static inline int hwif_to_node(ide_hwif_t *hwif)
static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive)
{
- ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1];
+ ide_drive_t *peer = drive->hwif->devices[(drive->dn ^ 1) & 1];
return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL;
}
+
+#define ide_port_for_each_dev(i, dev, port) \
+ for ((i) = 0; ((dev) = (port)->devices[i]) || (i) < MAX_DRIVES; (i)++)
+
+#define ide_host_for_each_port(i, port, host) \
+ for ((i) = 0; ((port) = (host)->ports[i]) || (i) < MAX_HOST_PORTS; (i)++)
+
#endif /* _IDE_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 218c73b..d543365 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1658,6 +1658,7 @@
#define PCI_VENDOR_ID_ROCKWELL 0x127A
#define PCI_VENDOR_ID_ITE 0x1283
+#define PCI_DEVICE_ID_ITE_8172 0x8172
#define PCI_DEVICE_ID_ITE_8211 0x8211
#define PCI_DEVICE_ID_ITE_8212 0x8212
#define PCI_DEVICE_ID_ITE_8213 0x8213
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [git pull] IDE updates part 3
@ 2009-03-31 19:35 Bartlomiej Zolnierkiewicz
0 siblings, 0 replies; 3+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-03-31 19:35 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, Stephen Rothwell, linux-ide, linux-kernel
Hi,
Part 3, some interesting stuff this time:
- ide-atapi: build fix for non-x86 archs (Geert Uytterhoeven)
- ide-cd: regression fix, start DMA after issuing a packet command
(Borislav Petkov)
- ide-park: regressing fix, correct handling of sleeping devices
(Elias Oltmanns)
- ide-pmac: cable detection fix for Apple PowerBook (TOMARI Hisanobu)
and fix allowing modular IDE build (Gilles Espinasse)
- ide-{floppy,tape}: bug fix for padding of PIO transfers
- support for CompactFlash specific transfer modes (Sergei Shtylyov)
- struct ide_tp_ops sanitizations (Sergei Shtylyov)
- ide-cd: conversion to use scatterlists also for PIO transfers
- many other fixes/cleanups, detailed changelog below
Linus, please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git/
to receive the following updates:
CREDITS | 9 +
MAINTAINERS | 15 +-
drivers/ide/Kconfig | 33 +--
drivers/ide/Makefile | 2 -
drivers/ide/alim15x3.c | 10 +-
drivers/ide/at91_ide.c | 39 +--
drivers/ide/au1xxx-ide.c | 26 +--
drivers/ide/cmd64x.c | 6 -
drivers/ide/cs5530.c | 3 +-
drivers/ide/cs5536.c | 1 -
drivers/ide/falconide.c | 4 +-
drivers/ide/gayle.c | 12 +-
drivers/ide/hpt366.c | 10 +-
drivers/ide/ht6560b.c | 20 ++-
drivers/ide/icside.c | 8 -
drivers/ide/ide-atapi.c | 168 +++++---------
drivers/ide/ide-cd.c | 525 +++++++++++++---------------------------
drivers/ide/ide-disk.c | 4 +-
drivers/ide/ide-dma-sff.c | 17 +-
drivers/ide/ide-dma.c | 118 ++++++----
drivers/ide/ide-eh.c | 14 +-
drivers/ide/ide-floppy.c | 29 +--
drivers/ide/ide-floppy_ioctl.c | 5 +-
drivers/ide/ide-generic.c | 86 +------
drivers/ide/ide-h8300.c | 34 +--
drivers/ide/ide-io-std.c | 130 ++++------
drivers/ide/ide-io.c | 27 ++-
drivers/ide/ide-iops.c | 41 ++--
drivers/ide/ide-pm.c | 5 +-
drivers/ide/ide-probe.c | 31 +--
drivers/ide/ide-tape.c | 36 ++--
drivers/ide/ide-taskfile.c | 96 ++++----
drivers/ide/ide-timings.c | 12 +-
drivers/ide/ide-xfer-mode.c | 15 +-
drivers/ide/ide_arm.c | 53 ----
drivers/ide/it821x.c | 3 +-
drivers/ide/ns87415.c | 85 ++++----
drivers/ide/pdc202xx_old.c | 10 +-
drivers/ide/pmac.c | 101 ++++----
drivers/ide/q40ide.c | 4 +-
drivers/ide/qd65xx.c | 21 ++-
drivers/ide/sc1200.c | 7 +-
drivers/ide/scc_pata.c | 56 ++---
drivers/ide/sgiioc4.c | 24 +--
drivers/ide/siimage.c | 1 -
drivers/ide/sl82c105.c | 10 +-
drivers/ide/tc86c001.c | 1 -
drivers/ide/trm290.c | 57 +++--
drivers/ide/tx4938ide.c | 41 +---
drivers/ide/tx4939ide.c | 62 ++----
include/linux/ide.h | 56 ++---
51 files changed, 847 insertions(+), 1336 deletions(-)
delete mode 100644 drivers/ide/ide_arm.c
Bartlomiej Zolnierkiewicz (40):
at91_ide: fix ->ftf_flags handling
ide: add support for arbitrary transfer lengths to ide_pio_bytes()
ide: use PageHighMem() instead of ifdefs in ide_pio_bytes()
ide-cd: remove dead URLs
ide-cd: use ide_end_rq() also for failed non-fs requests
ide-cd: remove dead code from cdrom_decode_status()
ide-cd: remove needless ide_dump_status_no_sense() wrapper
ide-cd: remove no longer needed 'ignore' module parameter
ide-cd: factor out failed request completion from cdrom_end_request()
ide-cd: unify ide_cd_do_request() exit paths
ide-cd: move setting REQ_FAILED flag out from 'end_request' exit path
ide-cd: unify cdrom_newpc_intr() exit paths
ide-cd: remove cdrom_end_request()
ide-cd: kill whole failed request in ide_cd_do_request()
ide-cd: cleanup ide_cd_do_request()
ide-cd: use scatterlists for PIO transfers (fs requests)
ide-cd: fix non-SECTOR_SIZE-multiples PIO transfers for fs requests
ide-cd: merge ide_cd_prepare_rw_request() into cdrom_start_rw()
ide-cd: use scatterlists for PIO transfers (non-fs requests) (v2)
ide-cd: use common completion path for DMA requests in cdrom_newpc_intr()
ide-cd: unify transfer padding in cdrom_newpc_intr()
ide-cd: minor ide_cdrom_setup() cleanup
ide: add ->dma_clear method and remove ->dma_timeout one
ide: inline ide_dma_timeout() into ide_dma_timeout_retry()
ide: destroy DMA mappings after ending DMA (v2)
ide: add ide_dma_prepare() helper
ns87415: use custom ->dma_{start,end} to handle ns87415_prepare_drive()
trm290: use custom ->dma_{start,end} to handle trm290_prepare_drive()
ide: add ->dma_check method
ide: move ide_map_sg() call out of ->dma_setup method (take 2)
ide: set/clear drive->waiting_for_dma flag in the core code
ide: sanitize ide_build_sglist() and ide_destroy_dmatable()
ide-generic: remove no longer needed sysfs interface
ide: merge ide_arm and ide_generic host drivers
ide: fix locking in drive_release_dev()
ide: decrease size of ->pc_buf field in struct ide_atapi_pc
ide: remove CONFIG_BLK_DEV_IDEDOUBLER config option
ide-{floppy,tape}: fix padding for PIO transfers
ide-floppy: use ide_pio_bytes()
MAINTAINERS: move old ide-{floppy,tape} entries to CREDITS (take 2)
Borislav Petkov (2):
ide-atapi: start DMA after issuing a packet command
ide-floppy: do not complete rq's prematurely
Elias Oltmanns (1):
ide: Fix code dealing with sleeping devices in do_ide_request()
Geert Uytterhoeven (1):
ide: drivers/ide/ide-atapi.c needs <linux/scatterlist.h>
Gilles Espinasse (1):
ide: be able to build pmac driver without IDE built-in
Sergei Shtylyov (13):
au1xxx-ide: auide_{in|out}sw() should be static
ide: identify data word 53 bit 1 doesn't cover words 62 and 63 (take 3)
ide-iops: only clear DMA words on setting DMA mode
ide: add support for CFA specified transfer modes (take 3)
ide-disk: use ATA_ERR
ide: use ATA_HOB
ide: turn set_irq() method into write_devctl() method
ide: rename IDE_TFLAG_IN_[HOB_]FEATURE
ide-io-std: shorten ide_{in|out}put_data()
ide: call {in|out}put_data() methods from tf_{read|load}() methods (take 2)
ide: move data register access out of tf_{read|load}() methods (take 2)
ide: turn selectproc() method into dev_select() method (take 5)
ide: inline SELECT_DRIVE()
TOMARI Hisanobu (1):
ide-pmac: IDE cable detection on Apple PowerBook
diff --git a/CREDITS b/CREDITS
index e8b7d36..9a93e3e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -495,6 +495,11 @@ S: Kopmansg 2
S: 411 13 Goteborg
S: Sweden
+N: Paul Bristow
+E: paul@paulbristow.net
+W: http://paulbristow.net/linux/idefloppy.html
+D: Maintainer of IDE/ATAPI floppy driver
+
N: Dominik Brodowski
E: linux@brodo.de
W: http://www.brodo.de/
@@ -2642,6 +2647,10 @@ S: C/ Mieses 20, 9-B
S: Valladolid 47009
S: Spain
+N: Gadi Oxman
+E: gadio@netvision.net.il
+D: Original author and maintainer of IDE/ATAPI floppy/tape drivers
+
N: Greg Page
E: gpage@sovereign.org
D: IPX development and support
diff --git a/MAINTAINERS b/MAINTAINERS
index c5f4e9d..d20c786 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2201,25 +2201,12 @@ L: linux-ide@vger.kernel.org
T: quilt kernel.org/pub/linux/kernel/people/bart/pata-2.6/
S: Maintained
-IDE/ATAPI CDROM DRIVER
+IDE/ATAPI DRIVERS
P: Borislav Petkov
M: petkovbb@gmail.com
L: linux-ide@vger.kernel.org
S: Maintained
-IDE/ATAPI FLOPPY DRIVERS
-P: Paul Bristow
-M: Paul Bristow <paul@paulbristow.net>
-W: http://paulbristow.net/linux/idefloppy.html
-L: linux-kernel@vger.kernel.org
-S: Maintained
-
-IDE/ATAPI TAPE DRIVERS
-P: Gadi Oxman
-M: Gadi Oxman <gadio@netvision.net.il>
-L: linux-kernel@vger.kernel.org
-S: Maintained
-
IDLE-I7300
P: Andy Henroid
M: andrew.d.henroid@intel.com
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 640c992..cf06494 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -222,7 +222,8 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
- depends on ALPHA || X86 || IA64 || M32R || MIPS
+ depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
+ default ARM && (ARCH_RPC || ARCH_SHARK)
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
@@ -680,7 +681,7 @@ endif
# TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
config BLK_DEV_IDE_PMAC
tristate "PowerMac on-board IDE support"
- depends on PPC_PMAC && IDE=y
+ depends on PPC_PMAC
select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
@@ -731,11 +732,6 @@ config BLK_DEV_IDE_AT91
depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
select IDE_TIMINGS
-config IDE_ARM
- tristate "ARM IDE support"
- depends on ARM && (ARCH_RPC || ARCH_SHARK)
- default y
-
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
@@ -774,27 +770,20 @@ config BLK_DEV_GAYLE
This includes on-board IDE interfaces on some Amiga models (A600,
A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
bus (M-Tech E-Matrix 530 expansion card).
- Say Y if you have an Amiga with a Gayle IDE interface and want to use
- IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
- it.
- Note that you also have to enable Zorro bus support if you want to
- use Gayle IDE interfaces on the Zorro expansion bus.
-config BLK_DEV_IDEDOUBLER
- bool "Amiga IDE Doubler support (EXPERIMENTAL)"
- depends on BLK_DEV_GAYLE && EXPERIMENTAL
- ---help---
- This feature provides support for the so-called `IDE doublers' (made
+ It also provides support for the so-called `IDE doublers' (made
by various manufacturers, e.g. Eyetech) that can be connected to
the on-board IDE interface of some Amiga models. Using such an IDE
doubler, you can connect up to four instead of two IDE devices to
- the Amiga's on-board IDE interface.
+ the Amiga's on-board IDE interface. The feature is enabled at kernel
+ runtime using the "gayle.doubler" kernel boot parameter.
- Note that the normal Amiga Gayle IDE driver may not work correctly
- if you have an IDE doubler and don't enable this feature!
+ Say Y if you have an Amiga with a Gayle IDE interface and want to use
+ IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
+ it.
- Say Y if you have an IDE doubler. The feature is enabled at kernel
- runtime using the "gayle.doubler" kernel boot parameter.
+ Note that you also have to enable Zorro bus support if you want to
+ use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_BUDDHA
tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 9b4bbe1..81df925 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -21,8 +21,6 @@ ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o
obj-$(CONFIG_IDE) += ide-core.o
-obj-$(CONFIG_IDE_ARM) += ide_arm.o
-
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index d516168..537da1c 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -189,20 +189,20 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * ali15x3_dma_setup - begin a DMA phase
+ * ali_dma_check - DMA check
* @drive: target device
* @cmd: command
*
* Returns 1 if the DMA cannot be performed, zero on success.
*/
-static int ali15x3_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
if (cmd->tf_flags & IDE_TFLAG_WRITE)
return 1; /* try PIO instead of DMA */
}
- return ide_dma_setup(drive, cmd);
+ return 0;
}
/**
@@ -503,13 +503,13 @@ static const struct ide_port_ops ali_port_ops = {
static const struct ide_dma_ops ali_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ali15x3_dma_setup,
+ .dma_setup = ide_dma_setup,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_check = ali_dma_check,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index 2754712..8eda552 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -192,15 +192,9 @@ static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_taskfile *tf = &cmd->tf;
u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (cmd->tf_flags & IDE_FTFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (cmd->tf_flags & IDE_FTFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- at91_ide_output_data(drive, NULL, &data, 2);
- }
-
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -233,19 +227,11 @@ static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
- if (cmd->tf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data;
-
- at91_ide_input_data(drive, NULL, &data, 2);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = ide_mm_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = ide_mm_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = ide_mm_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -258,18 +244,18 @@ static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = ide_mm_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = ide_mm_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = ide_mm_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
+ tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
+ tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
+ tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
+ tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
}
}
@@ -295,8 +281,9 @@ 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,
- .set_irq = ide_set_irq,
+ .write_devctl = ide_write_devctl,
+ .dev_select = ide_dev_select,
.tf_load = at91_ide_tf_load,
.tf_read = at91_ide_tf_read,
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index d3a9d6c..4601364 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -50,7 +50,7 @@ static _auide_hwif auide_hwif;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
-void auide_insw(unsigned long port, void *addr, u32 count)
+static inline void auide_insw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
@@ -68,7 +68,7 @@ void auide_insw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outsw(unsigned long port, void *addr, u32 count)
+static inline void auide_outsw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
@@ -236,7 +236,7 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (++count >= PRD_ENTRIES) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
}
/* Lets enable intr for the last descriptor only */
@@ -272,16 +272,11 @@ static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (count)
return 1;
- use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_destroy_dmatable(drive);
-
return 0;
}
@@ -292,12 +287,9 @@ static void auide_dma_start(ide_drive_t *drive )
static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- if (auide_build_dmatable(drive, cmd) == 0) {
- ide_map_sg(drive, cmd);
+ if (auide_build_dmatable(drive, cmd) == 0)
return 1;
- }
- drive->waiting_for_dma = 1;
return 0;
}
@@ -322,16 +314,11 @@ static void auide_dma_host_set(ide_drive_t *drive, int on)
static void auide_ddma_tx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
-
#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)
@@ -353,7 +340,6 @@ static const struct ide_dma_ops au1xxx_dma_ops = {
.dma_end = auide_dma_end,
.dma_test_irq = auide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
@@ -481,9 +467,9 @@ static const struct ide_tp_ops au1xxx_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index bf0e3f4..80b777e 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -318,7 +318,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
/* get DMA status */
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* read DMA command state */
@@ -327,8 +326,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
/* clear the INTR & ERROR bits */
outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
@@ -384,7 +381,6 @@ static const struct ide_dma_ops cmd64x_dma_ops = {
.dma_test_irq = cmd64x_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -396,7 +392,6 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -408,7 +403,6 @@ static const struct ide_dma_ops cmd648_dma_ops = {
.dma_test_irq = cmd648_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 8e8b35a..40bf05e 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -92,8 +92,7 @@ static u8 cs5530_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
- if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
- (mateid[ATA_ID_MWDMA_MODES] & 7))
+ if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
index d5dcf48..353a35b 100644
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -236,7 +236,6 @@ static const struct ide_dma_ops cs5536_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info cs5536_info = {
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index b368a5e..afa2af9 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -89,9 +89,9 @@ static const struct ide_tp_ops falconide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index dc77825..c711951 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -53,11 +53,6 @@
#define GAYLE_NEXT_PORT 0x1000
-#ifndef CONFIG_BLK_DEV_IDEDOUBLER
-#define GAYLE_NUM_HWIFS 1
-#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
-#define GAYLE_HAS_CONTROL_REG 1
-#else /* CONFIG_BLK_DEV_IDEDOUBLER */
#define GAYLE_NUM_HWIFS 2
#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
GAYLE_NUM_HWIFS-1)
@@ -66,8 +61,6 @@
static int ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
/*
* Check and acknowledge the interrupt status
@@ -151,10 +144,7 @@ static int __init gayle_init(void)
found:
printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
a4000 ? 4000 : 1200,
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
- ide_doubler ? ", IDE doubler" :
-#endif
- "");
+ ide_doubler ? ", IDE doubler" : "");
if (a4000) {
phys_base = GAYLE_BASE_4000;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index dbaf184..a0eb87f 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -835,12 +835,6 @@ static int hpt370_dma_end(ide_drive_t *drive)
return ide_dma_end(drive);
}
-static void hpt370_dma_timeout(ide_drive_t *drive)
-{
- hpt370_irq_timeout(drive);
- ide_dma_timeout(drive);
-}
-
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_dma_test_irq(ide_drive_t *drive)
{
@@ -1423,7 +1417,6 @@ static const struct ide_dma_ops hpt37x_dma_ops = {
.dma_test_irq = hpt374_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -1435,7 +1428,7 @@ static const struct ide_dma_ops hpt370_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = hpt370_dma_timeout,
+ .dma_clear = hpt370_irq_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -1447,7 +1440,6 @@ static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = hpt366_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index c7e5c22..2fb0f29 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -103,7 +103,7 @@
/*
* This routine is invoked from ide.c to prepare for access to a given drive.
*/
-static void ht6560b_selectproc (ide_drive_t *drive)
+static void ht6560b_dev_select(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
@@ -143,6 +143,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
#endif
}
local_irq_restore(flags);
+
+ outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
}
/*
@@ -305,15 +307,29 @@ static int probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
+static const struct ide_tp_ops ht6560b_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ht6560b_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
+
static const struct ide_port_ops ht6560b_port_ops = {
.init_dev = ht6560b_init_dev,
.set_pio_mode = ht6560b_set_pio_mode,
- .selectproc = ht6560b_selectproc,
};
static const struct ide_port_info ht6560b_port_info __initdata = {
.name = DRV_NAME,
.chipset = ide_ht6560b,
+ .tp_ops = &ht6560b_tp_ops,
.port_ops = &ht6560b_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */
IDE_HFLAG_NO_DMA |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 51ce404..4e16ce6 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -287,13 +287,8 @@ static int icside_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
- drive->waiting_for_dma = 0;
-
disable_dma(ec->dma);
- /* Teardown mappings after DMA has completed. */
- ide_destroy_dmatable(drive);
-
return get_dma_residue(ec->dma) != 0;
}
@@ -346,8 +341,6 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
set_dma_mode(ec->dma, dma_mode);
- drive->waiting_for_dma = 1;
-
return 0;
}
@@ -377,7 +370,6 @@ static const struct ide_dma_ops icside_v6_dma_ops = {
.dma_start = icside_dma_start,
.dma_end = icside_dma_end,
.dma_test_irq = icside_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
};
#else
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 2fb5d28..3e43b88 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -6,6 +6,8 @@
#include <linux/cdrom.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/scatterlist.h>
+
#include <scsi/scsi.h>
#ifdef DEBUG
@@ -69,56 +71,6 @@ int ide_check_atapi_device(ide_drive_t *drive, const char *s)
}
EXPORT_SYMBOL_GPL(ide_check_atapi_device);
-/* PIO data transfer routine using the scatter gather table. */
-int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int write)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
- struct scatterlist *sg = pc->sg;
- char *buf;
- int count, done = 0;
-
- while (bcount) {
- count = min(sg->length - pc->b_count, bcount);
-
- if (PageHighMem(sg_page(sg))) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
- xf(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = sg_virt(sg);
- xf(drive, NULL, buf + pc->b_count, count);
- }
-
- bcount -= count;
- pc->b_count += count;
- done += count;
-
- if (pc->b_count == sg->length) {
- if (!--pc->sg_cnt)
- break;
- pc->sg = sg = sg_next(sg);
- pc->b_count = 0;
- }
- }
-
- if (bcount) {
- printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
- bcount, write ? "padding with zeros"
- : "discarding data");
- ide_pad_transfer(drive, write, bcount);
- }
-
- return done;
-}
-EXPORT_SYMBOL_GPL(ide_io_buffers);
-
void ide_init_pc(struct ide_atapi_pc *pc)
{
memset(pc, 0, sizeof(*pc));
@@ -324,12 +276,14 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
+ 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, temp;
+ unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
+ u8 write = !!(pc->flags & PC_FLAG_WRITING);
debug_log("Enter %s - interrupt handler\n", __func__);
@@ -340,8 +294,13 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
stat = tp_ops->read_status(hwif);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->dma_ops->dma_end(drive) ||
- (drive->media == ide_tape && (stat & ATA_ERR))) {
+ int rc;
+
+ drive->waiting_for_dma = 0;
+ rc = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+
+ if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
if (drive->media == ide_floppy)
printk(KERN_ERR "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
@@ -357,7 +316,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
- int uptodate;
+ int uptodate, error;
+ unsigned int done;
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
@@ -404,16 +364,24 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
if (blk_special_request(rq)) {
rq->errors = 0;
- ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ done = blk_rq_bytes(rq);
+ error = 0;
} else {
+
if (blk_fs_request(rq) == 0 && uptodate <= 0) {
if (rq->errors == 0)
rq->errors = -EIO;
}
- ide_complete_rq(drive, uptodate ? 0 : -EIO,
- ide_rq_bytes(rq));
+
+ 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);
return ide_stopped;
}
@@ -433,8 +401,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- if (((ireason & ATAPI_IO) == ATAPI_IO) ==
- !!(pc->flags & PC_FLAG_WRITING)) {
+ 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,
@@ -443,45 +410,30 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- if (!(pc->flags & PC_FLAG_WRITING)) {
- /* Reading - Check that we have enough space */
- temp = pc->xferred + bcount;
- if (temp > pc->req_xfer) {
- if (temp > pc->buf_size) {
- printk(KERN_ERR "%s: The device wants to send "
- "us more data than expected - "
- "discarding data\n",
- drive->name);
-
- ide_pad_transfer(drive, 0, bcount);
- goto next_irq;
- }
- debug_log("The device wants to send us more data than "
- "expected - allowing transfer\n");
- }
- xferfunc = tp_ops->input_data;
- } else
- xferfunc = tp_ops->output_data;
-
- if ((drive->media == ide_floppy && !pc->buf) ||
- (drive->media == ide_tape && pc->bh)) {
- int done = drive->pc_io_buffers(drive, pc, bcount,
- !!(pc->flags & PC_FLAG_WRITING));
-
- /* FIXME: don't do partial completions */
- if (drive->media == ide_floppy)
- ide_complete_rq(drive, 0,
- done ? done : ide_rq_bytes(rq));
- } else
- xferfunc(drive, NULL, pc->cur_pos, bcount);
+ 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);
+ }
/* Update the current position */
- pc->xferred += bcount;
- pc->cur_pos += bcount;
+ pc->xferred += done;
+ pc->cur_pos += 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 on that intr.\n",
- rq->cmd[0], bcount);
-next_irq:
/* And set the interrupt handler again */
ide_set_handler(drive, ide_pc_intr, timeout);
return ide_started;
@@ -611,6 +563,10 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
: ide_pc_intr),
timeout);
+ /* Send the actual packet */
+ if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
+ hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
+
/* Begin DMA, if necessary */
if (dev_is_idecd(drive)) {
if (drive->dma)
@@ -622,10 +578,6 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
- /* Send the actual packet */
- if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
- hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
return ide_started;
}
@@ -633,7 +585,6 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_atapi_pc *pc;
ide_hwif_t *hwif = drive->hwif;
- const struct ide_dma_ops *dma_ops = hwif->dma_ops;
ide_expiry_t *expiry = NULL;
struct request *rq = hwif->rq;
unsigned int timeout;
@@ -647,12 +598,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
- if (drive->dma) {
- if (ide_build_sglist(drive, cmd))
- drive->dma = !dma_ops->dma_setup(drive, cmd);
- else
- drive->dma = 0;
- }
+ if (drive->dma)
+ drive->dma = !ide_dma_prepare(drive, cmd);
} else {
pc = drive->pc;
@@ -670,13 +617,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
ide_dma_off(drive);
}
- if ((pc->flags & PC_FLAG_DMA_OK) &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA)) {
- if (ide_build_sglist(drive, cmd))
- drive->dma = !dma_ops->dma_setup(drive, cmd);
- else
- drive->dma = 0;
- }
+ if (pc->flags & PC_FLAG_DMA_OK)
+ drive->dma = !ide_dma_prepare(drive, cmd);
if (!drive->dma)
pc->flags &= ~PC_FLAG_DMA_OK;
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3f630e4..35729a4 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -4,7 +4,7 @@
* Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
* Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
- * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -12,12 +12,9 @@
* See Documentation/cdrom/ide-cd for usage information.
*
* Suggestions are welcome. Patches that work are more welcome though. ;-)
- * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by
- * anonymous ftp from:
- * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
- * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
+ *
+ * Documentation:
+ * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
*
* For historical changelog please see:
* Documentation/ide/ChangeLog.ide-cd.1994-2004
@@ -245,73 +242,34 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
-static void cdrom_end_request(ide_drive_t *drive, int uptodate)
+static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
- struct request *rq = drive->hwif->rq;
- int nsectors = rq->hard_cur_sectors;
-
- ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, uptodate: 0x%x, nsectors: %d",
- rq->cmd[0], uptodate, nsectors);
-
- if (blk_sense_request(rq) && uptodate) {
- /*
- * For REQ_TYPE_SENSE, "rq->buffer" points to the original
- * failed request
- */
- struct request *failed = (struct request *) rq->buffer;
- struct cdrom_info *info = drive->driver_data;
- void *sense = &info->sense_data;
-
- if (failed) {
- if (failed->sense) {
- sense = failed->sense;
- failed->sense_len = rq->sense_len;
- }
- cdrom_analyze_sense_data(drive, failed, sense);
- /*
- * now end the failed request
- */
- if (blk_fs_request(failed)) {
- if (ide_end_rq(drive, failed, -EIO,
- failed->hard_nr_sectors << 9))
- BUG();
- } else {
- if (blk_end_request(failed, -EIO,
- failed->data_len))
- BUG();
- }
- } else
- cdrom_analyze_sense_data(drive, NULL, sense);
- }
-
- if (!rq->current_nr_sectors && blk_fs_request(rq))
- uptodate = 1;
- /* make sure it's fully ended */
- if (blk_pc_request(rq))
- nsectors = (rq->data_len + 511) >> 9;
- if (!nsectors)
- nsectors = 1;
-
- ide_debug_log(IDE_DBG_FUNC, "uptodate: 0x%x, nsectors: %d",
- uptodate, nsectors);
-
- if (blk_fs_request(rq) == 0 && uptodate <= 0 && rq->errors == 0)
- rq->errors = -EIO;
+ /*
+ * For REQ_TYPE_SENSE, "rq->buffer" points to the original
+ * failed request
+ */
+ struct request *failed = (struct request *)rq->buffer;
+ struct cdrom_info *info = drive->driver_data;
+ void *sense = &info->sense_data;
- ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
-}
+ if (failed) {
+ if (failed->sense) {
+ sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }
+ cdrom_analyze_sense_data(drive, failed, sense);
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
-{
- if (st & 0x80)
- return;
- ide_dump_status(drive, msg, st);
+ if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
+ BUG();
+ } else
+ cdrom_analyze_sense_data(drive, NULL, sense);
}
/*
* Returns:
* 0: if the request should be continued.
- * 1: if the request was ended.
+ * 1: if the request will be going through error recovery.
+ * 2: if the request should be ended.
*/
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
@@ -332,12 +290,6 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
err = ide_read_error(drive);
sense_key = err >> 4;
- if (rq == NULL) {
- printk(KERN_ERR PFX "%s: missing rq in %s\n",
- drive->name, __func__);
- return 1;
- }
-
ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, "
"rq->cmd_type: 0x%x, err: 0x%x",
stat, good_stat, rq->cmd[0], rq->cmd_type,
@@ -350,10 +302,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* Just give up.
*/
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
- ide_error(drive, "request sense failure", stat);
- return 1;
-
+ return 2;
} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
/* All other functions, except for READ. */
@@ -456,21 +405,19 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* No point in retrying after an illegal request or data
* protect error.
*/
- ide_dump_status_no_sense(drive, "command error", stat);
+ ide_dump_status(drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/*
* No point in re-trying a zillion times on a bad
* sector. If we got here the error is not correctable.
*/
- ide_dump_status_no_sense(drive,
- "media error (bad sector)",
- stat);
+ ide_dump_status(drive, "media error (bad sector)",
+ stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* disk appears blank ?? */
- ide_dump_status_no_sense(drive, "media error (blank)",
- stat);
+ ide_dump_status(drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ATA_ABORTED) != 0) {
/* go to the default handler for other errors */
@@ -495,14 +442,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
*/
if (stat & ATA_ERR)
cdrom_queue_request_sense(drive, NULL, NULL);
+ return 1;
} else {
blk_dump_rq_flags(rq, PFX "bad rq");
- cdrom_end_request(drive, 0);
+ return 2;
}
- /* retry, or handle the next request */
- return 1;
-
end_request:
if (stat & ATA_ERR) {
struct request_queue *q = drive->queue;
@@ -515,10 +460,9 @@ end_request:
hwif->rq = NULL;
cdrom_queue_request_sense(drive, rq->sense, rq);
+ return 1;
} else
- cdrom_end_request(drive, 0);
-
- return 1;
+ return 2;
}
/*
@@ -562,101 +506,13 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
if (rq->cmd_type == REQ_TYPE_ATA_PC)
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
return -1;
}
-/*
- * Assume that the drive will always provide data in multiples of at least
- * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise.
- */
-static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
+static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_debug_log(IDE_DBG_FUNC, "len: %d", len);
-
- if ((len % SECTOR_SIZE) == 0)
- return 0;
+ struct request *rq = cmd->rq;
- printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name,
- __func__, len);
-
- if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
- printk(KERN_ERR PFX "This drive is not supported by this "
- "version of the driver\n");
- else {
- printk(KERN_ERR PFX "Trying to limit transfer sizes\n");
- drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
- }
-
- return 1;
-}
-
-static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
- struct request *rq)
-{
- ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags);
-
- if (rq_data_dir(rq) == READ) {
- unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
- int nskip = rq->sector & (sectors_per_frame - 1);
-
- /*
- * If the requested sector doesn't start on a frame boundary,
- * we must adjust the start of the transfer so that it does,
- * and remember to skip the first few sectors.
- *
- * If the rq->current_nr_sectors field is larger than the size
- * of the buffer, it will mean that we're to skip a number of
- * sectors equal to the amount by which rq->current_nr_sectors
- * is larger than the buffer size.
- */
- if (nskip > 0) {
- /* sanity check... */
- if (rq->current_nr_sectors !=
- bio_cur_sectors(rq->bio)) {
- printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- rq->current_nr_sectors += nskip;
- }
- }
-
- /* set up the command */
- rq->timeout = ATAPI_WAIT_PC;
-
- return ide_started;
-}
-
-/*
- * Fix up a possibly partially-processed request so that we can start it over
- * entirely, or even put it back on the request queue.
- */
-static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
-{
-
- ide_debug_log(IDE_DBG_FUNC, "enter");
-
- if (rq->buffer != bio_data(rq->bio)) {
- sector_t n =
- (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
-
- rq->buffer = bio_data(rq->bio);
- rq->nr_sectors += n;
- rq->sector -= n;
- }
- rq->current_nr_sectors = bio_cur_sectors(rq->bio);
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->hard_nr_sectors = rq->nr_sectors;
- rq->hard_sector = rq->sector;
- rq->q->prep_rq_fn(rq->q, rq);
-}
-
-static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
-{
ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
/*
@@ -664,11 +520,14 @@ static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
* and some drives don't send them. Sigh.
*/
if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
- rq->data_len > 0 && rq->data_len <= 5)
- while (rq->data_len > 0) {
- *(u8 *)rq->data++ = 0;
- --rq->data_len;
+ cmd->nleft > 0 && cmd->nleft <= 5) {
+ unsigned int ofs = cmd->nbytes - cmd->nleft;
+
+ while (cmd->nleft > 0) {
+ *((u8 *)rq->data + ofs++) = 0;
+ cmd->nleft--;
}
+ }
}
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -748,24 +607,26 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}
-/*
- * Called from blk_end_request_callback() after the data of the request is
- * completed and before the request itself is completed. By returning value '1',
- * blk_end_request_callback() returns immediately without completing it.
- */
-static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- return 1;
+ 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)
+ ide_complete_rq(drive, 0, nr_bytes);
}
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
- xfer_func_t *xferfunc;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, stat, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
+ int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
u8 ireason;
@@ -777,7 +638,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
dma = drive->dma;
if (dma) {
drive->dma = 0;
+ drive->waiting_for_dma = 0;
dma_error = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
if (dma_error) {
printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
write ? "write" : "read");
@@ -785,27 +648,24 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
}
}
- if (cdrom_decode_status(drive, 0, &stat))
+ rc = cdrom_decode_status(drive, 0, &stat);
+ if (rc) {
+ if (rc == 2)
+ goto out_end;
return ide_stopped;
+ }
/* using dma, transfer is complete now */
if (dma) {
if (dma_error)
return ide_error(drive, "dma error", stat);
- if (blk_fs_request(rq)) {
- ide_complete_rq(drive, 0, rq->nr_sectors
- ? (rq->nr_sectors << 9) : ide_rq_bytes(rq));
- return ide_stopped;
- } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
- ide_complete_rq(drive, 0, 512);
- return ide_stopped;
- }
- goto end_request;
+ uptodate = 1;
+ goto out_end;
}
ide_read_bcount_and_ireason(drive, &len, &ireason);
- thislen = blk_fs_request(rq) ? len : rq->data_len;
+ thislen = blk_fs_request(rq) ? len : cmd->nleft;
if (thislen > len)
thislen = len;
@@ -820,60 +680,30 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
* Otherwise, complete the command normally.
*/
uptodate = 1;
- if (rq->current_nr_sectors > 0) {
+ if (cmd->nleft > 0) {
printk(KERN_ERR PFX "%s: %s: data underrun "
- "(%d blocks)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
+ "(%u bytes)\n", drive->name, __func__,
+ cmd->nleft);
if (!write)
rq->cmd_flags |= REQ_FAILED;
uptodate = 0;
}
- cdrom_end_request(drive, uptodate);
- return ide_stopped;
} else if (!blk_pc_request(rq)) {
- ide_cd_request_sense_fixup(drive, rq);
+ ide_cd_request_sense_fixup(drive, cmd);
/* complain if we still have data left to transfer */
- uptodate = rq->data_len ? 0 : 1;
+ uptodate = cmd->nleft ? 0 : 1;
+ if (uptodate == 0)
+ rq->cmd_flags |= REQ_FAILED;
}
- goto end_request;
+ goto out_end;
}
/* check which way to transfer data */
- if (ide_cd_check_ireason(drive, rq, len, ireason, write))
- return ide_stopped;
+ rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+ if (rc)
+ goto out_end;
- if (blk_fs_request(rq)) {
- if (write == 0) {
- int nskip;
-
- if (ide_cd_check_transfer_size(drive, len)) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
-
- /*
- * First, figure out if we need to bit-bucket
- * any of the leading sectors.
- */
- nskip = min_t(int, rq->current_nr_sectors
- - bio_cur_sectors(rq->bio),
- thislen >> 9);
- if (nskip > 0) {
- ide_pad_transfer(drive, write, nskip << 9);
- rq->current_nr_sectors -= nskip;
- thislen -= (nskip << 9);
- }
- }
- }
-
- if (ireason == 0) {
- write = 1;
- xferfunc = hwif->tp_ops->output_data;
- } else {
- write = 0;
- xferfunc = hwif->tp_ops->input_data;
- }
+ cmd->last_xfer_len = 0;
ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
"ireason: 0x%x",
@@ -881,75 +711,31 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
/* transfer data */
while (thislen > 0) {
- u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
- int blen = rq->data_len;
-
- /* bio backed? */
- if (rq->bio) {
- if (blk_fs_request(rq)) {
- ptr = rq->buffer;
- blen = rq->current_nr_sectors << 9;
- } else {
- ptr = bio_data(rq->bio);
- blen = bio_iovec(rq->bio)->bv_len;
- }
- }
+ int blen = min_t(int, thislen, cmd->nleft);
- if (!ptr) {
- if (blk_fs_request(rq) && !write)
- /*
- * If the buffers are full, pipe the rest into
- * oblivion.
- */
- ide_pad_transfer(drive, 0, thislen);
- else {
- printk(KERN_ERR PFX "%s: confused, missing data\n",
- drive->name);
- blk_dump_rq_flags(rq, rq_data_dir(rq)
- ? "cdrom_newpc_intr, write"
- : "cdrom_newpc_intr, read");
- }
+ if (cmd->nleft == 0)
break;
- }
-
- if (blen > thislen)
- blen = thislen;
- xferfunc(drive, NULL, ptr, blen);
+ ide_pio_bytes(drive, cmd, write, blen);
+ cmd->last_xfer_len += blen;
thislen -= blen;
len -= blen;
- if (blk_fs_request(rq)) {
- rq->buffer += blen;
- rq->nr_sectors -= (blen >> 9);
- rq->current_nr_sectors -= (blen >> 9);
- rq->sector += (blen >> 9);
-
- if (rq->current_nr_sectors == 0 && rq->nr_sectors)
- cdrom_end_request(drive, 1);
- } else {
- rq->data_len -= blen;
-
- /*
- * The request can't be completed until DRQ is cleared.
- * So complete the data, but don't complete the request
- * using the dummy function for the callback feature
- * of blk_end_request_callback().
- */
- if (rq->bio)
- blk_end_request_callback(rq, 0, blen,
- cdrom_newpc_intr_dummy_cb);
- else
- rq->data += blen;
- }
- if (!write && blk_sense_request(rq))
+ if (sense && write == 0)
rq->sense_len += blen;
}
/* pad, if necessary */
- if (!blk_fs_request(rq) && len > 0)
- ide_pad_transfer(drive, write, len);
+ if (len > 0) {
+ if (blk_fs_request(rq) == 0 || write == 0)
+ ide_pad_transfer(drive, write, len);
+ else {
+ printk(KERN_ERR PFX "%s: confused, missing data\n",
+ drive->name);
+ blk_dump_rq_flags(rq, "cdrom_newpc_intr");
+ }
+ }
if (blk_pc_request(rq)) {
timeout = rq->timeout;
@@ -963,21 +749,50 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
ide_set_handler(drive, cdrom_newpc_intr, timeout);
return ide_started;
-end_request:
- if (blk_pc_request(rq)) {
+out_end:
+ if (blk_pc_request(rq) && rc == 0) {
unsigned int dlen = rq->data_len;
- if (dma)
- rq->data_len = 0;
+ rq->data_len = 0;
if (blk_end_request(rq, 0, dlen))
BUG();
hwif->rq = NULL;
} else {
- if (!uptodate)
- rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, uptodate);
+ if (sense && uptodate)
+ ide_cd_complete_failed_rq(drive, rq);
+
+ if (blk_fs_request(rq)) {
+ if (cmd->nleft == 0)
+ uptodate = 1;
+ } else {
+ if (uptodate <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ }
+
+ if (uptodate == 0)
+ ide_cd_error_cmd(drive, cmd);
+
+ /* 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 (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
+ rq->data_len += cmd->last_xfer_len;
+ }
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ if (sense && rc == 2)
+ ide_error(drive, "request sense failure", stat);
}
return ide_stopped;
}
@@ -985,42 +800,40 @@ end_request:
static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
+ struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
+ queue_hardsect_size(q) >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, "
+ ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
"secs_per_frame: %u",
- rq->cmd[0], write, sectors_per_frame);
+ rq->cmd[0], rq->cmd_flags, sectors_per_frame);
if (write) {
/* disk has become write protected */
- if (get_disk_ro(cd->disk)) {
- cdrom_end_request(drive, 0);
+ if (get_disk_ro(cd->disk))
return ide_stopped;
- }
} else {
/*
* We may be retrying this request after an error. Fix up any
* weirdness which might be present in the request packet.
*/
- ide_cd_restore_request(drive, rq);
+ q->prep_rq_fn(q, rq);
}
- /* use DMA, if possible / writes *must* be hardware frame aligned */
+ /* fs requests *must* be hardware frame aligned */
if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
- (rq->sector & (sectors_per_frame - 1))) {
- if (write) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- drive->dma = 0;
- } else
- drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+ (rq->sector & (sectors_per_frame - 1)))
+ return ide_stopped;
+
+ /* use DMA, if possible */
+ drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
if (write)
cd->devinfo.media_written = 1;
+ rq->timeout = ATAPI_WAIT_PC;
+
return ide_started;
}
@@ -1068,6 +881,7 @@ 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;
ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
rq->cmd[0], (unsigned long long)block);
@@ -1077,10 +891,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
if (blk_fs_request(rq)) {
if (cdrom_start_rw(drive, rq) == ide_stopped)
- return ide_stopped;
-
- if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
- return ide_stopped;
+ goto out_end;
} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
rq->cmd_type == REQ_TYPE_ATA_PC) {
if (!rq->timeout)
@@ -1089,12 +900,13 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
cdrom_do_block_pc(drive, rq);
} else if (blk_special_request(rq)) {
/* right now this can only be a reset... */
- cdrom_end_request(drive, 1);
- return ide_stopped;
+ uptodate = 1;
+ goto out_end;
} else {
blk_dump_rq_flags(rq, DRV_NAME " bad flags");
- cdrom_end_request(drive, 0);
- return ide_stopped;
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ goto out_end;
}
memset(&cmd, 0, sizeof(cmd));
@@ -1104,7 +916,22 @@ 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);
+ ide_map_sg(drive, &cmd);
+ }
+
return ide_issue_pc(drive, &cmd);
+out_end:
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ return ide_stopped;
}
/*
@@ -1696,9 +1523,6 @@ static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
#endif
static const struct cd_list_entry ide_cd_quirks_list[] = {
- /* Limit transfer size per interrupt. */
- { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_AFLAG_LIMIT_NFRAMES },
- { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_AFLAG_LIMIT_NFRAMES },
/* SCR-3231 doesn't support the SET_CD_SPEED command. */
{ "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT },
/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
@@ -1759,18 +1583,18 @@ static int ide_cdrom_setup(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
+ struct request_queue *q = drive->queue;
u16 *id = drive->id;
char *fw_rev = (char *)&id[ATA_ID_FW_REV];
int nslots;
ide_debug_log(IDE_DBG_PROBE, "enter");
- blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
- blk_queue_dma_alignment(drive->queue, 31);
- blk_queue_update_dma_pad(drive->queue, 15);
- drive->queue->unplug_delay = (1 * HZ) / 1000;
- if (!drive->queue->unplug_delay)
- drive->queue->unplug_delay = 1;
+ blk_queue_prep_rq(q, ide_cdrom_prep_fn);
+ 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);
@@ -1788,8 +1612,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities(drive);
- /* set correct block size */
- blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+ blk_queue_hardsect_size(q, CD_FRAMESIZE);
if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1968,9 +1791,6 @@ static struct block_device_operations idecd_ops = {
};
/* module options */
-static char *ignore;
-module_param(ignore, charp, 0400);
-
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);
@@ -1991,15 +1811,6 @@ static int ide_cd_probe(ide_drive_t *drive)
if (drive->media != ide_cdrom && drive->media != ide_optical)
goto failed;
- /* skip drives that we were told to ignore */
- if (ignore != NULL) {
- if (strstr(ignore, drive->name)) {
- printk(KERN_INFO PFX "ignoring drive %s\n",
- drive->name);
- goto failed;
- }
- }
-
drive->debug_mask = debug_mask;
drive->irq_handler = cdrom_newpc_intr;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index ca934c8..c998cf8 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -227,7 +227,7 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
- if ((tf->status & 0x01) == 0)
+ if (!(tf->status & ATA_ERR))
addr = ide_get_lba_addr(tf, lba48) + 1;
return addr;
@@ -267,7 +267,7 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
- if ((tf->status & 0x01) == 0)
+ if (!(tf->status & ATA_ERR))
addr_set = ide_get_lba_addr(tf, lba48) + 1;
return addr_set;
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 75a9ea2..16fc46e 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *drive)
* Enable DMA on any drive that has mode2 DMA
* (multi or single) enabled
*/
- if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */
- if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
- (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
- return 1;
+ if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
+ (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
+ return 1;
/* Consult the list of known "good" drives */
if (ide_dma_good_drive(drive))
@@ -166,8 +165,6 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
EXPORT_SYMBOL_GPL(ide_build_dmatable);
@@ -218,7 +215,6 @@ int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/* clear INTR & ERROR flags */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- drive->waiting_for_dma = 1;
return 0;
}
EXPORT_SYMBOL_GPL(ide_dma_setup);
@@ -292,8 +288,6 @@ int ide_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0, mask;
- drive->waiting_for_dma = 0;
-
/* stop DMA */
if (hwif->host_flags & IDE_HFLAG_MMIO) {
dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
@@ -310,8 +304,6 @@ int ide_dma_end(ide_drive_t *drive)
/* clear INTR & ERROR bits */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
wmb();
/* verify good DMA status */
@@ -338,9 +330,8 @@ const struct ide_dma_ops sff_dma_ops = {
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
EXPORT_SYMBOL_GPL(sff_dma_ops);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 3dbf80c..a0b8cab 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -89,15 +89,16 @@ static const struct drive_list_entry drive_blacklist[] = {
ide_startstop_t ide_dma_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
u8 stat = 0, dma_stat = 0;
+ drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
if (!dma_stat) {
- struct ide_cmd *cmd = &hwif->cmd;
-
if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
ide_finish_cmd(drive, cmd, stat);
else
@@ -117,8 +118,8 @@ int ide_dma_good_drive(ide_drive_t *drive)
}
/**
- * ide_build_sglist - map IDE scatter gather for DMA I/O
- * @drive: the drive to build the DMA table for
+ * ide_dma_map_sg - map IDE scatter gather for DMA I/O
+ * @drive: the drive to map the DMA table for
* @cmd: command
*
* Perform the DMA mapping magic necessary to access the source or
@@ -127,23 +128,19 @@ int ide_dma_good_drive(ide_drive_t *drive)
* operate in a portable fashion.
*/
-int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
+static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
int i;
- ide_map_sg(drive, cmd);
-
if (cmd->tf_flags & IDE_TFLAG_WRITE)
cmd->sg_dma_direction = DMA_TO_DEVICE;
else
cmd->sg_dma_direction = DMA_FROM_DEVICE;
i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
- if (i == 0)
- ide_map_sg(drive, cmd);
- else {
+ if (i) {
cmd->orig_sg_nents = cmd->sg_nents;
cmd->sg_nents = i;
}
@@ -152,7 +149,7 @@ int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
}
/**
- * ide_destroy_dmatable - clean up DMA mapping
+ * ide_dma_unmap_sg - clean up DMA mapping
* @drive: The drive to unmap
*
* Teardown mappings after DMA has completed. This must be called
@@ -162,15 +159,14 @@ int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
* time.
*/
-void ide_destroy_dmatable(ide_drive_t *drive)
+void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct ide_cmd *cmd = &hwif->cmd;
dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents,
cmd->sg_dma_direction);
}
-EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
+EXPORT_SYMBOL_GPL(ide_dma_unmap_sg);
/**
* ide_dma_off_quietly - Generic DMA kill
@@ -249,12 +245,11 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
case XFER_UDMA_0:
if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
break;
-
+ mask = id[ATA_ID_UDMA_MODES];
if (port_ops && port_ops->udma_filter)
- mask = port_ops->udma_filter(drive);
+ mask &= port_ops->udma_filter(drive);
else
- mask = hwif->ultra_mask;
- mask &= id[ATA_ID_UDMA_MODES];
+ mask &= hwif->ultra_mask;
/*
* avoid false cable warning from eighty_ninty_three()
@@ -265,18 +260,23 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
}
break;
case XFER_MW_DMA_0:
- if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
- break;
+ mask = id[ATA_ID_MWDMA_MODES];
+
+ /* Also look for the CF specific MWDMA modes... */
+ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) {
+ u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1;
+
+ mask |= ((2 << mode) - 1) << 3;
+ }
+
if (port_ops && port_ops->mdma_filter)
- mask = port_ops->mdma_filter(drive);
+ mask &= port_ops->mdma_filter(drive);
else
- mask = hwif->mwdma_mask;
- mask &= id[ATA_ID_MWDMA_MODES];
+ mask &= hwif->mwdma_mask;
break;
case XFER_SW_DMA_0:
- if (id[ATA_ID_FIELD_VALID] & 2) {
- mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
- } else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
+ mask = id[ATA_ID_SWDMA_MODES];
+ if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
/*
@@ -284,8 +284,9 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
* (the maximum allowed mode is XFER_SW_DMA_2)
*/
if (mode <= 2)
- mask = ((2 << mode) - 1) & hwif->swdma_mask;
+ mask = (2 << mode) - 1;
}
+ mask &= hwif->swdma_mask;
break;
default:
BUG();
@@ -402,11 +403,10 @@ int ide_id_dma_bug(ide_drive_t *drive)
if ((id[ATA_ID_UDMA_MODES] >> 8) &&
(id[ATA_ID_MWDMA_MODES] >> 8))
goto err_out;
- } else if (id[ATA_ID_FIELD_VALID] & 2) {
- if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
- (id[ATA_ID_SWDMA_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);
@@ -460,21 +460,6 @@ void ide_dma_lost_irq(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
-void ide_dma_timeout(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
-
- if (hwif->dma_ops->dma_test_irq(drive))
- return;
-
- ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
-
- hwif->dma_ops->dma_end(drive);
-}
-EXPORT_SYMBOL_GPL(ide_dma_timeout);
-
/*
* un-busy the port etc, and clear any pending DMA status. we want to
* retry the current request in pio mode instead of risking tossing it
@@ -483,6 +468,8 @@ EXPORT_SYMBOL_GPL(ide_dma_timeout);
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;
@@ -492,12 +479,23 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
if (error < 0) {
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
- (void)hwif->dma_ops->dma_end(drive);
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
ret = ide_error(drive, "dma timeout error",
hwif->tp_ops->read_status(hwif));
} else {
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
- hwif->dma_ops->dma_timeout(drive);
+ if (dma_ops->dma_clear)
+ dma_ops->dma_clear(drive);
+ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ if (dma_ops->dma_test_irq(drive) == 0) {
+ ide_dump_status(drive, "DMA timeout",
+ hwif->tp_ops->read_status(hwif));
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+ }
}
/*
@@ -567,3 +565,25 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif)
return 0;
}
EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops;
+
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
+ (dma_ops->dma_check && dma_ops->dma_check(drive, cmd)))
+ goto out;
+ ide_map_sg(drive, cmd);
+ if (ide_dma_map_sg(drive, cmd) == 0)
+ goto out_map;
+ if (dma_ops->dma_setup(drive, cmd))
+ goto out_dma_unmap;
+ drive->waiting_for_dma = 1;
+ return 0;
+out_dma_unmap:
+ ide_dma_unmap_sg(drive, cmd);
+out_map:
+ ide_map_sg(drive, cmd);
+out:
+ return 1;
+}
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
index 1166497..5d5fb96 100644
--- a/drivers/ide/ide-eh.c
+++ b/drivers/ide/ide-eh.c
@@ -165,11 +165,12 @@ static ide_startstop_t do_reset1(ide_drive_t *, int);
static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u8 stat;
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
udelay(10);
- stat = hwif->tp_ops->read_status(hwif);
+ stat = tp_ops->read_status(hwif);
if (OK_STAT(stat, 0, ATA_BUSY))
printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
@@ -348,7 +349,7 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk && !do_not_try_atapi) {
pre_reset(drive);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
udelay(20);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
ndelay(400);
@@ -401,15 +402,14 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
* immediate interrupt due to the edge transition it produces.
* This single interrupt gives us a "fast poll" for drives that
* recover from reset very quickly, saving us the first 50ms wait time.
- *
- * TODO: add ->softreset method and stop abusing ->set_irq
*/
/* set SRST and nIEN */
- tp_ops->set_irq(hwif, 4);
+ tp_ops->write_devctl(hwif, ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS);
/* more than enough time */
udelay(10);
/* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->set_irq(hwif, drive->quirk_list == 2);
+ tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 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 7ae6623..2b4868d 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -61,16 +61,6 @@
*/
#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
-static void idefloppy_update_buffers(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
-{
- struct request *rq = pc->rq;
- struct bio *bio = rq->bio;
-
- while ((bio = rq->bio) != NULL)
- ide_complete_rq(drive, 0, ide_rq_bytes(rq));
-}
-
static int ide_floppy_callback(ide_drive_t *drive, int dsc)
{
struct ide_disk_obj *floppy = drive->driver_data;
@@ -213,7 +203,6 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
memcpy(rq->cmd, pc->c, 12);
pc->rq = rq;
- pc->b_count = 0;
if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING;
pc->buf = NULL;
@@ -227,7 +216,6 @@ 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;
- pc->b_count = 0;
if (rq->data_len && rq_data_dir(rq) == WRITE)
pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data;
@@ -244,10 +232,11 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
struct request *rq, sector_t block)
{
struct ide_disk_obj *floppy = drive->driver_data;
- ide_hwif_t *hwif = drive->hwif;
struct ide_cmd cmd;
struct ide_atapi_pc *pc;
+ ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]);
+
if (drive->debug_mask & IDE_DBG_RQ)
blk_dump_rq_flags(rq, (rq->rq_disk
? rq->rq_disk->disk_name
@@ -294,13 +283,10 @@ 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, rq->nr_sectors << 9);
+ ide_init_sg_cmd(&cmd, pc->req_xfer);
ide_map_sg(drive, &cmd);
}
- pc->sg = hwif->sg_table;
- pc->sg_cnt = cmd.sg_nents;
-
pc->rq = rq;
return ide_floppy_issue_pc(drive, &cmd, pc);
@@ -385,9 +371,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
- u8 header_len, desc_cnt;
+ u8 pc_buf[256], header_len, desc_cnt;
int i, rc = 1, blocks, length;
+ ide_debug_log(IDE_DBG_FUNC, "enter");
+
drive->bios_cyl = 0;
drive->bios_head = drive->bios_sect = 0;
floppy->blocks = 0;
@@ -395,6 +383,9 @@ 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)) {
printk(KERN_ERR PFX "Can't get floppy parameters\n");
return 1;
@@ -485,8 +476,6 @@ static void ide_floppy_setup(ide_drive_t *drive)
u16 *id = drive->id;
drive->pc_callback = ide_floppy_callback;
- drive->pc_update_buffers = idefloppy_update_buffers;
- drive->pc_io_buffers = ide_io_buffers;
/*
* We used to check revisions here. At this point however I'm giving up.
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index 8f8be85..cd8a420 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
- u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
int __user *argp;
+ u8 pc_buf[256], header_len, desc_cnt;
if (get_user(u_array_size, arg))
return -EFAULT;
@@ -47,6 +47,9 @@ 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)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 9d03e82..7812ca0 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -1,27 +1,22 @@
/*
* generic/default IDE host driver
*
- * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
-/*
- * For special cases new interfaces may be added using sysfs, i.e.
- *
- * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
- *
- * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
- */
-
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci_ids.h>
-/* FIXME: convert m32r to use ide_platform host driver */
+/* FIXME: convert arm and m32r to use ide_platform host driver */
+#ifdef CONFIG_ARM
+#include <asm/irq.h>
+#endif
#ifdef CONFIG_M32R
#include <asm/m32r.h>
#endif
@@ -36,62 +31,11 @@ static const struct ide_port_info ide_generic_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
};
-static ssize_t store_add(struct class *cls, const char *buf, size_t n)
-{
- unsigned int base, ctl;
- int irq, rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
- return -EINVAL;
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = irq;
- hw.chipset = ide_generic;
-
- rc = ide_host_add(&ide_generic_port_info, hws, NULL);
- if (rc)
- return rc;
-
- return n;
-};
-
-static struct class_attribute ide_generic_class_attrs[] = {
- __ATTR(add, S_IWUSR, NULL, store_add),
- __ATTR_NULL
-};
-
-static void ide_generic_class_release(struct class *cls)
-{
- kfree(cls);
-}
-
-static int __init ide_generic_sysfs_init(void)
-{
- struct class *cls;
- int rc;
-
- cls = kzalloc(sizeof(*cls), GFP_KERNEL);
- if (!cls)
- return -ENOMEM;
-
- cls->name = DRV_NAME;
- cls->owner = THIS_MODULE;
- cls->class_release = ide_generic_class_release;
- cls->class_attrs = ide_generic_class_attrs;
-
- rc = class_register(cls);
- if (rc) {
- kfree(cls);
- return rc;
- }
-
- return 0;
-}
-
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
- || defined(CONFIG_PLAT_OPSPUT)
+#ifdef CONFIG_ARM
+static const u16 legacy_bases[] = { 0x1f0 };
+static const int legacy_irqs[] = { IRQ_HARDDISK };
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
+ defined(CONFIG_PLAT_OPSPUT)
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ };
#elif defined(CONFIG_PLAT_MAPPI3)
@@ -107,11 +51,11 @@ static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 };
static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
{
+#ifdef CONFIG_PCI
struct pci_dev *p = NULL;
u16 val;
for_each_pci_dev(p) {
-
if (pci_resource_start(p, 0) == 0x1f0)
*primary = 1;
if (pci_resource_start(p, 2) == 0x170)
@@ -126,7 +70,6 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
if (p->vendor == PCI_VENDOR_ID_INTEL &&
p->device == PCI_DEVICE_ID_INTEL_82371MX) {
-
pci_read_config_word(p, 0x6C, &val);
if (val & 0x8000) {
/* ATA port enabled */
@@ -137,6 +80,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
}
}
}
+#endif
}
static int __init ide_generic_init(void)
@@ -168,6 +112,7 @@ static int __init ide_generic_init(void)
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
"not free.\n",
DRV_NAME, io_addr, io_addr + 7);
+ rc = -EBUSY;
continue;
}
@@ -176,6 +121,7 @@ static int __init ide_generic_init(void)
"not free.\n",
DRV_NAME, io_addr + 0x206);
release_region(io_addr, 8);
+ rc = -EBUSY;
continue;
}
@@ -196,10 +142,6 @@ static int __init ide_generic_init(void)
}
}
- if (ide_generic_sysfs_init())
- printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
- "class\n");
-
return rc;
}
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index ff8339e..dac9a6d 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -54,9 +54,6 @@ static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA)
- mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
-
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -90,18 +87,11 @@ static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
- if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data = mm_inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -114,18 +104,18 @@ static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
+ tf->hob_nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
+ tf->hob_lbal = inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
+ tf->hob_lbam = inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
+ tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
@@ -159,9 +149,9 @@ 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,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = h8300_tf_load,
.tf_read = h8300_tf_read,
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 2d9c6dc..9cac281 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -64,23 +64,26 @@ u8 ide_read_altstatus(ide_hwif_t *hwif)
}
EXPORT_SYMBOL_GPL(ide_read_altstatus);
-void ide_set_irq(ide_hwif_t *hwif, int on)
+void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
if (hwif->host_flags & IDE_HFLAG_MMIO)
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
else
outb(ctl, hwif->io_ports.ctl_addr);
}
-EXPORT_SYMBOL_GPL(ide_set_irq);
+EXPORT_SYMBOL_GPL(ide_write_devctl);
+
+void ide_dev_select(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 select = drive->select | ATA_DEVICE_OBS;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(select, (void __iomem *)hwif->io_ports.device_addr);
+ else
+ outb(select, hwif->io_ports.device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_dev_select);
void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
@@ -99,15 +102,6 @@ void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- if (mmio)
- writew(data, (void __iomem *)io_ports->data_addr);
- else
- outw(data, io_ports->data_addr);
- }
-
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tf_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -153,23 +147,11 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf_inb = ide_inb;
}
- if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data;
-
- if (mmio)
- data = readw((void __iomem *)io_ports->data_addr);
- else
- data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tf_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tf_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -182,18 +164,18 @@ void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = tf_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tf_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
+ tf->hob_nsect = tf_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
+ tf->hob_lbal = tf_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
+ tf->hob_lbam = tf_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
+ tf->hob_lbah = tf_inb(io_ports->lbah_addr);
}
}
EXPORT_SYMBOL_GPL(ide_tf_read);
@@ -225,11 +207,10 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long data_addr = io_ports->data_addr;
+ unsigned int words = (len + 1) >> 1;
u8 io_32bit = drive->io_32bit;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- len++;
-
if (io_32bit) {
unsigned long uninitialized_var(flags);
@@ -238,27 +219,26 @@ void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ata_vlb_sync(io_ports->nsect_addr);
}
+ words >>= 1;
if (mmio)
- __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
+ __ide_mm_insl((void __iomem *)data_addr, buf, words);
else
- insl(data_addr, buf, len / 4);
+ insl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
local_irq_restore(flags);
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- insw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
- else
- insw(data_addr, buf, len / 2);
+ if (((len + 1) & 3) < 2)
+ return;
+
+ buf += len & ~3;
+ words = 1;
}
+
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr, buf, words);
+ else
+ insw(data_addr, buf, words);
}
EXPORT_SYMBOL_GPL(ide_input_data);
@@ -271,11 +251,10 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long data_addr = io_ports->data_addr;
+ unsigned int words = (len + 1) >> 1;
u8 io_32bit = drive->io_32bit;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- len++;
-
if (io_32bit) {
unsigned long uninitialized_var(flags);
@@ -284,27 +263,26 @@ void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
ata_vlb_sync(io_ports->nsect_addr);
}
+ words >>= 1;
if (mmio)
- __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
+ __ide_mm_outsl((void __iomem *)data_addr, buf, words);
else
- outsl(data_addr, buf, len / 4);
+ outsl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
local_irq_restore(flags);
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- outsw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
- else
- outsw(data_addr, buf, len / 2);
+ if (((len + 1) & 3) < 2)
+ return;
+
+ buf += len & ~3;
+ words = 1;
}
+
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr, buf, words);
+ else
+ outsw(data_addr, buf, words);
}
EXPORT_SYMBOL_GPL(ide_output_data);
@@ -312,9 +290,9 @@ const struct ide_tp_ops default_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 1adc5e2..1deb6d2 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -73,6 +73,7 @@ EXPORT_SYMBOL_GPL(ide_end_rq);
void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
{
+ const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
struct ide_taskfile *tf = &cmd->tf;
struct request *rq = cmd->rq;
u8 tf_cmd = tf->command;
@@ -80,7 +81,16 @@ void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
tf->error = err;
tf->status = stat;
- drive->hwif->tp_ops->tf_read(drive, cmd);
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
+ u8 data[2];
+
+ tp_ops->input_data(drive, cmd, data, 2);
+
+ tf->data = data[0];
+ tf->hob_data = data[1];
+ }
+
+ tp_ops->tf_read(drive, cmd);
if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
@@ -338,7 +348,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (blk_pm_request(rq))
ide_check_pm_state(drive, rq);
- SELECT_DRIVE(drive);
+ drive->hwif->tp_ops->dev_select(drive);
if (ide_wait_stat(&startstop, drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ, WAIT_READY)) {
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
@@ -481,11 +491,10 @@ repeat:
prev_port = hwif->host->cur_port;
hwif->rq = NULL;
- if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
- if (time_before(drive->sleep, jiffies)) {
- ide_unlock_port(hwif);
- goto plug_device;
- }
+ if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
+ time_after(drive->sleep, jiffies)) {
+ ide_unlock_port(hwif);
+ goto plug_device;
}
if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
@@ -495,7 +504,9 @@ repeat:
* quirk_list may not like intr setups/cleanups
*/
if (prev_port && prev_port->cur_dev->quirk_list == 0)
- prev_port->tp_ops->set_irq(prev_port, 0);
+ prev_port->tp_ops->write_devctl(prev_port,
+ ATA_NIEN |
+ ATA_DEVCTL_OBS);
hwif->host->cur_port = hwif;
}
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 5403e4a..27bb70d 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,21 +27,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-void SELECT_DRIVE(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- struct ide_cmd cmd;
-
- if (port_ops && port_ops->selectproc)
- port_ops->selectproc(drive);
-
- memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_OUT_DEVICE;
-
- drive->hwif->tp_ops->tf_load(drive, &cmd);
-}
-
void SELECT_MASK(ide_drive_t *drive, int mask)
{
const struct ide_port_ops *port_ops = drive->hwif->port_ops;
@@ -55,7 +40,7 @@ u8 ide_read_error(ide_drive_t *drive)
struct ide_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
- cmd.tf_flags = IDE_TFLAG_IN_FEATURE;
+ cmd.tf_flags = IDE_TFLAG_IN_ERROR;
drive->hwif->tp_ops->tf_read(drive, &cmd);
@@ -306,6 +291,7 @@ int ide_driveid_update(ide_drive_t *drive)
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
+ drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES];
/* anything more ? */
kfree(id);
@@ -356,10 +342,10 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
disable_irq_nosync(hwif->irq);
udelay(1);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
SELECT_MASK(drive, 1);
udelay(1);
- tp_ops->set_irq(hwif, 0);
+ tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
memset(&cmd, 0, sizeof(cmd));
cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
@@ -371,7 +357,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)
- tp_ops->set_irq(hwif, 1);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
error = __ide_wait_stat(drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ | ATA_ERR,
@@ -386,9 +372,14 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error;
}
- id[ATA_ID_UDMA_MODES] &= ~0xFF00;
- id[ATA_ID_MWDMA_MODES] &= ~0x0F00;
- id[ATA_ID_SWDMA_MODES] &= ~0x0F00;
+ if (speed >= XFER_SW_DMA_0) {
+ id[ATA_ID_UDMA_MODES] &= ~0xFF00;
+ id[ATA_ID_MWDMA_MODES] &= ~0x0700;
+ id[ATA_ID_SWDMA_MODES] &= ~0x0700;
+ if (ata_id_is_cfa(id))
+ id[ATA_ID_CFA_MODES] &= ~0x0E00;
+ } else if (ata_id_is_cfa(id))
+ id[ATA_ID_CFA_MODES] &= ~0x01C0;
skip:
#ifdef CONFIG_BLK_DEV_IDEDMA
@@ -401,12 +392,18 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
if (speed >= XFER_UDMA_0) {
i = 1 << (speed - XFER_UDMA_0);
id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
+ } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
+ i = speed - XFER_MW_DMA_2;
+ id[ATA_ID_CFA_MODES] |= i << 9;
} else if (speed >= XFER_MW_DMA_0) {
i = 1 << (speed - XFER_MW_DMA_0);
id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
} else if (speed >= XFER_SW_DMA_0) {
i = 1 << (speed - XFER_SW_DMA_0);
id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
+ } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
+ i = speed - XFER_PIO_4;
+ id[ATA_ID_CFA_MODES] |= i << 6;
}
if (!drive->init_speed)
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index ebf2d21..bb7858e 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -223,6 +223,7 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
* point.
*/
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
struct request_queue *q = drive->queue;
unsigned long flags;
int rc;
@@ -232,8 +233,8 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
- SELECT_DRIVE(drive);
- hwif->tp_ops->set_irq(hwif, 1);
+ tp_ops->dev_select(drive);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
rc = ide_wait_not_busy(hwif, 100000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 5488645..d8c1c3e 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -260,7 +260,7 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
* during the identify phase that the IRQ handler isn't expecting.
*/
if (io_ports->ctl_addr)
- tp_ops->set_irq(hwif, 0);
+ tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */
msleep(50);
@@ -390,13 +390,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
* (e.g. crw9624 as drive0 with disk as slave)
*/
msleep(50);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
msleep(50);
if (ide_read_device(drive) != drive->select && present == 0) {
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
/* allow ATA_BUSY to assert & clear */
msleep(50);
}
@@ -422,7 +422,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
@@ -441,7 +441,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
}
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
msleep(50);
/* ensure drive irq is clear */
(void)tp_ops->read_status(hwif);
@@ -605,6 +605,7 @@ out:
static int ide_port_wait_ready(ide_hwif_t *hwif)
{
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
ide_drive_t *drive;
int i, rc;
@@ -627,8 +628,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
/* Ignore disks that we will not probe for later. */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
(drive->dev_flags & IDE_DFLAG_PRESENT)) {
- SELECT_DRIVE(drive);
- hwif->tp_ops->set_irq(hwif, 1);
+ tp_ops->dev_select(drive);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
mdelay(2);
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
@@ -640,7 +641,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
out:
/* Exit function with master reselected (let's be sane) */
if (i)
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
return rc;
}
@@ -845,7 +846,7 @@ static int init_irq (ide_hwif_t *hwif)
irq_handler = ide_intr;
if (io_ports->ctl_addr)
- hwif->tp_ops->set_irq(hwif, 1);
+ hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
goto out_up;
@@ -942,20 +943,16 @@ EXPORT_SYMBOL_GPL(ide_init_disk);
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
- ide_hwif_t *hwif = drive->hwif;
ide_proc_unregister_device(drive);
- spin_lock_irq(&hwif->lock);
+ blk_cleanup_queue(drive->queue);
+ drive->queue = NULL;
+
kfree(drive->id);
drive->id = NULL;
+
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
- /* Messed up locking ... */
- spin_unlock_irq(&hwif->lock);
- blk_cleanup_queue(drive->queue);
- spin_lock_irq(&hwif->lock);
- drive->queue = NULL;
- spin_unlock_irq(&hwif->lock);
complete(&drive->gendev_rel_comp);
}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 64dfa74..cb942a9 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -297,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
return tape;
}
-static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+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) {
- printk(KERN_ERR "ide-tape: bh == NULL in "
- "idetape_input_buffers\n");
- ide_pad_transfer(drive, 0, bcount);
- return;
- }
+ if (bh == NULL)
+ break;
count = min(
(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
bcount);
@@ -323,21 +319,21 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
atomic_set(&bh->b_count, 0);
}
}
+
pc->bh = bh;
+
+ return bcount;
}
-static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+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) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return;
- }
+ 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;
@@ -352,6 +348,8 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
}
+
+ return bcount;
}
static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
@@ -563,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drive_t *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)
- idetape_output_buffers(drive, pc, bcount);
+ bleft = idetape_output_buffers(drive, pc, bcount);
else
- idetape_input_buffers(drive, pc, bcount);
+ bleft = idetape_input_buffers(drive, pc, bcount);
- return bcount;
+ return bcount - bleft;
}
/*
@@ -2014,9 +2014,13 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
+ u8 pc_buf[256];
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)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 84532be..243421c 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -80,8 +80,14 @@ 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, tf);
- tp_ops->set_irq(hwif, 1);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
SELECT_MASK(drive, 0);
+
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
+ u8 data[2] = { tf->data, tf->hob_data };
+
+ tp_ops->output_data(drive, cmd, data, 2);
+ }
tp_ops->tf_load(drive, cmd);
}
@@ -100,9 +106,7 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
return ide_started;
case ATA_PROT_DMA:
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
- ide_build_sglist(drive, cmd) == 0 ||
- dma_ops->dma_setup(drive, cmd))
+ if (ide_dma_prepare(drive, cmd))
return ide_stopped;
hwif->expiry = dma_ops->dma_timer_expiry;
ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
@@ -188,70 +192,68 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}
-static void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
- unsigned int write, unsigned int nr_bytes)
+void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
struct scatterlist *cursg = cmd->cursg;
struct page *page;
-#ifdef CONFIG_HIGHMEM
unsigned long flags;
-#endif
unsigned int offset;
u8 *buf;
cursg = cmd->cursg;
- if (!cursg) {
- cursg = sg;
- cmd->cursg = sg;
- }
+ if (cursg == NULL)
+ cursg = cmd->cursg = sg;
- page = sg_page(cursg);
- offset = cursg->offset + cmd->cursg_ofs;
+ while (len) {
+ unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
- /* get the current page and offset */
- page = nth_page(page, (offset >> PAGE_SHIFT));
- offset %= PAGE_SIZE;
+ if (nr_bytes > PAGE_SIZE)
+ nr_bytes = PAGE_SIZE;
-#ifdef CONFIG_HIGHMEM
- local_irq_save(flags);
-#endif
- buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+ page = sg_page(cursg);
+ offset = cursg->offset + cmd->cursg_ofs;
- cmd->nleft -= nr_bytes;
- cmd->cursg_ofs += nr_bytes;
+ /* get the current page and offset */
+ page = nth_page(page, (offset >> PAGE_SHIFT));
+ offset %= PAGE_SIZE;
- if (cmd->cursg_ofs == cursg->length) {
- cmd->cursg = sg_next(cmd->cursg);
- cmd->cursg_ofs = 0;
- }
+ if (PageHighMem(page))
+ local_irq_save(flags);
- /* do the actual data transfer */
- if (write)
- hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
- else
- hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
+ buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
- kunmap_atomic(buf, KM_BIO_SRC_IRQ);
-#ifdef CONFIG_HIGHMEM
- local_irq_restore(flags);
-#endif
-}
+ cmd->nleft -= nr_bytes;
+ cmd->cursg_ofs += nr_bytes;
-static void ide_pio_multi(ide_drive_t *drive, struct ide_cmd *cmd,
- unsigned int write)
-{
- unsigned int nsect;
+ if (cmd->cursg_ofs == cursg->length) {
+ cursg = cmd->cursg = sg_next(cmd->cursg);
+ cmd->cursg_ofs = 0;
+ }
+
+ /* do the actual data transfer */
+ if (write)
+ hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
+ else
+ hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
+
+ kunmap_atomic(buf, KM_BIO_SRC_IRQ);
- nsect = min_t(unsigned int, cmd->nleft >> 9, drive->mult_count);
- while (nsect--)
- ide_pio_bytes(drive, cmd, write, SECTOR_SIZE);
+ if (PageHighMem(page))
+ local_irq_restore(flags);
+
+ len -= nr_bytes;
+ }
}
+EXPORT_SYMBOL_GPL(ide_pio_bytes);
static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
unsigned int write)
{
+ unsigned int nr_bytes;
+
u8 saved_io_32bit = drive->io_32bit;
if (cmd->tf_flags & IDE_TFLAG_FS)
@@ -263,9 +265,11 @@ static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
touch_softlockup_watchdog();
if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
- ide_pio_multi(drive, cmd, write);
+ nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
else
- ide_pio_bytes(drive, cmd, write, SECTOR_SIZE);
+ nr_bytes = SECTOR_SIZE;
+
+ ide_pio_bytes(drive, cmd, write, nr_bytes);
drive->io_32bit = saved_io_32bit;
}
diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c
index 81f527a..001a563 100644
--- a/drivers/ide/ide-timings.c
+++ b/drivers/ide/ide-timings.c
@@ -43,6 +43,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
{ XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
+ { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 },
+ { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 },
{ XFER_MW_DMA_2, 25, 0, 0, 0, 70, 25, 120, 0 },
{ XFER_MW_DMA_1, 45, 0, 0, 0, 80, 50, 150, 0 },
{ XFER_MW_DMA_0, 60, 0, 0, 0, 215, 215, 480, 0 },
@@ -51,7 +53,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
{ XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
- { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 },
+ { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 },
+ { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 },
{ XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
{ XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
@@ -90,6 +93,10 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
/* conservative "downgrade" for all pre-ATA2 drives */
if (pio < 3 && cycle < t->cycle)
cycle = 0; /* use standard timing */
+
+ /* Use the standard timing for the CF specific modes too */
+ if (pio > 4 && ata_id_is_cfa(id))
+ cycle = 0;
}
return cycle ? cycle : t->cycle;
@@ -161,7 +168,8 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
- else if (speed <= XFER_PIO_5)
+ 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];
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
index 6910f6a..af44be9 100644
--- a/drivers/ide/ide-xfer-mode.c
+++ b/drivers/ide/ide-xfer-mode.c
@@ -9,11 +9,11 @@ static const char *udma_str[] =
{ "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
"UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
static const char *mwdma_str[] =
- { "MWDMA0", "MWDMA1", "MWDMA2" };
+ { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
static const char *swdma_str[] =
{ "SWDMA0", "SWDMA1", "SWDMA2" };
static const char *pio_str[] =
- { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
+ { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
/**
* ide_xfer_verbose - return IDE mode names
@@ -30,11 +30,11 @@ const char *ide_xfer_verbose(u8 mode)
if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
s = udma_str[i];
- else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
+ else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
s = mwdma_str[i];
else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
s = swdma_str[i];
- else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
+ else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
s = pio_str[i & 0x7];
else if (mode == XFER_PIO_SLOW)
s = "PIO SLOW";
@@ -79,7 +79,10 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
}
if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
- if (ata_id_has_iordy(id)) {
+ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
+ pio_mode = 4 + min_t(int, 2,
+ id[ATA_ID_CFA_MODES] & 7);
+ else if (ata_id_has_iordy(id)) {
if (id[ATA_ID_PIO_MODES] & 7) {
overridden = 0;
if (id[ATA_ID_PIO_MODES] & 4)
@@ -239,7 +242,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
BUG_ON(rate < XFER_PIO_0);
- if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+ if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
return ide_set_pio_mode(drive, rate);
return ide_set_dma_mode(drive, rate);
diff --git a/drivers/ide/ide_arm.c b/drivers/ide/ide_arm.c
deleted file mode 100644
index cf63854..0000000
--- a/drivers/ide/ide_arm.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * ARM default IDE host driver
- *
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
- * Based on code by: Russell King, Ian Molton and Alexander Schulz.
- *
- * May be copied or modified under the terms of the GNU General Public License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/irq.h>
-
-#define DRV_NAME "ide_arm"
-
-#define IDE_ARM_IO 0x1f0
-#define IDE_ARM_IRQ IRQ_HARDDISK
-
-static const struct ide_port_info ide_arm_port_info = {
- .host_flags = IDE_HFLAG_NO_DMA,
-};
-
-static int __init ide_arm_init(void)
-{
- unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (!request_region(base, 8, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
- DRV_NAME, base, base + 7);
- return -EBUSY;
- }
-
- if (!request_region(ctl, 1, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
- DRV_NAME, ctl);
- release_region(base, 8);
- return -EBUSY;
- }
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = IDE_ARM_IRQ;
- hw.chipset = ide_generic;
-
- return ide_host_add(&ide_arm_port_info, hws, NULL);
-}
-
-module_init(ide_arm_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index 0d4ac65..51aa745 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -511,9 +511,8 @@ static struct ide_dma_ops it821x_pass_through_dma_ops = {
.dma_start = it821x_dma_start,
.dma_end = it821x_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index 7b65fe5..71a39fb 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -66,18 +66,11 @@ static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
- if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -90,28 +83,30 @@ static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = superio_ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
+ tf->hob_nsect = inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
+ tf->hob_lbal = inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
+ tf->hob_lbam = inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
+ tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
+static void ns87415_dev_select(ide_drive_t *drive);
+
static const struct ide_tp_ops superio_tp_ops = {
.exec_command = ide_exec_command,
.read_status = superio_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ns87415_dev_select,
.tf_load = ide_tf_load,
.tf_read = superio_tf_read,
@@ -190,10 +185,18 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
-static void ns87415_selectproc (ide_drive_t *drive)
+static void ns87415_dev_select(ide_drive_t *drive)
{
ns87415_prepare_drive(drive,
!!(drive->dev_flags & IDE_DFLAG_USING_DMA));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
+}
+
+static void ns87415_dma_start(ide_drive_t *drive)
+{
+ ns87415_prepare_drive(drive, 1);
+ ide_dma_start(drive);
}
static int ns87415_dma_end(ide_drive_t *drive)
@@ -201,7 +204,6 @@ static int ns87415_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
@@ -210,21 +212,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
/* from ERRATA: clear the INTR & ERROR bits */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
- return (dma_stat & 7) != 4;
-}
-static int ns87415_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
-{
- /* select DMA xfer */
- ns87415_prepare_drive(drive, 1);
- if (ide_dma_setup(drive, cmd) == 0)
- return 0;
- /* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
- return 1;
+
+ /* verify good DMA status */
+ return (dma_stat & 7) != 4;
}
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
@@ -242,7 +234,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
* Also, leave IRQ masked during drive probing, to prevent infinite
* interrupts from a potentially floating INTA..
*
- * IRQs get unmasked in selectproc when drive is first used.
+ * IRQs get unmasked in dev_select() when drive is first used.
*/
(void) pci_read_config_dword(dev, 0x40, &ctrl);
(void) pci_read_config_byte(dev, 0x09, &progif);
@@ -270,7 +262,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
#ifdef __sparc_v9__
/*
* XXX: Reset the device, if we don't it will not respond to
- * SELECT_DRIVE() properly during first ide_probe_port().
+ * dev_select() properly during first ide_probe_port().
*/
timeout = 10000;
outb(12, hwif->io_ports.ctl_addr);
@@ -294,26 +286,35 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
outb(0x60, hwif->dma_base + ATA_DMA_STATUS);
}
-static const struct ide_port_ops ns87415_port_ops = {
- .selectproc = ns87415_selectproc,
+static const struct ide_tp_ops ns87415_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ns87415_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static const struct ide_dma_ops ns87415_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ns87415_dma_setup,
- .dma_start = ide_dma_start,
+ .dma_setup = ide_dma_setup,
+ .dma_start = ns87415_dma_start,
.dma_end = ns87415_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = superio_dma_sff_read_status,
};
static const struct ide_port_info ns87415_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_ns87415,
- .port_ops = &ns87415_port_ops,
+ .tp_ops = &ns87415_tp_ops,
.dma_ops = &ns87415_dma_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_NO_ATAPI_DMA,
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index f7536d1..248a54b 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -258,12 +258,6 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
ide_dma_lost_irq(drive);
}
-static void pdc202xx_dma_timeout(ide_drive_t *drive)
-{
- pdc202xx_reset(drive);
- ide_dma_timeout(drive);
-}
-
static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
@@ -336,7 +330,7 @@ static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
@@ -348,7 +342,7 @@ static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 2bfcfed..052b9bf 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -404,8 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
#define IDE_WAKEUP_DELAY (1*HZ)
static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
-static void pmac_ide_selectproc(ide_drive_t *drive);
-static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
#define PMAC_IDE_REG(x) \
((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
@@ -415,8 +413,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
-static void
-pmac_ide_selectproc(ide_drive_t *drive)
+static void pmac_ide_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
@@ -434,8 +431,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
-static void
-pmac_ide_kauai_selectproc(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 =
@@ -464,9 +460,25 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
if (pmif->kind == controller_sh_ata6 ||
pmif->kind == controller_un_ata6 ||
pmif->kind == controller_k2_ata6)
- pmac_ide_kauai_selectproc(drive);
+ pmac_ide_kauai_apply_timings(drive);
else
- pmac_ide_selectproc(drive);
+ pmac_ide_apply_timings(drive);
+}
+
+static void pmac_dev_select(ide_drive_t *drive)
+{
+ pmac_ide_apply_timings(drive);
+
+ writeb(drive->select | ATA_DEVICE_OBS,
+ (void __iomem *)drive->hwif->io_ports.device_addr);
+}
+
+static void pmac_kauai_dev_select(ide_drive_t *drive)
+{
+ pmac_ide_kauai_apply_timings(drive);
+
+ writeb(drive->select | ATA_DEVICE_OBS,
+ (void __iomem *)drive->hwif->io_ports.device_addr);
}
static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
@@ -476,17 +488,8 @@ static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
+ IDE_TIMING_CONFIG));
}
-static void pmac_set_irq(ide_hwif_t *hwif, int on)
+static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
(void)readl((void __iomem *)(hwif->io_ports.data_addr
+ IDE_TIMING_CONFIG));
@@ -916,10 +919,18 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
(pmac_ide_hwif_t *)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("/");
+ const char *model = of_get_property(root, "model", NULL);
/* Get cable type from device-tree. */
- if (cable && !strncmp(cable, "80-", 3))
- return ATA_CBL_PATA80;
+ if (cable && !strncmp(cable, "80-", 3)) {
+ /* Some drives fail to detect 80c cable in PowerBook */
+ /* These machine use proprietary short IDE cable anyway */
+ if (!strncmp(model, "PowerBook", 9))
+ return ATA_CBL_PATA40_SHORT;
+ else
+ return ATA_CBL_PATA80;
+ }
/*
* G5's seem to have incorrect cable type in device-tree.
@@ -954,9 +965,9 @@ static const struct ide_tp_ops pmac_tp_ops = {
.exec_command = pmac_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = pmac_write_devctl,
- .set_irq = pmac_set_irq,
-
+ .dev_select = pmac_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -964,19 +975,24 @@ static const struct ide_tp_ops pmac_tp_ops = {
.output_data = ide_output_data,
};
-static const struct ide_port_ops pmac_ide_ata6_port_ops = {
- .init_dev = pmac_ide_init_dev,
- .set_pio_mode = pmac_ide_set_pio_mode,
- .set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_kauai_selectproc,
- .cable_detect = pmac_ide_cable_detect,
+static const struct ide_tp_ops pmac_ata6_tp_ops = {
+ .exec_command = pmac_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = pmac_write_devctl,
+
+ .dev_select = pmac_kauai_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static const struct ide_port_ops pmac_ide_ata4_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_selectproc,
.cable_detect = pmac_ide_cable_detect,
};
@@ -984,7 +1000,6 @@ static const struct ide_port_ops pmac_ide_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_selectproc,
};
static const struct ide_dma_ops pmac_dma_ops;
@@ -1021,15 +1036,18 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
pmif->broken_dma = pmif->broken_dma_warn = 0;
if (of_device_is_compatible(np, "shasta-ata")) {
pmif->kind = controller_sh_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA6;
} else if (of_device_is_compatible(np, "kauai-ata")) {
pmif->kind = controller_un_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "K2-UATA")) {
pmif->kind = controller_k2_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0) {
@@ -1455,7 +1473,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
"switching to PIO on Ohare chipset\n", drive->name);
pmif->broken_dma_warn = 1;
}
- goto use_pio_instead;
+ return 0;
}
while (cur_len) {
unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
@@ -1463,7 +1481,7 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
if (count++ >= MAX_DCMDS) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
}
st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
st_le16(&table->req_count, tc);
@@ -1492,9 +1510,6 @@ static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
@@ -1510,10 +1525,8 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (pmac_ide_build_dmatable(drive, cmd) == 0) {
- ide_map_sg(drive, cmd);
+ if (pmac_ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
@@ -1522,8 +1535,6 @@ static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
- drive->waiting_for_dma = 1;
-
return 0;
}
@@ -1558,12 +1569,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
u32 dstat;
- drive->waiting_for_dma = 0;
dstat = readl(&dma->status);
writel(((RUN|WAKE|DEAD) << 16), &dma->control);
- ide_destroy_dmatable(drive);
-
/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
* in theory, but with ATAPI decices doing buffer underruns, that would
* cause us to disable DMA, which isn't what we want
@@ -1650,7 +1658,6 @@ static const struct ide_dma_ops pmac_dma_ops = {
.dma_start = pmac_ide_dma_start,
.dma_end = pmac_ide_dma_end,
.dma_test_irq = pmac_ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = pmac_ide_dma_lost_irq,
};
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index 2a43a2f..d007e7f 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -99,9 +99,9 @@ static const struct ide_tp_ops q40ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 08c4fa3..c9a1349 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -90,13 +90,15 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
* This routine is invoked to prepare for access to a given drive.
*/
-static void qd65xx_select(ide_drive_t *drive)
+static void qd65xx_dev_select(ide_drive_t *drive)
{
u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
(QD_TIMREG(drive) & 0x02);
if (timings[index] != QD_TIMING(drive))
outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
/*
@@ -309,20 +311,33 @@ static void __init qd6580_init_dev(ide_drive_t *drive)
drive->drive_data = (drive->dn & 1) ? t2 : t1;
}
+static const struct ide_tp_ops qd65xx_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = qd65xx_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
+
static const struct ide_port_ops qd6500_port_ops = {
.init_dev = qd6500_init_dev,
.set_pio_mode = qd6500_set_pio_mode,
- .selectproc = qd65xx_select,
};
static const struct ide_port_ops qd6580_port_ops = {
.init_dev = qd6580_init_dev,
.set_pio_mode = qd6580_set_pio_mode,
- .selectproc = qd65xx_select,
};
static const struct ide_port_info qd65xx_port_info __initdata = {
.name = DRV_NAME,
+ .tp_ops = &qd65xx_tp_ops,
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
IDE_HFLAG_NO_DMA,
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index 1c3a829..d467478 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -115,8 +115,7 @@ static u8 sc1200_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
- if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
- (mateid[ATA_ID_MWDMA_MODES] & 7))
+ if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
@@ -183,9 +182,6 @@ static int sc1200_dma_end(ide_drive_t *drive)
outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */
outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive); /* purge DMA mappings */
-
return (dma_stat & 7) != 4; /* verify good DMA status */
}
@@ -291,7 +287,6 @@ static const struct ide_dma_ops sc1200_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 0cc137c..6d8dbd9 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -148,17 +148,8 @@ static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
return (u8)in_be32((void *)(hwif->dma_base + 4));
}
-static void scc_set_irq(ide_hwif_t *hwif, int on)
+static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
out_be32((void *)hwif->io_ports.ctl_addr, ctl);
eieio();
in_be32((void *)(hwif->dma_base + 0x01c));
@@ -321,10 +312,8 @@ static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
u8 dma_stat;
/* fall back to pio! */
- if (ide_build_dmatable(drive, cmd) == 0) {
- ide_map_sg(drive, cmd);
+ if (ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
@@ -337,7 +326,7 @@ static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/* clear INTR & ERROR flags */
out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
- drive->waiting_for_dma = 1;
+
return 0;
}
@@ -356,7 +345,6 @@ static int __scc_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat, dma_cmd;
- drive->waiting_for_dma = 0;
/* get DMA command mode */
dma_cmd = scc_ide_inb(hwif->dma_base);
/* stop DMA */
@@ -365,8 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive)
dma_stat = scc_dma_sff_read_status(hwif);
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
wmb();
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
@@ -670,10 +656,6 @@ static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA)
- out_be32((void *)io_ports->data_addr,
- (tf->hob_data << 8) | tf->data);
-
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -706,18 +688,11 @@ static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
- if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data = (u16)in_be32((void *)io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = scc_ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = scc_ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -730,18 +705,18 @@ static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = scc_ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = scc_ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
+ tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
+ tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
+ tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
+ tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
}
}
@@ -848,9 +823,9 @@ static const struct ide_tp_ops scc_tp_ops = {
.exec_command = scc_exec_command,
.read_status = scc_read_status,
.read_altstatus = scc_read_altstatus,
+ .write_devctl = scc_write_devctl,
- .set_irq = scc_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = scc_tf_load,
.tf_read = scc_tf_read,
@@ -872,7 +847,6 @@ static const struct ide_dma_ops scc_dma_ops = {
.dma_end = scc_dma_end,
.dma_test_irq = scc_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = scc_dma_sff_read_status,
};
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index b12de83..e5d2a48 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -258,9 +258,6 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
}
}
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive);
-
return dma_stat;
}
@@ -280,10 +277,12 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
sgiioc4_clearirq(drive);
}
-static void
-sgiioc4_resetproc(ide_drive_t * drive)
+static void sgiioc4_resetproc(ide_drive_t *drive)
{
+ struct ide_cmd *cmd = &drive->hwif->cmd;
+
sgiioc4_dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
sgiioc4_clearirq(drive);
}
@@ -412,7 +411,6 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
- drive->waiting_for_dma = 1;
}
/* IOC4 Scatter Gather list Format */
@@ -442,7 +440,7 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
printk(KERN_WARNING
"%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
} else {
u32 bcount =
0x10000 - (cur_addr & 0xffff);
@@ -477,9 +475,6 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
return count;
}
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
@@ -488,11 +483,9 @@ static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
int ddir;
u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (sgiioc4_build_dmatable(drive, cmd) == 0) {
+ if (sgiioc4_build_dmatable(drive, cmd) == 0)
/* try PIO instead of DMA */
- ide_map_sg(drive, cmd);
return 1;
- }
if (write)
/* Writes TO the IOC4 FROM Main Memory */
@@ -510,9 +503,9 @@ static const struct ide_tp_ops sgiioc4_tp_ops = {
.exec_command = ide_exec_command,
.read_status = sgiioc4_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -533,7 +526,6 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
.dma_end = sgiioc4_dma_end,
.dma_test_irq = sgiioc4_dma_test_irq,
.dma_lost_irq = sgiioc4_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info sgiioc4_port_info __devinitconst = {
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index 075cb12..e4973cd 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -715,7 +715,6 @@ static const struct ide_dma_ops sil_dma_ops = {
.dma_end = ide_dma_end,
.dma_test_irq = siimage_dma_test_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index d25137b..b0a4606 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -61,7 +61,8 @@ 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))
+ if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
+ !(pio > 4 && ata_id_is_cfa(drive->id)))
iordy = 0x40;
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
@@ -189,14 +190,13 @@ static void sl82c105_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static void sl82c105_dma_timeout(ide_drive_t *drive)
+static void sl82c105_dma_clear(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
+ DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
sl82c105_reset_host(dev);
- ide_dma_timeout(drive);
}
static int sl82c105_dma_end(ide_drive_t *drive)
@@ -298,7 +298,7 @@ static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = sl82c105_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = sl82c105_dma_timeout,
+ .dma_clear = sl82c105_dma_clear,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index 427d4b3..b4cf42d 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -187,7 +187,6 @@ static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index ed14968..4b42ca0 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -171,54 +171,51 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
-static void trm290_selectproc (ide_drive_t *drive)
+static void trm290_dev_select(ide_drive_t *drive)
{
trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
-static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_hwif_t *hwif = drive->hwif;
- unsigned int count, rw;
-
if (cmd->tf_flags & IDE_TFLAG_WRITE) {
#ifdef TRM290_NO_DMA_WRITES
/* always use PIO for writes */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
- rw = 1;
- } else
- rw = 2;
+ }
+ return 0;
+}
+
+static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2;
count = ide_build_dmatable(drive, cmd);
- if (count == 0) {
- ide_map_sg(drive, cmd);
+ if (count == 0)
/* try PIO instead of DMA */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
- }
- /* select DMA xfer */
- trm290_prepare_drive(drive, 1);
+
outl(hwif->dmatable_dma | rw, hwif->dma_base);
- drive->waiting_for_dma = 1;
/* start DMA */
outw(count * 2 - 1, hwif->dma_base + 2);
+
return 0;
}
static void trm290_dma_start(ide_drive_t *drive)
{
+ trm290_prepare_drive(drive, 1);
}
static int trm290_dma_end(ide_drive_t *drive)
{
- u16 status;
+ u16 status = inw(drive->hwif->dma_base + 2);
- drive->waiting_for_dma = 0;
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- status = inw(drive->hwif->dma_base + 2);
+ trm290_prepare_drive(drive, 0);
return status != 0x00ff;
}
@@ -303,8 +300,18 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
#endif
}
-static const struct ide_port_ops trm290_port_ops = {
- .selectproc = trm290_selectproc,
+static const struct ide_tp_ops trm290_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = trm290_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static struct ide_dma_ops trm290_dma_ops = {
@@ -314,13 +321,13 @@ static struct ide_dma_ops trm290_dma_ops = {
.dma_end = trm290_dma_end,
.dma_test_irq = trm290_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = trm290_dma_check,
};
static const struct ide_port_info trm290_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_trm290,
- .port_ops = &trm290_port_ops,
+ .tp_ops = &trm290_tp_ops,
.dma_ops = &trm290_dma_ops,
.host_flags = IDE_HFLAG_TRM290 |
IDE_HFLAG_NO_ATAPI_DMA |
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index 657a618..4cb79c4 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -92,13 +92,6 @@ static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- /* no endian swap */
- __raw_writew(data, (void __iomem *)io_ports->data_addr);
- }
-
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -132,20 +125,11 @@ static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
- if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data;
-
- /* no endian swap */
- data = __raw_readw((void __iomem *)io_ports->data_addr);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tx4938ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tx4938ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4938ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -158,19 +142,18 @@ static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = tx4938ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- tx4938ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tx4938ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
+ tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
+ tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
+ tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
+ tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
}
}
@@ -204,9 +187,9 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4938ide_tf_load,
.tf_read = tx4938ide_tf_read,
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index e0e0a80..0040a9a 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -279,8 +279,6 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
#else
@@ -294,10 +292,8 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
/* fall back to PIO! */
- if (tx4939ide_build_dmatable(drive, cmd) == 0) {
- ide_map_sg(drive, cmd);
+ if (tx4939ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
@@ -308,8 +304,6 @@ static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
/* clear INTR & ERROR flags */
tx4939ide_clear_dma_status(base);
- drive->waiting_for_dma = 1;
-
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
@@ -325,8 +319,6 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
void __iomem *base = TX4939IDE_BASE(hwif);
u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
- drive->waiting_for_dma = 0;
-
/* get DMA command mode */
dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
/* stop DMA */
@@ -335,11 +327,9 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
/* read and clear the INTR & ERROR bits */
dma_stat = tx4939ide_clear_dma_status(base);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
wmb();
+ /* verify good DMA status */
if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
(ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
(TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
@@ -439,7 +429,7 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
* Fix ATA100 CORE System Control Register. (The write to the
* Device/Head register may write wrong data to the System
* Control Register)
- * While Sys_Ctl is written here, selectproc is not needed.
+ * While Sys_Ctl is written here, dev_select() is not needed.
*/
tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
}
@@ -467,13 +457,6 @@ static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- /* no endian swap */
- __raw_writew(data, (void __iomem *)io_ports->data_addr);
- }
-
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
@@ -509,20 +492,11 @@ static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
struct ide_io_ports *io_ports = &hwif->io_ports;
struct ide_taskfile *tf = &cmd->tf;
- if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
- u16 data;
-
- /* no endian swap */
- data = __raw_readw((void __iomem *)io_ports->data_addr);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tx4939ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tx4939ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
@@ -535,19 +509,18 @@ static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
tf->device = tx4939ide_inb(io_ports->device_addr);
if (cmd->tf_flags & IDE_TFLAG_LBA48) {
- tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
+ tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (cmd->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- tx4939ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tx4939ide_inb(io_ports->feature_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
+ tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
+ tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
+ tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
+ tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
}
}
@@ -581,9 +554,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = tx4939ide_tf_read,
@@ -605,9 +578,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = ide_tf_read,
@@ -632,7 +605,6 @@ static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_test_irq = tx4939ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
.dma_timer_expiry = ide_dma_sff_timer_expiry,
- .dma_timeout = ide_dma_timeout,
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
diff --git a/include/linux/ide.h b/include/linux/ide.h
index d5d8322..a5d26f6 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -265,7 +265,7 @@ enum {
IDE_TFLAG_WRITE = (1 << 12),
IDE_TFLAG_CUSTOM_HANDLER = (1 << 13),
IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 14),
- IDE_TFLAG_IN_HOB_FEATURE = (1 << 15),
+ IDE_TFLAG_IN_HOB_ERROR = (1 << 15),
IDE_TFLAG_IN_HOB_NSECT = (1 << 16),
IDE_TFLAG_IN_HOB_LBAL = (1 << 17),
IDE_TFLAG_IN_HOB_LBAM = (1 << 18),
@@ -273,10 +273,10 @@ enum {
IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL |
IDE_TFLAG_IN_HOB_LBAM |
IDE_TFLAG_IN_HOB_LBAH,
- IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE |
+ IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_ERROR |
IDE_TFLAG_IN_HOB_NSECT |
IDE_TFLAG_IN_HOB_LBA,
- IDE_TFLAG_IN_FEATURE = (1 << 20),
+ IDE_TFLAG_IN_ERROR = (1 << 20),
IDE_TFLAG_IN_NSECT = (1 << 21),
IDE_TFLAG_IN_LBAL = (1 << 22),
IDE_TFLAG_IN_LBAM = (1 << 23),
@@ -310,8 +310,12 @@ enum {
struct ide_taskfile {
u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */
+ /* 1-5: additional data to support LBA48 */
+ union {
+ u8 hob_error; /* read: error */
+ u8 hob_feature; /* write: feature */
+ };
- u8 hob_feature; /* 1-5: additional data to support LBA48 */
u8 hob_nsect;
u8 hob_lbal;
u8 hob_lbam;
@@ -352,6 +356,8 @@ struct ide_cmd {
unsigned int nbytes;
unsigned int nleft;
+ unsigned int last_xfer_len;
+
struct scatterlist *cursg;
unsigned int cursg_ofs;
@@ -375,7 +381,7 @@ enum {
* With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
* This is used for several packet commands (not for READ/WRITE commands).
*/
-#define IDE_PC_BUFFER_SIZE 256
+#define IDE_PC_BUFFER_SIZE 64
#define ATAPI_WAIT_PC (60 * HZ)
struct ide_atapi_pc {
@@ -413,9 +419,6 @@ struct ide_atapi_pc {
struct idetape_bh *bh;
char *b_data;
- struct scatterlist *sg;
- unsigned int sg_cnt;
-
unsigned long timeout;
};
@@ -456,11 +459,6 @@ enum {
IDE_AFLAG_TOCADDR_AS_BCD = (1 << 3),
/* TOC track numbers are in BCD. */
IDE_AFLAG_TOCTRACKS_AS_BCD = (1 << 4),
- /*
- * Drive does not provide data in multiples of SECTOR_SIZE
- * when more than one interrupt is needed.
- */
- IDE_AFLAG_LIMIT_NFRAMES = (1 << 5),
/* Saved TOC information is current. */
IDE_AFLAG_TOC_VALID = (1 << 6),
/* We think that the drive door is locked. */
@@ -605,7 +603,7 @@ struct ide_drive_s {
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
- unsigned int drive_data; /* used by set_pio_mode/selectproc */
+ unsigned int drive_data; /* used by set_pio_mode/dev_select() */
unsigned int failures; /* current failure count */
unsigned int max_failures; /* maximum allowed failure count */
u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */
@@ -661,9 +659,9 @@ struct ide_tp_ops {
void (*exec_command)(struct hwif_s *, u8);
u8 (*read_status)(struct hwif_s *);
u8 (*read_altstatus)(struct hwif_s *);
+ void (*write_devctl)(struct hwif_s *, u8);
- void (*set_irq)(struct hwif_s *, int);
-
+ void (*dev_select)(ide_drive_t *);
void (*tf_load)(ide_drive_t *, struct ide_cmd *);
void (*tf_read)(ide_drive_t *, struct ide_cmd *);
@@ -681,7 +679,6 @@ extern const struct ide_tp_ops default_tp_ops;
* @init_dev: host specific initialization of a device
* @set_pio_mode: routine to program host for PIO mode
* @set_dma_mode: routine to program host for DMA mode
- * @selectproc: tweaks hardware to select drive
* @reset_poll: chipset polling based on hba specifics
* @pre_reset: chipset specific changes to default for device-hba resets
* @resetproc: routine to reset controller after a disk reset
@@ -698,7 +695,6 @@ struct ide_port_ops {
void (*init_dev)(ide_drive_t *);
void (*set_pio_mode)(ide_drive_t *, const u8);
void (*set_dma_mode)(ide_drive_t *, const u8);
- void (*selectproc)(ide_drive_t *);
int (*reset_poll)(ide_drive_t *);
void (*pre_reset)(ide_drive_t *);
void (*resetproc)(ide_drive_t *);
@@ -719,8 +715,10 @@ struct ide_dma_ops {
int (*dma_end)(struct ide_drive_s *);
int (*dma_test_irq)(struct ide_drive_s *);
void (*dma_lost_irq)(struct ide_drive_s *);
+ /* below ones are optional */
+ int (*dma_check)(struct ide_drive_s *, struct ide_cmd *);
int (*dma_timer_expiry)(struct ide_drive_s *);
- void (*dma_timeout)(struct ide_drive_s *);
+ void (*dma_clear)(struct ide_drive_s *);
/*
* The following method is optional and only required to be
* implemented for the SFF-8038i compatible controllers.
@@ -1169,18 +1167,15 @@ void ide_tf_dump(const char *, struct ide_taskfile *);
void ide_exec_command(ide_hwif_t *, u8);
u8 ide_read_status(ide_hwif_t *);
u8 ide_read_altstatus(ide_hwif_t *);
+void ide_write_devctl(ide_hwif_t *, u8);
-void ide_set_irq(ide_hwif_t *, int);
-
+void ide_dev_select(ide_drive_t *);
void ide_tf_load(ide_drive_t *, struct ide_cmd *);
void ide_tf_read(ide_drive_t *, struct ide_cmd *);
void ide_input_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int);
void ide_output_data(ide_drive_t *, struct ide_cmd *, void *, unsigned int);
-int ide_io_buffers(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int);
-
-extern void SELECT_DRIVE(ide_drive_t *);
void SELECT_MASK(ide_drive_t *, int);
u8 ide_read_error(ide_drive_t *);
@@ -1226,6 +1221,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_cmd *);
ide_startstop_t do_rw_taskfile(ide_drive_t *, struct ide_cmd *);
+void ide_pio_bytes(ide_drive_t *, struct ide_cmd *, unsigned int, unsigned int);
+
void ide_finish_cmd(ide_drive_t *, struct ide_cmd *, u8);
int ide_raw_taskfile(ide_drive_t *, struct ide_cmd *, u8 *, u16);
@@ -1443,8 +1440,8 @@ ide_startstop_t ide_dma_intr(ide_drive_t *);
int ide_allocate_dma_engine(ide_hwif_t *);
void ide_release_dma_engine(ide_hwif_t *);
-int ide_build_sglist(ide_drive_t *, struct ide_cmd *);
-void ide_destroy_dmatable(ide_drive_t *);
+int ide_dma_prepare(ide_drive_t *, struct ide_cmd *);
+void ide_dma_unmap_sg(ide_drive_t *, struct ide_cmd *);
#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
int config_drive_for_dma(ide_drive_t *);
@@ -1462,7 +1459,6 @@ static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; }
#endif /* CONFIG_BLK_DEV_IDEDMA_SFF */
void ide_dma_lost_irq(ide_drive_t *);
-void ide_dma_timeout(ide_drive_t *);
ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int);
#else
@@ -1478,8 +1474,10 @@ static inline void ide_check_dma_crc(ide_drive_t *drive) { ; }
static inline ide_startstop_t ide_dma_intr(ide_drive_t *drive) { return ide_stopped; }
static inline ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) { return ide_stopped; }
static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; }
-static inline int ide_build_sglist(ide_drive_t *drive,
- struct ide_cmd *cmd) { return 0; }
+static inline int ide_dma_prepare(ide_drive_t *drive,
+ struct ide_cmd *cmd) { return 1; }
+static inline void ide_dma_unmap_sg(ide_drive_t *drive,
+ struct ide_cmd *cmd) { ; }
#endif /* CONFIG_BLK_DEV_IDEDMA */
#ifdef CONFIG_BLK_DEV_IDEACPI
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [git pull] IDE updates part 3
@ 2009-06-20 11:56 Bartlomiej Zolnierkiewicz
0 siblings, 0 replies; 3+ messages in thread
From: Bartlomiej Zolnierkiewicz @ 2009-06-20 11:56 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andrew Morton, Stephen Rothwell, linux-ide, linux-kernel
Hi,
The last part of IDE changes for 2.6.31 merge window:
* Fix ide-cd OOPSing on failed commands. (Rainer Weikusat)
* IORDY handling fixes.
* Sanitize methods for IRQ clearing/testing. (Sergei Shtylyov)
* ATAPI support update. (Borislav Petkov)
* Misc fixes/cleanups.
Linus, please pull from 'for-2.6.31' branch of:
master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6.git for-2.6.31
to receive the following updates:
drivers/ide/at91_ide.c | 3 +-
drivers/ide/buddha.c | 40 +++++----
drivers/ide/cmd640.c | 13 +++
drivers/ide/cmd64x.c | 103 +++++++---------------
drivers/ide/cs5536.c | 23 +++--
drivers/ide/falconide.c | 1 -
drivers/ide/gayle.c | 33 ++++---
drivers/ide/ht6560b.c | 33 +++++--
drivers/ide/icside.c | 10 ++-
drivers/ide/ide-atapi.c | 138 +++++++++++++++++++-----------
drivers/ide/ide-cd.c | 78 +++--------------
drivers/ide/ide-disk.c | 9 +--
drivers/ide/ide-floppy.c | 56 +++++-------
drivers/ide/ide-floppy_ioctl.c | 43 +++++-----
drivers/ide/ide-io.c | 8 +-
drivers/ide/ide-ioctls.c | 13 +--
drivers/ide/ide-probe.c | 17 +++-
drivers/ide/ide-tape.c | 186 ++++++++++++++++++----------------------
drivers/ide/ide-xfer-mode.c | 12 +++
drivers/ide/it8172.c | 2 +-
drivers/ide/it8213.c | 2 +-
drivers/ide/macide.c | 30 ++++---
drivers/ide/opti621.c | 8 +-
drivers/ide/pdc202xx_old.c | 24 +++++-
drivers/ide/piix.c | 2 +-
drivers/ide/q40ide.c | 7 +-
drivers/ide/qd65xx.c | 11 ++-
drivers/ide/qd65xx.h | 11 ++-
drivers/ide/sgiioc4.c | 119 ++++++++++++--------------
drivers/ide/siimage.c | 42 +++------
drivers/ide/sl82c105.c | 32 +++++--
drivers/ide/slc90e66.c | 2 +-
include/linux/ata.h | 14 +++
include/linux/ide.h | 47 +++++-----
34 files changed, 598 insertions(+), 574 deletions(-)
Bartlomiej Zolnierkiewicz (7):
Merge branch 'bp-remove-pc-buf' into for-next
ata: add ata_id_pio_need_iordy() helper (v2)
ide: IORDY handling fixes
ide: don't enable IORDY at a probe time
ide: filter out invalid DMA xfer mode changes in HDIO_DRIVE_CMD ioctl handler
ide: BUG() on unknown requests
Merge branch 'for-2.6.31' into 2.6.31
Borislav Petkov (16):
ide-tape: fix potential fs requests bug
ide-atapi: switch to blk_rq_bytes() on do_request() path
ide-atapi: switch to rq->resid_len
ide-atapi: add a len-parameter to ide_queue_pc_tail
ide-atapi: add a buffer-arg to ide_queue_pc_tail
ide-floppy/ide_floppy_get_flexible_disk_page: use local buffer
ide-floppy/ide_floppy_get_sfrp_bit: use local buffer
ide-floppy/ide_floppy_format_unit: use local buffer
ide-atapi: use local sense buffer
ide-floppy/ide_floppy_get_format_progress: use local sense buffer
ide-tape/ide_tape_get_bsize_from_bdesc: use local buffer
ide-tape: fix READ POSITION cmd handling
ide-atapi: remove pc->buf
ide-cd: use whole request_sense buffer in EH
ide: unify interrupt reason checking
ide-tape: fix build issue
Joao Ramos (1):
ide: do not access ide_drive_t 'drive_data' field directly
Rainer Weikusat (1):
ide-cd: prevent null pointer deref via cdrom_newpc_intr
Sergei Shtylyov (11):
sgiioc4: coding style cleanup
ide: call clear_irq() method in ide_timer_expiry()
cmd64x: implement clear_irq() method (take 2)
siimage: use ide_dma_test_irq() (take 2)
ide: move IRQ clearing from ack_intr() method to clear_irq() method (take 2)
ide: move ack_intr() method into 'struct ide_port_ops' (take 2)
cmd640: implement test_irq() method
cmd64x: implement test_irq() method
pdc202xx_old: implement test_irq() method (take 2)
siimage: implement test_irq() method
sl82c105: implement test_irq() method
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index fc0949a..dbfeda4 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -185,8 +185,7 @@ static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 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))
+ if (ide_pio_need_iordy(drive, pio))
use_iordy = 1;
apply_timings(chipselect, pio, timing, use_iordy);
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c
index e3c6a59..ab4f169 100644
--- a/drivers/ide/buddha.c
+++ b/drivers/ide/buddha.c
@@ -99,7 +99,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 +109,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(struct ide_hw *hw, unsigned long base,
- unsigned long ctl, unsigned long irq_port,
- ide_ack_intr_t *ack_intr)
+ unsigned long ctl, unsigned long irq_port)
{
int i;
@@ -138,10 +133,19 @@ static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base,
hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
- hw->ack_intr = ack_intr;
}
+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,6 +165,7 @@ static int __init buddha_init(void)
while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
unsigned long board;
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;
@@ -171,6 +176,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;
@@ -203,28 +209,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, i, NULL);
+ ide_host_add(&d, hws, i, NULL);
}
return 0;
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c
index 1683ed5..1a32d62 100644
--- a/drivers/ide/cmd640.c
+++ b/drivers/ide/cmd640.c
@@ -153,6 +153,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
@@ -629,12 +630,24 @@ static void cmd640_init_dev(ide_drive_t *drive)
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
}
+static int cmd640_test_irq(ide_hwif_t *hwif)
+{
+ struct pci_dev *dev = to_pci_dev(hwif->dev);
+ int irq_reg = hwif->channel ? ARTTIM23 : CFR;
+ u8 irq_stat, irq_mask = hwif->channel ? ARTTIM23_IDE23INTR :
+ CFR_IDE01INTR;
+
+ pci_read_config_byte(dev, irq_reg, &irq_stat);
+
+ 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)
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index 80b777e..03c8620 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -7,7 +7,7 @@
* 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,2009 MontaVista Software, Inc. <source@mvista.com>
*/
#include <linux/module.h>
@@ -118,8 +118,9 @@ 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 long setup_count;
unsigned int cycle_time;
- u8 setup_count, arttim = 0;
+ u8 arttim = 0;
static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0};
static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23};
@@ -140,10 +141,11 @@ 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;
+ ide_set_drivedata(drive, (void *)setup_count);
if (pair)
- setup_count = max_t(u8, setup_count, pair->drive_data);
+ setup_count = max_t(u8, setup_count,
+ (unsigned long)ide_get_drivedata(pair));
}
if (setup_count > 5) /* shouldn't actually happen... */
@@ -226,11 +228,11 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed)
(void) 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 +240,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 +250,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;
-
- /* return 1 if INTR asserted */
- if (dma_stat & 4)
- return 1;
+ pr_debug("%s: mrdmode: 0x%02x irq_mask: 0x%02x\n",
+ hwif->name, mrdmode, irq_mask);
- 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 +348,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,24 +372,12 @@ 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 = {
{ /* 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,
.pio_mask = ATA_PIO5,
@@ -423,8 +388,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_SERIALIZE |
IDE_HFLAG_ABUSE_PREFETCH,
.pio_mask = ATA_PIO5,
@@ -435,8 +399,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 +409,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,
@@ -484,10 +446,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;
}
}
}
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
index 0332a95..9623b85 100644
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -146,14 +146,16 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio)
struct pci_dev *pdev = to_pci_dev(drive->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;
u8 cmd_pio = pio;
if (pair)
cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4));
- 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]);
@@ -186,6 +188,7 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode)
struct pci_dev *pdev = to_pci_dev(drive->hwif->dev);
int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT;
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
u32 etc;
cs5536_read(pdev, ETC, &etc);
@@ -195,8 +198,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 +208,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 +220,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;
}
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index 22fa273..a5a07cc 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -128,7 +128,6 @@ static void __init falconide_setup_ports(struct ide_hw *hw)
hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL;
hw->irq = IRQ_MFP_IDE;
- hw->ack_intr = NULL;
}
/*
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 4451a6a..b9e517d 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -66,7 +66,7 @@ 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;
@@ -76,21 +76,16 @@ static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
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;
}
static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base,
- unsigned long ctl, unsigned long irq_port,
- ide_ack_intr_t *ack_intr)
+ unsigned long ctl, unsigned long irq_port)
{
int i;
@@ -105,9 +100,17 @@ static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base,
hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
- hw->ack_intr = ack_intr;
}
+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,
@@ -123,9 +126,9 @@ static int __init gayle_init(void)
{
unsigned long phys_base, res_start, res_n;
unsigned long base, ctrlport, irqport;
- ide_ack_intr_t *ack_intr;
int a4000, i, rc;
struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS];
+ struct ide_port_info d = gayle_port_info;
if (!MACH_IS_AMIGA)
return -ENODEV;
@@ -148,11 +151,11 @@ found:
if (a4000) {
phys_base = GAYLE_BASE_4000;
irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000);
- ack_intr = gayle_ack_intr_a4000;
+ d.port_ops = &gayle_a4000_port_ops;
} else {
phys_base = GAYLE_BASE_1200;
irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
- ack_intr = gayle_ack_intr_a1200;
+ d.port_ops = &gayle_a1200_port_ops;
}
res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
@@ -165,12 +168,12 @@ found:
base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT);
ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0;
- gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr);
+ gayle_setup_ports(&hw[i], base, ctrlport, irqport);
hws[i] = &hw[i];
}
- rc = ide_host_add(&gayle_port_info, hws, i, NULL);
+ rc = ide_host_add(&d, hws, i, NULL);
if (rc)
release_mem_region(res_start, res_n);
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index 2fb0f29..aafed80 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -44,7 +44,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 +95,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 +251,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
@@ -268,7 +281,7 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
- unsigned long flags;
+ unsigned long flags, config;
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,7 +314,7 @@ 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;
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 5af3d0f..0f67f1a 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -187,7 +187,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = {
*/
static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
{
- int cycle_time, use_dma_info = 0;
+ unsigned long cycle_time;
+ int use_dma_info = 0;
switch (xfer_mode) {
case XFER_MW_DMA_2:
@@ -218,10 +219,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);
+ ide_xfer_verbose(xfer_mode),
+ 2000 / (unsigned long)ide_get_drivedata(drive));
}
static const struct ide_port_ops icside_v6_port_ops = {
@@ -277,7 +279,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
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 702ef64..eb2181a 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -10,6 +10,9 @@
#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,8 +77,6 @@ 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);
@@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(ide_init_pc);
* 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;
@@ -93,8 +94,8 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
rq->cmd_type = REQ_TYPE_SPECIAL;
rq->special = (char *)pc;
- if (pc->req_xfer) {
- error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer,
+ if (buf && bufflen) {
+ error = blk_rq_map_kern(drive->queue, rq, buf, bufflen,
GFP_NOIO);
if (error)
goto put_req;
@@ -117,7 +118,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);
@@ -132,7 +133,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);
@@ -147,7 +148,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);
@@ -172,8 +173,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
unsigned int cmd_len, sense_len;
int err;
- debug_log("%s: enter\n", __func__);
-
switch (drive->media) {
case ide_floppy:
cmd_len = 255;
@@ -201,8 +200,8 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
GFP_NOIO);
if (unlikely(err)) {
if (printk_ratelimit())
- printk(KERN_WARNING "%s: failed to map sense buffer\n",
- drive->name);
+ printk(KERN_WARNING PFX "%s: failed to map sense "
+ "buffer\n", drive->name);
return;
}
@@ -223,7 +222,7 @@ 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 "%s: failed queue sense request\n",
+ printk(KERN_WARNING PFX "%s: error queuing a sense request\n",
drive->name);
return -ENOMEM;
}
@@ -255,8 +254,6 @@ void ide_retry_pc(ide_drive_t *drive)
/* init pc from sense_rq */
ide_init_pc(pc);
memcpy(pc->c, sense_rq->cmd, 12);
- pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */
- pc->req_xfer = blk_rq_bytes(sense_rq);
if (drive->media == ide_tape)
drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC;
@@ -298,7 +295,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;
@@ -332,6 +329,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.
@@ -365,12 +411,12 @@ 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;
+ rq->resid_len = 0;
debug_log("%s: DMA finished\n", drive->name);
}
@@ -379,7 +425,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
int uptodate, error;
debug_log("Packet command completed, %d bytes transferred\n",
- pc->xferred);
+ blk_rq_bytes(rq));
pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS;
@@ -397,8 +443,8 @@ 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);
}
@@ -446,8 +492,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
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);
}
@@ -455,33 +501,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);
- }
done = min_t(unsigned int, bcount, cmd->nleft);
ide_pio_bytes(drive, cmd, write, done);
/* Update transferred byte count */
- pc->xferred += done;
+ 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);
@@ -515,13 +550,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;
@@ -552,7 +587,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;
}
@@ -594,8 +629,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);
}
@@ -633,7 +668,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);
@@ -649,13 +684,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;
-
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 424140c..4a19686 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -92,16 +92,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 +140,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 +154,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;
/*
@@ -225,15 +225,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
* sense pointer set.
*/
memcpy(failed->sense, sense, 18);
- sense = failed->sense;
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);
}
@@ -410,50 +409,6 @@ end_request:
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;
@@ -645,8 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
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;
@@ -713,7 +667,7 @@ out_end:
rq->errors = -EIO;
}
- if (uptodate == 0)
+ if (uptodate == 0 && rq->bio)
ide_cd_error_cmd(drive, cmd);
/* make sure it's fully ended */
@@ -831,12 +785,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
/* 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;
- }
+ } else
+ BUG();
/* prepare sense request for this command */
ide_prep_sense(drive, rq);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 6a1de21..6951811 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -184,14 +184,7 @@ 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(!blk_fs_request(rq));
ledtrig_ide_activity();
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 6509817..8b3f204 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -77,7 +77,8 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc)
(rq && blk_pc_request(rq)))
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;
@@ -209,8 +210,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
pc->rq = rq;
if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING;
- pc->buf = NULL;
- pc->req_xfer = pc->buf_size = blocks * floppy->block_size;
+
pc->flags |= PC_FLAG_DMA_OK;
}
@@ -225,9 +225,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
if (rq_data_dir(rq) == WRITE)
pc->flags |= PC_FLAG_WRITING;
}
- /* pio will be performed by ide_pio_bytes() which handles sg fine */
- pc->buf = NULL;
- pc->req_xfer = pc->buf_size = blk_rq_bytes(rq);
}
static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
@@ -272,10 +269,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
} else if (blk_pc_request(rq)) {
pc = &floppy->queued_pc;
idefloppy_blockpc_cmd(floppy, pc, rq);
- } else {
- blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- goto out_end;
- }
+ } else
+ BUG();
ide_prep_sense(drive, rq);
@@ -286,8 +281,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 (blk_fs_request(rq) || blk_rq_bytes(rq)) {
+ ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
ide_map_sg(drive, &cmd);
}
@@ -311,33 +306,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;
@@ -387,22 +382,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",
@@ -415,7 +407,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))
@@ -464,7 +456,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 */
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index cd8a420..9c22882 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -47,15 +47,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 +70,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 +92,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 +137,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 +171,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 +197,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 &&
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 272cc38..1059f80 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -683,8 +683,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);
@@ -803,7 +804,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;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 5991b23..82f252c 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -118,7 +118,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;
@@ -161,14 +160,10 @@ 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, XFER_UDMA_6);
+ if (xfer_rate != tf->nsect) {
+ err = -EINVAL;
goto abort;
}
}
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 79e0af3..51af4ee 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1170,7 +1170,6 @@ static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw)
hwif->irq = hw->irq;
hwif->dev = hw->dev;
hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
- hwif->ack_intr = hw->ack_intr;
hwif->config_data = hw->config;
}
@@ -1378,6 +1377,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);
}
@@ -1388,6 +1390,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)) {
@@ -1569,11 +1573,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-tape.c b/drivers/ide/ide-tape.c
index 4b447a8..013dc59 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -279,10 +279,12 @@ static void ide_tape_put(struct ide_tape_obj *tape)
* 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];
@@ -291,11 +293,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n",
pc->c[0], tape->sense_key, tape->asc, tape->ascq);
- /* Correct pc->xferred by asking the tape. */
+ /* correct remaining bytes to transfer */
if (pc->flags & PC_FLAG_DMA_ERROR)
- pc->xferred = pc->req_xfer -
- tape->blk_size *
- get_unaligned_be32(&sense[3]);
+ rq->resid_len = tape->blk_size * get_unaligned_be32(&sense[3]);
/*
* If error was the result of a zero-length read or write command,
@@ -329,7 +329,7 @@ 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;
}
}
@@ -354,12 +354,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;
@@ -371,38 +372,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc)
}
tape->first_frame += blocks;
- rq->resid_len -= blocks * tape->blk_size;
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(ilog2(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(ilog2(IDE_AFLAG_ADDRESS_VALID),
- &drive->atapi_flags);
- }
}
-
rq->errors = err;
return uptodate;
@@ -477,6 +452,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;
+ struct request *rq = drive->hwif->rq;
if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
drive->failed_pc = pc;
@@ -486,7 +462,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
if (pc->retries > IDETAPE_MAX_PC_RETRIES ||
(pc->flags & PC_FLAG_ABORT)) {
- unsigned int done = blk_rq_bytes(drive->hwif->rq);
/*
* We will "abort" retrying a packet command in case legitimate
@@ -510,7 +485,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
- ide_complete_rq(drive, -EIO, done);
+ 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]);
@@ -579,15 +554,13 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape,
struct ide_atapi_pc *pc, struct request *rq,
u8 opcode)
{
- unsigned int length = blk_rq_sectors(rq);
+ 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->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)
@@ -613,15 +586,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n"
(unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq));
- if (!(blk_special_request(rq) || blk_sense_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;
- }
+ BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq)));
/* Retry a failed packet command */
if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
@@ -713,7 +678,7 @@ out:
cmd.rq = rq;
- ide_init_sg_cmd(&cmd, pc->req_xfer);
+ ide_init_sg_cmd(&cmd, blk_rq_bytes(rq));
ide_map_sg(drive, &cmd);
return ide_tape_issue_pc(drive, &cmd, pc);
@@ -767,33 +732,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];
debug_log(DBG_PROCS, "Enter %s\n", __func__);
- idetape_create_read_position_cmd(&pc);
- if (ide_queue_pc_tail(drive, tape->disk, &pc))
+ /* prep cmd */
+ ide_init_pc(&pc);
+ pc.c[0] = READ_POSITION;
+ pc.req_xfer = 20;
+
+ if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer))
return -1;
- position = tape->first_frame;
- return position;
+
+ if (!pc.error) {
+ debug_log(DBG_SENSE, "BOP - %s\n",
+ (buf[0] & 0x80) ? "Yes" : "No");
+ debug_log(DBG_SENSE, "EOP - %s\n",
+ (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 {
+ debug_log(DBG_SENSE, "Block Location - %u\n",
+ 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,
@@ -836,19 +821,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,
@@ -859,7 +846,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"
@@ -1039,20 +1026,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__);
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;
}
@@ -1119,7 +1105,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)
@@ -1259,7 +1245,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;
}
@@ -1345,11 +1331,11 @@ 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 ||
@@ -1415,7 +1401,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file,
if (cmd == MTIOCGET || cmd == MTIOCPOS) {
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;
}
@@ -1458,9 +1444,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 "
@@ -1469,10 +1456,10 @@ 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;
}
static int idetape_chrdev_open(struct inode *inode, struct file *filp)
@@ -1517,7 +1504,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
goto out_put_tape;
}
- idetape_read_position(drive);
+ ide_tape_read_position(drive);
if (!test_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), &drive->atapi_flags))
(void)idetape_rewind_tape(drive);
@@ -1615,17 +1602,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);
@@ -1643,11 +1627,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;
@@ -1656,7 +1640,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]);
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
index af44be9..46d203c 100644
--- a/drivers/ide/ide-xfer-mode.c
+++ b/drivers/ide/ide-xfer-mode.c
@@ -107,6 +107,18 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_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)
{
ide_hwif_t *hwif = drive->hwif;
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c
index e021078..0d266a5 100644
--- a/drivers/ide/it8172.c
+++ b/drivers/ide/it8172.c
@@ -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);
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c
index d7969b6..4797616 100644
--- a/drivers/ide/it8213.c
+++ b/drivers/ide/it8213.c
@@ -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;
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c
index 1447c8c..505ec43 100644
--- a/drivers/ide/macide.c
+++ b/drivers/ide/macide.c
@@ -53,17 +53,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 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, ide_ack_intr_t *ack_intr)
+ int irq)
{
int i;
@@ -75,10 +78,15 @@ static void __init macide_setup_ports(struct ide_hw *hw, unsigned long base,
hw->io_ports.ctl_addr = base + IDE_CONTROL;
hw->irq = irq;
- hw->ack_intr = ack_intr;
}
+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,
@@ -93,10 +101,10 @@ static const char *mac_ide_name[] =
static int __init macide_init(void)
{
- ide_ack_intr_t *ack_intr;
unsigned long base;
int irq;
struct ide_hw hw, *hws[] = { &hw };
+ struct ide_port_info d = macide_port_info;
if (!MACH_IS_MAC)
return -ENODEV;
@@ -104,17 +112,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:
@@ -124,9 +130,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, 1, NULL);
+ return ide_host_add(&d, hws, 1, NULL);
}
module_init(macide_init);
diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c
index 6048eda..f1d70d6 100644
--- a/drivers/ide/opti621.c
+++ b/drivers/ide/opti621.c
@@ -138,6 +138,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
ide_hwif_t *hwif = drive->hwif;
ide_drive_t *pair = ide_get_pair_dev(drive);
unsigned long flags;
+ unsigned long mode = XFER_PIO_0 + pio, pair_mode;
u8 tim, misc, addr_pio = pio, clk;
/* DRDY is default 2 (by OPTi Databook) */
@@ -150,11 +151,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);
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index b6abf7e..cb812f3 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -73,7 +73,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 */
@@ -104,6 +104,27 @@ static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
}
+static int pdc202xx_test_irq(ide_hwif_t *hwif)
+{
+ 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 & 0x50) == 0x40) ? 1 : 0;
+ } else {
+ /*
+ * bit 3: error, bit 2: interrupting,
+ * bit 1: FIFO full, bit 0: FIFO empty
+ */
+ return ((sc1d & 0x05) == 0x04) ? 1 : 0;
+ }
+}
+
static u8 pdc2026x_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
@@ -231,6 +252,7 @@ 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,
+ .test_irq = pdc202xx_test_irq,
};
static const struct ide_port_ops pdc2026x_port_ops = {
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c
index 69860de..bf14f39 100644
--- a/drivers/ide/piix.c
+++ b/drivers/ide/piix.c
@@ -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;
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index ab49a97..9078608 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -51,9 +51,7 @@ static int q40ide_default_irq(unsigned long base)
/*
* Addresses are pretranslated for Q40 ISA access.
*/
-static void q40_ide_setup_ports(struct ide_hw *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));
/* BIG FAT WARNING:
@@ -69,7 +67,6 @@ static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base,
hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206);
hw->irq = irq;
- hw->ack_intr = ack_intr;
}
static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
@@ -156,7 +153,7 @@ 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];
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index c9a1349..74696ed 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -180,8 +180,11 @@ 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);
}
@@ -292,7 +295,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 +311,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 = {
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
index d7e67a1..1fba2a5 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/sgiioc4.c b/drivers/ide/sgiioc4.c
index 5f37f16..b7d61dc 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(struct ide_hw *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(struct ide_hw *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.
*/
@@ -265,7 +259,7 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
}
-/* 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,13 @@ 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 __devinit 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 +355,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 +366,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 +396,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 +438,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);
@@ -540,8 +532,7 @@ 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 __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
{
unsigned long cmd_base, irqport;
unsigned long bar0, cmd_phys_base, ctl;
@@ -549,7 +540,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
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 +548,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,
@@ -577,7 +568,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
hw.irq = dev->irq;
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, 1, NULL);
@@ -590,8 +581,7 @@ req_mem_rgn_err:
return rc;
}
-static unsigned int __devinit
-pci_init_sgiioc4(struct pci_dev *dev)
+static unsigned int __devinit pci_init_sgiioc4(struct pci_dev *dev)
{
int ret;
@@ -611,10 +601,10 @@ out:
return ret;
}
-int __devinit
-ioc4_ide_attach_one(struct ioc4_driver_data *idd)
+int __devinit 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)
@@ -627,7 +617,6 @@ static struct ioc4_submodule __devinitdata 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 bd82d22..d95df52 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -32,7 +32,6 @@
* smarter code in libata.
*
* TODO:
- * - IORDY fixes
* - VDMA support
*/
@@ -234,8 +233,7 @@ static u8 sil_sata_udma_filter(ide_drive_t *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)
@@ -276,13 +274,16 @@ 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);
}
@@ -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);
}
/**
@@ -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,
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 0924abf..d698da4 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -61,8 +61,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;
@@ -74,6 +73,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
+ unsigned long timings = (unsigned long)ide_get_drivedata(drive);
int reg = 0x44 + drive->dn * 4;
u16 drv_ctrl;
@@ -83,8 +83,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);
@@ -100,6 +101,7 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio)
static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed)
{
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",
@@ -111,8 +113,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;
}
/*
@@ -185,7 +198,8 @@ static void sl82c105_dma_start(ide_drive_t *drive)
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);
@@ -210,7 +224,8 @@ static int sl82c105_dma_end(ide_drive_t *drive)
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;
}
@@ -289,6 +304,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 = {
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c
index f55d7d6..9aec78d 100644
--- a/drivers/ide/slc90e66.c
+++ b/drivers/ide/slc90e66.c
@@ -44,7 +44,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;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 915da43..9c75921 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -800,6 +800,20 @@ static inline int ata_id_is_ssd(const u16 *id)
return id[ATA_ID_ROT_SPEED] == 0x01;
}
+static inline int ata_id_pio_need_iordy(const u16 *id, const u8 pio)
+{
+ /* CF spec. r4.1 Table 22 says no IORDY on PIO5 and PIO6. */
+ if (pio > 4 && ata_id_is_cfa(id))
+ return 0;
+ /* For PIO3 and higher it is mandatory. */
+ if (pio > 2)
+ return 1;
+ /* Turn it on when possible. */
+ if (ata_id_has_iordy(id))
+ return 1;
+ return 0;
+}
+
static inline int ata_drive_40wire(const u16 *dev_id)
{
if (ata_id_is_sata(dev_id))
diff --git a/include/linux/ide.h b/include/linux/ide.h
index a6c6a2f..95c6e00 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -157,12 +157,6 @@ enum {
#define REQ_UNPARK_HEADS 0x23
/*
- * Check for an interrupt and acknowledge the interrupt status
- */
-struct hwif_s;
-typedef int (ide_ack_intr_t)(struct hwif_s *);
-
-/*
* hwif_chipset_t is used to keep track of the specific hardware
* chipset used by each IDE interface, if known.
*/
@@ -185,7 +179,6 @@ struct ide_hw {
};
int irq; /* our irq number */
- ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
struct device *dev, *parent;
unsigned long config;
};
@@ -331,11 +324,6 @@ enum {
PC_FLAG_WRITING = (1 << 6),
};
-/*
- * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes.
- * This is used for several packet commands (not for READ/WRITE commands).
- */
-#define IDE_PC_BUFFER_SIZE 64
#define ATAPI_WAIT_PC (60 * HZ)
struct ide_atapi_pc {
@@ -347,12 +335,6 @@ struct ide_atapi_pc {
/* bytes to transfer */
int req_xfer;
- /* bytes actually transferred */
- int xferred;
-
- /* data buffer */
- u8 *buf;
- int buf_size;
/* the corresponding request */
struct request *rq;
@@ -363,8 +345,6 @@ struct ide_atapi_pc {
* those are more or less driver-specific and some of them are subject
* to change/removal later.
*/
- u8 pc_buf[IDE_PC_BUFFER_SIZE];
-
unsigned long timeout;
};
@@ -552,7 +532,7 @@ struct ide_drive_s {
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */
- unsigned int drive_data; /* used by set_pio_mode/dev_select() */
+ void *drive_data; /* used by set_pio_mode/dev_select() */
unsigned int failures; /* current failure count */
unsigned int max_failures; /* maximum allowed failure count */
u64 probed_capacity;/* initial/native media capacity */
@@ -649,6 +629,7 @@ struct ide_port_ops {
void (*maskproc)(ide_drive_t *, int);
void (*quirkproc)(ide_drive_t *);
void (*clear_irq)(ide_drive_t *);
+ int (*test_irq)(struct hwif_s *);
u8 (*mdma_filter)(ide_drive_t *);
u8 (*udma_filter)(ide_drive_t *);
@@ -674,6 +655,10 @@ struct ide_dma_ops {
u8 (*dma_sff_read_status)(struct hwif_s *);
};
+enum {
+ IDE_PFLAG_PROBING = (1 << 0),
+};
+
struct ide_host;
typedef struct hwif_s {
@@ -690,6 +675,8 @@ typedef struct hwif_s {
ide_drive_t *devices[MAX_DRIVES + 1];
+ unsigned long port_flags;
+
u8 major; /* our major number */
u8 index; /* 0 for ide0; 1 for ide1; ... */
u8 channel; /* for dual-port chips: 0=primary, 1=secondary */
@@ -708,8 +695,6 @@ typedef struct hwif_s {
struct device *dev;
- ide_ack_intr_t *ack_intr;
-
void (*rw_disk)(ide_drive_t *, struct request *);
const struct ide_tp_ops *tp_ops;
@@ -1130,6 +1115,8 @@ void SELECT_MASK(ide_drive_t *, int);
u8 ide_read_error(ide_drive_t *);
void ide_read_bcount_and_ireason(ide_drive_t *, u16 *, u8 *);
+int ide_check_ireason(ide_drive_t *, struct request *, int, int, int);
+
int ide_check_atapi_device(ide_drive_t *, const char *);
void ide_init_pc(struct ide_atapi_pc *);
@@ -1154,7 +1141,8 @@ enum {
REQ_IDETAPE_WRITE = (1 << 3),
};
-int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);
+int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
+ void *, unsigned int);
int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *);
int ide_do_start_stop(ide_drive_t *, struct gendisk *, int);
@@ -1524,6 +1512,7 @@ int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int);
int ide_scan_pio_blacklist(char *);
const char *ide_xfer_verbose(u8);
u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8);
+int ide_pio_need_iordy(ide_drive_t *, const u8);
int ide_set_pio_mode(ide_drive_t *, u8);
int ide_set_dma_mode(ide_drive_t *, u8);
void ide_set_pio(ide_drive_t *, u8);
@@ -1561,6 +1550,16 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive)
return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL;
}
+static inline void *ide_get_drivedata(ide_drive_t *drive)
+{
+ return drive->drive_data;
+}
+
+static inline void ide_set_drivedata(ide_drive_t *drive, void *data)
+{
+ drive->drive_data = data;
+}
+
#define ide_port_for_each_dev(i, dev, port) \
for ((i) = 0; ((dev) = (port)->devices[i]) || (i) < MAX_DRIVES; (i)++)
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-06-20 11:56 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-20 11:56 [git pull] IDE updates part 3 Bartlomiej Zolnierkiewicz
-- strict thread matches above, loose matches on Subject: below --
2009-03-31 19:35 Bartlomiej Zolnierkiewicz
2009-01-06 17:12 Bartlomiej Zolnierkiewicz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).